Dlaczego CREATE INDEX… WITH ONLINE = ON blokuje dostęp do tabeli w ciągu kilku minut?

22

Mam istniejący stół:

CREATE TABLE dbo.ProofDetails
(
    ProofDetailsID int NOT NULL 
        CONSTRAINT PK_ProofDetails 
        PRIMARY KEY CLUSTERED IDENTITY(1,1)
    , ProofID int NULL
    , IDShownToUser int NULL
    , UserViewedDetails bit NOT NULL 
        CONSTRAINT DF_ProofDetails_UserViewedDetails 
        DEFAULT ((0))
);

Ta tabela ma 150 000 000 wierszy. System działa 24x7x365, więc nie ma regularnie występujących okien serwisowych.

Chcę dodać indeks do tabeli, a wraz z wersją SQL Server Enterprise, powinienem móc to zrobić bez blokowania dostępu do zapisu w tabeli. Polecenie, którego użyłem to:

CREATE INDEX IX_ProofDetails_ProofID_Etc 
ON dbo.ProofDetails (ProofID, IDShownToUser)
INCLUDE (UserViewedDetails)
WITH (ONLINE=ON
    , ALLOW_ROW_LOCKS=ON
    , ALLOW_PAGE_LOCKS=ON
    , FILLFACTOR=100
    , MAXDOP=4
);

Sam wykonałem instrukcję w SSMS, naciskając F5. Trwało to ponad minutę, a następnie zaczęło blokować inne sesje. Następnie natychmiast anulowałem CREATE INDEXpolecenie, ponieważ nie mogę zablokować innych sesji.

W pierwszej minucie nic nie blokowało mojej CREATE INDEXkomendy, sys.dm_exec_requestspokazało proces z typem oczekiwania CXPACKET- oczywiście. Nie sądzę, żeby to było złe, ponieważ operacja została zrównoleglona.

Nie miałem dużo czasu na sprawdzenie wyników sys.dm_exec_requests. Został zwrócony tylko jeden wiersz z zapytania WHERE session_id = xxx. Zablokowane sesje próbowały wstawić wiersze do tabeli docelowej.

Nie wiem, jak długo trwały blokady, z wyjątkiem tego, że anulowałem wykonanie instrukcji około 2 minuty po jej uruchomieniu. W tym momencie pojawiały się bloki.

Czy źle zrozumiałem wdrożenie WITH (ONLINE=ON)? Czy jest coś jeszcze, o czym muszę wiedzieć?

Serwer jest dość mocną maszyną, z 2 czterordzeniowymi procesorami Xeon E5-2643 3,3 GHz, 192 GB pamięci RAM i pamięcią SAN zdolną do ponad 5000 Iops. Procesor jest zwykle poniżej 20%, pamięć RAM jest wykorzystywana w 93%, głównie przez SQL Server. W tym pudełku nie działa nic więcej, tylko Windows Server 2012 i SQL Server 2012.

Max Vernon
źródło

Odpowiedzi:

23

Podczas tworzenia indeksu przy włączonym trybie online proces tworzenia indeksu nie będzie blokował się podczas tworzenia samego obiektu indeksu, ale gdy dojdzie do końca procesu, uzyska blokadę modyfikacji schematu * na pewien okres, aby faktycznie dodaj indeks do tabeli, ten typ blokady będzie blokować wszystkie operacje zewnętrzne, dopóki blokada nie zostanie zwolniona, co może wyjaśniać problemy z blokowaniem.

* Sch-MBlokada nie jest wymagana do kompilacji online nowego indeksu nieklastrowanego, chociaż jest wymagana we wszystkich innych przypadkach. Nowy indeks nieklastrowany wymaga tylko blokady współużytkowanej na poziomie tabeli podczas fazy końcowej, takiej samej jak potrzebna podczas fazy przygotowawczej.

Szczegółowe informacje można znaleźć w białej księdze:

Operacje indeksowania online w SQL Server 2005

Jak zasugerował Mushtaq Mohammed w komentarzu do pytania, zobacz także:

Jednorożce, tęcze i operacji indeksu forum autorstwa Pawła Randal

steoleary
źródło