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

22

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 24x7x365 in Betrieb, daher gibt es keine regelmäßig auftretenden Wartungsfenster.

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 verwendete, 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 in SSMS selbst ausgeführt, indem ich gedrückt habe F5. Es lief über eine Minute und blockierte dann andere Sitzungen. Ich habe den CREATE INDEXBefehl dann sofort abgebrochen, da ich andere Sitzungen nicht blockieren kann.

Während der ersten Minute blockierte nichts mein CREATE INDEXKommando, sys.dm_exec_requestszeigte den Vorgang mit einer Wartezeit 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 zu überprüfen sys.dm_exec_requests. Von der Abfrage wurde nur eine einzige Zeile zurückgegeben WHERE session_id = xxx. Die blockierten Sitzungen versuchten, Zeilen in die Zieltabelle einzufügen.

Ich weiß nicht, wie lange die Sperren gedauert haben, mit der Ausnahme, dass ich die Ausführung der Anweisung etwa 2 Minuten nach dem Start abgebrochen habe. Zu diesem Zeitpunkt traten etwa eine Minute lang Blockaden auf.

Missverstehe ich die Umsetzung von WITH (ONLINE=ON)? Oder gibt es noch etwas, das ich beachten muss?

Der Server ist eine ziemlich leistungsfähige Maschine mit 2 Quad-Core-Xeon E5-2643-Prozessoren mit 3,3 GHz, 192 GB RAM und SAN-Speicher mit über 5.000 Iops. Die CPU-Auslastung liegt in der Regel unter 20%, der Arbeitsspeicher wird zu 93% genutzt, hauptsächlich von SQL Server. Auf der Box läuft nichts anderes, nur Windows Server 2012 und SQL Server 2012.

Max Vernon
quelle

Antworten:

23

Wenn Sie einen Index mit online = on erstellen, wird der Erstellungsindexprozess beim Erstellen des Indexobjekts selbst nicht blockiert, aber wenn er sich dem Ende des Prozesses nähert, erhält er eine Schemamodifikationssperre * für einen bestimmten Zeitraum, um tatsächlich zu arbeiten Wenn Sie den Index zur Tabelle hinzufügen, blockiert dieser Sperrentyp alle externen Vorgänge, bis die Sperre aufgehoben wird. Dies kann Ihre Blockierungsprobleme beheben.

* Für Sch-Mdie Online-Erstellung eines neuen Nonclustered-Index ist keine Sperre erforderlich, in allen anderen Fällen jedoch. Für einen neuen nicht gruppierten Index ist in der letzten Phase nur eine gemeinsame Sperre auf Tabellenebene erforderlich, die auch in der Vorbereitungsphase erforderlich war.

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

steolear
quelle