web-dev-qa-db-fra.com

Pourquoi CREATE INDEX ... WITH ONLINE = ON bloque-t-il l'accès à la table sur une période de minutes?

J'ai une table existante:

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

Ce tableau comporte 150 000 000 lignes. Le système fonctionne 24x7x365, il n'y a donc pas de fenêtres de maintenance régulières.

Je veux ajouter un index à la table, et avec l'édition Enterprise de SQL Server, je devrais pouvoir le faire sans bloquer l'accès en écriture à la table. La commande que j'ai utilisée était:

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

J'ai exécuté l'instruction seule dans SSMS, en appuyant sur F5. Il a fonctionné pendant plus d'une minute, puis a commencé à bloquer d'autres sessions. J'ai ensuite immédiatement annulé la commande CREATE INDEX Car je ne peux pas bloquer d'autres sessions.

Pendant la première minute, rien ne bloquait ma commande CREATE INDEX, sys.dm_exec_requests A montré le processus avec un type d'attente CXPACKET - bien sûr. Je ne pense pas que ce soit une mauvaise chose puisque l'opération a été parallélisée.

Je n'ai pas eu beaucoup de temps pour inspecter la sortie de sys.dm_exec_requests. Une seule ligne a été renvoyée par la requête WHERE session_id = xxx. Les sessions bloquées tentaient d'insérer des lignes dans la table cible.

Je ne sais pas combien de temps les verrous ont duré, sauf pour dire que j'ai annulé l'exécution de la déclaration environ 2 minutes après son début. Des blocages se sont produits pendant environ une minute à ce moment-là.

Suis-je en train de mal comprendre l'implémentation de WITH (ONLINE=ON)? Ou y a-t-il autre chose dont je dois être conscient?

Le serveur est une machine assez robuste, avec 2 processeurs Xeon E5-2643 3,3 GHz à quatre cœurs, 192 Go de RAM et SAN capable de plus de 5000 iops. Le processeur est généralement inférieur à 20%, = RAM est utilisé à 93%, principalement par SQL Server. Il n'y a rien d'autre en cours d'exécution sur la boîte, juste Windows Server 2012 et SQL Server 2012.

24
Max Vernon

Lors de la création d'un index avec online = on, le processus de création d'index ne se bloque pas lors de la création de l'objet d'index lui-même, mais lorsqu'il arrive à la fin du processus, il acquiert un verrou de modification de schéma * pendant une période afin de réellement ajoutez l'index à la table, ce type de verrou bloquera toutes les opérations extérieures jusqu'à ce que le verrou soit libéré, ce qui pourrait expliquer vos problèmes de blocage.

* Une Sch-M le verrouillage n'est pas requis pour la création en ligne d'un nouvel index non cluster, bien qu'il soit nécessaire dans tous les autres cas. Un nouvel index non clusterisé ne nécessite qu'un verrou partagé au niveau de la table pendant la phase finale, identique à ce qui était nécessaire pendant la phase de préparation.

Consultez ce livre blanc pour plus de détails:

Opérations d'indexation en ligne dans SQL Server 2005

Comme suggéré par Mushtaq Mohammed dans un commentaire sur la question, voir également:

Licornes, arcs-en-ciel et opérations d'index en ligne par Paul Randal

25
steoleary