it-swarm.com.de

Warum blockiert CREATE INDEX ... WITH ONLINE = ON den Zugriff auf die Tabelle über einen Zeitraum von Minuten?

Ich habe eine vorhandene Tabelle:

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))
);

Diese Tabelle enthält 150.000.000 Zeilen. Das System ist rund um die Uhr und 365 Tage die Woche in Betrieb, sodass keine regelmäßig auftretenden Wartungsfenster vorhanden sind.

Ich möchte der Tabelle einen Index hinzufügen, und mit der Enterprise Edition von SQL Server sollte dies möglich sein, ohne den Schreibzugriff auf die Tabelle zu blockieren. Der Befehl, den ich benutzte, war:

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
);

Ich habe die Anweisung selbst in SSMS ausgeführt, indem ich gedrückt habe F5. Es lief über eine Minute und blockierte dann andere Sitzungen. Ich habe dann sofort den Befehl CREATE INDEX Abgebrochen, da ich andere Sitzungen nicht blockieren kann.

Während der ersten Minute blockierte nichts meinen Befehl CREATE INDEX, sys.dm_exec_requests Zeigte den Prozess mit einem Wartetyp von CXPACKET - natürlich. Ich denke nicht, dass das eine schlechte Sache ist, da die Operation parallelisiert wurde.

Ich hatte nicht viel Zeit, um die Ausgabe von sys.dm_exec_requests Zu überprüfen. Von der Abfrage WHERE session_id = xxx Wurde nur eine einzige Zeile zurückgegeben. Die blockierten Sitzungen versuchten, Zeilen in die Zieltabelle einzufügen.

Ich weiß nicht, wie lange die Sperren gedauert haben, außer dass ich die Ausführung der Anweisung etwa 2 Minuten nach ihrem Start abgebrochen habe. Zu diesem Zeitpunkt traten etwa eine Minute lang Blöcke auf.

Verstehe ich die Implementierung von WITH (ONLINE=ON) falsch? Oder gibt es noch etwas, das ich beachten muss?

Der Server ist ein ziemlich leistungsfähiger Computer mit 2 Quad-Core-Xeon E5-2643-Prozessoren mit 3,3 GHz, 192 GB RAM und SAN Speicher mit mehr als 5.000 Iops. Die CPU liegt normalerweise unter 20%, = RAM wird zu 93% verwendet, hauptsächlich von SQL Server. Auf der Box wird nichts anderes ausgeführt, nur Windows Server 2012 und SQL Server 2012.

24
Max Vernon

Wenn Sie einen Index mit online = on erstellen, wird der Prozess zum Erstellen eines Index beim Erstellen des Indexobjekts selbst nicht blockiert. Gegen Ende des Prozesses wird jedoch für einen bestimmten Zeitraum eine Schemamodifikationssperre * abgerufen, um dies tatsächlich zu tun Wenn Sie den Index zur Tabelle hinzufügen, blockiert dieser Sperrtyp alle externen Vorgänge, bis die Sperre aufgehoben wird. Dies könnte Ihre Blockierungsprobleme erklären.

* Ein Sch-M lock ist für die Online-Erstellung eines neuen nicht gruppierten Index nicht erforderlich, in allen anderen Fällen jedoch erforderlich. Ein neuer nicht gruppierter Index erfordert in der letzten Phase nur eine gemeinsame Sperre auf Tabellenebene, wie sie in der Vorbereitungsphase benötigt wurde.

Weitere Informationen finden Sie in diesem Whitepaper:

Online-Indizierungsvorgänge in SQL Server 2005

Wie von Mushtaq Mohammed in einem Kommentar zur Frage vorgeschlagen, siehe auch:

Einhörner, Regenbogen und Online-Indexoperationen von Paul Randal

25
steoleary