ALTER INDEX ALL REBUILD utilizza più spazio nel registro delle transazioni con un semplice modello di recupero rispetto alla ricostruzione di ciascun indice singolarmente?


18

Un'operazione "ALTER INDEX ALL REBUILD" su SQL Server 2012 non è riuscita perché il registro delle transazioni ha esaurito lo spazio. Gli indici non sono mai stati riorganizzati o ricostruiti, quindi la frammentazione è superiore all'80% su quasi tutti.

Il DB utilizza un modello di recupero semplice. Supponevo che dopo ogni operazione sull'indice eseguita dal modulo "ALL" del comando, i dati del registro delle transazioni sarebbero stati cancellati prima della ricostruzione dell'indice successivo. Funziona così o le ricostruzioni dell'indice sono registrate come se facessero parte di una singola transazione?

In altre parole, posso ridurre la crescita del registro delle transazioni scrivendo uno script per eseguire ogni ricostruzione singolarmente? Ci sono altri fattori da considerare?


2
Escludendo i dati espliciti al contrario, suppongo che un comando SQL specifico venga considerato una singola transazione atomica dal motore DB. In questo caso, puoi testare abbastanza facilmente la teoria. Prendi il tuo indice più grande e prova a ricostruirlo. Se ciò ha esito positivo, è ragionevole supporre che il registro stia accumulando informazioni da più ricostruzioni. Se fallisce, allora devi aggiungere spazio per il registro (dato che hai un problema in entrambi i casi), oppure devi provare a riorganizzare quell'indice, invece di ricostruire (se non puoi aumentare lo spazio per il t- log).
RDFozz,

Sì, quel pensiero mi è venuto in mente proprio quando ho finito di scrivere questo (effetto paperella di gomma), ma ho pensato che sarebbe stato meglio ottenere conferma e lasciarlo per altri che potrebbero pensare allo stesso modo. Non voglio sperimentare questo ambiente, quindi probabilmente finirò per aggiungere spazio ai registri in entrambi i modi.
Google Fail

Risposte:


16

Supponevo che dopo ogni operazione sull'indice eseguita dal modulo "ALL" del comando, i dati del registro delle transazioni sarebbero stati scaricati prima della ricostruzione dell'indice successivo. Funziona così o le ricostruzioni dell'indice sono registrate come se facessero parte di una singola transazione?

1) Svuotamento del registro: il modello di recupero SEMPLICE non cancella il registro dopo ogni transazione, ma ai punti di controllo. ( link per maggiori informazioni)

2a) REBUILD ALL: sì, REBUILD ALL funziona come un'unica transazione. L'indice ricostruito all'interno ha le proprie transazioni, ma l'operazione complessiva non è completamente impegnata fino alla fine. Quindi sì, potresti limitare la crescita del file di registro ricostruendo i singoli indici (ed eventualmente lanciando i comandi CHECKPOINT).

2b) Prova! Ecco, hai uno script demo. (Costruito nel 2016 sviluppatore) Innanzitutto, imposta un db di prova, con tabella e indici:

USE master
GO

CREATE DATABASE Test_RebuildLog
GO

ALTER DATABASE Test_RebuildLog
SET RECOVERY SIMPLE
GO

USE Test_RebuildLog
GO

CREATE TABLE IndexTest
(ID int identity(1,1),
a char(1),
b char(1))

CREATE CLUSTERED INDEX CIX_IndexTest_ID ON IndexTest(ID)
CREATE INDEX IX_IndexTest_a ON IndexTest(a)
CREATE INDEX IX_IndexTest_b ON IndexTest(b)

INSERT IndexTest
(a,b)
VALUES ('a','b'),('z','y'),('s','r')

Ora puoi confrontare l'attività del registro tra REBUILD ALL e la ricostruzione individualmente

CHECKPOINT
GO
ALTER INDEX ALL ON IndexTest REBUILD

SELECT *
FROM sys.fn_dblog(NULL,NULL)
WHERE Operation = 'LOP_COMMIT_XACT'
OR Operation = 'LOP_BEGIN_XACT'
GO

CHECKPOINT
GO
ALTER INDEX CIX_IndexTest_ID ON IndexTest REBUILD
ALTER INDEX IX_IndexTest_a ON IndexTest REBUILD
ALTER INDEX IX_IndexTest_b ON IndexTest REBUILD

SELECT *
FROM sys.fn_dblog(NULL,NULL)
WHERE Operation = 'LOP_COMMIT_XACT'
OR Operation = 'LOP_BEGIN_XACT'
GO

Nota come la prima transazione aperta (ID transazione 0000: 000002fa per me) non viene impegnata fino alla fine di REBUILD ALL, ma per le ricostruzioni indice per indice, vengono impegnate successivamente.


Caspita, grazie per la risposta davvero dettagliata! È un ottimo modo per vedere cosa succede sotto il cofano, per così dire.
Google Fail

Ben spiegato.
Ramakant Dadhichi,

4

Allo stato attuale, questa è una singola transazione.


6
Benvenuto in DBA.SE! In generale, le risposte migliori non sono semplici asserzioni, ma sono supportate da informazioni tratte da documenti o articoli o da esperienze personali (spesso persino migliori) che dimostrano la risposta dichiarata. Puoi espandere la tua risposta per fornire quel tipo di supporto?
RDFozz,

