Perché CREATE INDEX ... WITH ONLINE = ON blocca l'accesso alla tabella per un periodo di minuti?


22

Ho una tabella esistente:

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

Questa tabella ha 150.000.000 di righe. Il sistema è in funzione 24x7x365, quindi non ci sono finestre di manutenzione che si verificano regolarmente.

Voglio aggiungere un indice alla tabella e, con l'edizione Enterprise di SQL Server, dovrei essere in grado di farlo senza bloccare l'accesso in scrittura alla tabella. Il comando che ho usato era:

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

Ho eseguito la dichiarazione da sola in SSMS, premendo F5. Ha funzionato per oltre un minuto, quindi ha iniziato a bloccare altre sessioni. Ho quindi immediatamente annullato il CREATE INDEXcomando poiché non riesco a bloccare altre sessioni.

Durante il primo minuto, nulla stava bloccando il mio CREATE INDEXcomando, ha sys.dm_exec_requestsmostrato il processo con un tipo di attesa di CXPACKET- ovviamente. Non penso che sia una cosa negativa da quando l'operazione è stata parallelizzata.

Non ho avuto molto tempo per ispezionare l'output di sys.dm_exec_requests. Dalla query è stata restituita una sola riga WHERE session_id = xxx. Le sessioni bloccate stavano tentando di inserire righe nella tabella di destinazione.

Non so per quanto tempo sono durati i blocchi, tranne per dire che ho annullato l'esecuzione dell'istruzione circa 2 minuti dopo l'avvio. A quel punto si stavano verificando blocchi per circa un minuto.

Sto fraintendendo l'implementazione di WITH (ONLINE=ON)? O c'è qualcos'altro di cui devo essere consapevole?

Il server è una macchina abbastanza robusta, con 2 processori quad-core Xeon E5-2643 3,3 Ghz, 192 GB di RAM e memoria SAN capace di oltre 5.000 iops. La CPU è in genere inferiore al 20%, la RAM è utilizzata al 93%, principalmente da SQL Server. Non c'è nient'altro in esecuzione sulla scatola, solo Windows Server 2012 e SQL Server 2012.

Risposte:


23

Quando si crea un indice con online = on, il processo di creazione dell'indice non si bloccherà durante la creazione dell'oggetto indice stesso, ma quando si avvicina alla fine del processo, acquisirà un blocco di modifica dello schema * per un periodo al fine di aggiungere l'indice alla tabella, questo tipo di blocco bloccherà tutte le operazioni esterne fino al rilascio del blocco, il che potrebbe spiegare i problemi di blocco.

* Sch-MNon è richiesto un blocco per la creazione online di un nuovo indice non cluster, sebbene sia necessario in tutti gli altri casi. Un nuovo indice non cluster richiede solo un blocco condiviso a livello di tabella durante la fase finale, lo stesso che era necessario durante la fase di preparazione.

Vedi questo white paper per i dettagli:

Operazioni di indicizzazione online in SQL Server 2005

Come suggerito da Mushtaq Mohammed in un commento sulla domanda, vedi anche:

Unicorni, arcobaleni e operazioni su indici online di Paul Randal

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.