¿Por qué CREATE INDEX ... WITH ONLINE = ON bloquea el acceso a la tabla durante un período de minutos?

22

Tengo una tabla existente:

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

Esta tabla tiene 150,000,000 filas. El sistema está en funcionamiento las 24 horas del día, los 7 días de la semana, los 365 días del año, por lo que no hay ventanas de mantenimiento que ocurran regularmente.

Quiero agregar un índice a la tabla, y con la edición Enterprise de SQL Server, debería poder hacerlo sin bloquear el acceso de escritura a la tabla. El comando que usé fue:

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

Ejecuté la declaración sola en SSMS, presionando F5. Funcionó por más de un minuto, luego comenzó a bloquear otras sesiones. Luego cancelé inmediatamente el CREATE INDEXcomando ya que no puedo bloquear otras sesiones.

Durante el primer minuto, nada bloqueaba mi CREATE INDEXcomando, sys.dm_exec_requestsmostró el proceso con un tipo de espera CXPACKET, por supuesto. No creo que sea algo malo ya que la operación fue paralela.

No tuve mucho tiempo para inspeccionar la salida de sys.dm_exec_requests. Solo se devolvió una fila de la consulta WHERE session_id = xxx. Las sesiones bloqueadas intentaban insertar filas en la tabla de destino.

No sé cuánto duraron las cerraduras, excepto para decir que cancelé la ejecución de la declaración alrededor de 2 minutos después de que comenzó. Los bloqueos ocurrieron durante alrededor de un minuto en ese punto.

¿Estoy malinterpretando la implementación de WITH (ONLINE=ON)? ¿O hay algo más que necesito tener en cuenta?

El servidor es una máquina bastante robusta, con 2 procesadores Xeon E5-2643 de cuatro núcleos de 3.3Ghz, 192GB de RAM y almacenamiento SAN capaz de más de 5,000 iops. La CPU suele estar por debajo del 20%, la RAM se utiliza en un 93%, principalmente por SQL Server. No hay nada más ejecutándose en la caja, solo Windows Server 2012 y SQL Server 2012.

Max Vernon
fuente

Respuestas:

23

Al crear un índice con online = on, el proceso de creación de índice no se bloqueará al crear el objeto de índice en sí, pero cuando se acerque al final del proceso, adquirirá un bloqueo de modificación de esquema * durante un período para realmente agregue el índice a la tabla, este tipo de bloqueo bloqueará todas las operaciones externas hasta que se libere el bloqueo, lo que podría explicar sus problemas de bloqueo.

* No Sch-Mse requiere un bloqueo para la creación en línea de un nuevo índice no agrupado, aunque se requiere en todos los demás casos. Un nuevo índice no agrupado requiere solo un bloqueo compartido a nivel de tabla durante la fase final, lo mismo que se necesitaba durante la fase de preparación.

Vea este Libro Blanco para más detalles:

Operaciones de indexación en línea en SQL Server 2005

Como lo sugirió Mushtaq Mohammed en un comentario sobre la pregunta, también vea:

Unicornios, arcoiris y operaciones de índice en línea por Paul Randal

esteoleario
fuente