2
@RDFozz Fair comment, ma hai guardato il profilo di Pedro ? L'accesso al codice sorgente può probabilmente essere considerato più autorevole dell'esperienza o della documentazione personale. :-)
Aaron Bertrand

3
@AaronBertrand - lo confesso, non l'ho fatto. Penserei sicuramente che far parte del team di SQL Server si qualificherebbe davvero. Tuttavia, vale la pena fare riferimento a quello nella risposta. +1, in ogni caso.
RDFozz,

3

La domanda è banale per una ricostruzione offline . Naturalmente è una singola transazione. Immagina il caos che ne deriverebbe se l'operazione suddividesse ciascun indice nella propria transazione, in quanto dovrebbe rilasciare i blocchi durante il commit e quindi riacquistarli. Mentre è stato rilasciato il blocco SCH-M della tabella critica, è possibile che vengano eliminati gli indici e che possano essere creati nuovi indici, in che modo l'istruzione gestirà tali casi? Per non parlare del fatto che la tabella può essere eliminata e persino ricreata tra le due transazioni! Compreso il caso in cui la tabella viene eliminata e viene creata una tabella diversa con lo stesso ID oggetto (sì, può succedere) ...

Che cosa succede se aumenti la domanda per dire cosa succede se la ricostruzione dell'indice è una ricostruzione online ? È una singola transazione o molte? La risposta è complessa, poiché in realtà sono coinvolte diverse transazioni interne . Tuttavia, il punto chiave è che esiste una transazione di archiviazione globale che abbraccia l'intera operazione (l'istruzione ALTER) e che blocca il log in atto (impossibile troncare), quindi l'operazione deve essere pianificata di conseguenza per consentire dati ~ 1,6x dimensione per la modalità di recupero COMPLETA o dimensione dei dati 0,2x per la modalità BULK_LOGGED / SEMPLICE. Vedi il documento collegato per maggiori dettagli.

Puoi sostenere che perché la build offline non utilizza le stesse transazioni interne della modalità online e divide l'operazione? I problemi che ho citato in merito alla modifica / eliminazione della tabella tra le singole operazioni sull'indice (ovvero la "stabilità dello schema" della tabella) richiederebbero comunque che esista una transazione comprensiva che contenga uno SCH-S sulla tabella per l'intera durata dell'istruzione. Poiché questa transazione deve contenere SCH-S anche durante il ripristino, deve essere registrata e come tale ci sarà un record di registro BEGIN XACT che bloccherà il registro e impedirà il troncamento per l'intera durata dell'istruzione. So che questo particolare problema è stato risolto nel lasso di tempo di SQL 2016-2017 (a causa di problemi di dimensioni del registro di SQL Azure), ma non sono sicuro di quali progressi siano stati fatti . Sembra che sia in anteprima ora:La ricostruzione dell'indice online ripristinabile è in anteprima pubblica per SQL Server 2017 CTP 2.0 .


0

Sì, ho avuto lo stesso problema con un tavolo molto grande. Ogni volta che ho emesso ALTER INDEX ALL, il registro delle transazioni cresce molto, ma se emesso ALTER INDEX singolarmente, l'utilizzo dello spazio del registro sarebbe inferiore.


0

La precedente risposta di Remus secondo cui l'indicizzazione online richiede 1,6 volte la dimensione dell'indice in modalità di recupero COMPLETO non è corretta. La percentuale di spazio di registrazione delle transazioni richiesta per ricostruire un indice online in FULL può essere molto più elevata e abbiamo osservato molte volte la dimensione dell'indice, specialmente quando l'indice da ricostruire viene compresso in quanto la registrazione delle transazioni non è compressa. Questo da solo dovrebbe chiarire che la registrazione delle transazioni durante una ricostruzione online in FULL può essere almeno alcune volte la dimensione dell'indice. Aggiungi un overhead del record di tlog che non è completamente documentato da Microsoft ma è spesso stimato a 60 byte per riga e la dimensione proporzionata della registrazione durante una ricostruzione dell'indice online in fase di ripristino completo può essere molte volte la dimensione dell'indice da ricostruire, soprattutto se l'indice è compresso


-1

Rdfozz è corretto, questo è il modo migliore per decidere se il tuo indice più grande può essere ricostruito in base alla memoria corrente. Esegui semplicemente dm_exec_requestsmentre è in corso l'operazione (o SQL Profiler) per vedere se tutti gli indici vengono ricostruiti. Vorrei anche prendere in considerazione la modifica del modello di recupero in log di massa. Questo è quello che faccio e ci sono ancora dei backup del registro delle transazioni durante la finestra. Vedi sotto l'articolo https://technet.microsoft.com/en-us/library/ms191484(v=sql.105).aspx


2
Si noti che l'OP ha dichiarato che il loro DB sta già utilizzando il modello di recupero SEMPLICE; ciò mantiene le transazioni nel registro solo per il tempo necessario per il completamento delle transazioni. Non ci sarebbero miglioramenti se passassero alla registrazione in blocco.
RDFozz,

Hai ragione. Mie scuse.
ADTJOB,
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.