Il registro di SQL Server registra operazioni non impegnate?


12

Vedo spesso dichiarazioni come i record di log del server sql ogni transction e opeation.

Ma io sono confuso su ciò che accade quando una transazione viene poi rotolato indietro .

Dire una transazione esplicita ha 3 dichiarazioni: statement A, statement B, statement C, e, infine, un rollback statement D.

Ora dite che quando l'esecuzione non ha raggiunto il rollback statement D, le modifiche risultanti verranno statements A through Cregistrate nel log del server sql?

Comprensione 1 :

Le dichiarazioni da A a D vengono tutte registrate. SQL Server registra tutto, qualunque cosa accada.

Comprensione 2 : Le modifiche vengono archiviate solo da qualche parte nella memoria e registrate per registrare solo quando SQL Server visualizza commitun'istruzione. Se risulta essere rollbackun'istruzione, SQL Server ignora semplicemente la transacrion, non viene eseguita alcuna scrittura nel log perché non serve a nulla. In altre parole, SQL Server registra quando esiste un risultato netto prima e dopo le transazioni.

Entrambi sembrano logici, almeno per me, ma non possono entrambi avere ragione. Grazie per qualsiasi aiuto.


Ciao, prova [ systoolsgroup.com/sql-log-analyzer.html] (SQL Log Analyzer) per analizzare cosa succede nel file di registro. È possibile provare la versione gratuita di SysTools SQL Log Analyzer solo per l'anteprima dei dati del registro SQL. Spero che questo funzioni per te.
Rylan08,

Risposte:


13

La comprensione di 1 è corretta. SQL Server registra ogni operazione che modifica i dati nel registro delle transazioni. Un rollback è una modifica ai dati, quindi registra anche quello nel registro delle transazioni. Come istruzione A, scriverà i dati nel registro delle transazioni e prenoterà anche i dati nel registro delle transazioni nel caso in cui sia necessario ripristinare l'istruzione A. Lo stesso vale per B e C. Quando si esegue il rollback della transazione, nel registro verranno scritte più informazioni.

Ci sono molti modi per vederlo in azione, quindi di seguito è una breve demo. Ecco la query che userò per vedere cosa è stato scritto nel registro:

SELECT 
  COUNT(*) transaction_count
, SUM(database_transaction_log_bytes_used) used_bytes
, SUM(database_transaction_log_bytes_reserved) reserved_bytes
FROM sys.dm_tran_database_transactions
where database_id = 10;

Il mio tavolo:

create table TLOGDEMO (FLUFF VARCHAR(1000));

BEGIN TRANSACTION

La query A utilizza la registrazione minima:

INSERT INTO TLOGDEMO WITH (TABLOCK)
SELECT REPLICATE('A', 1000)
FROM master..spt_values t1
CROSS JOIN master..spt_values t2;

Dopo un:

╔═══════════════════╦════════════╦════════════════╗
 transaction_count  used_bytes  reserved_bytes 
╠═══════════════════╬════════════╬════════════════╣
                 1    24006640       175429451 
╚═══════════════════╩════════════╩════════════════╝

La query B non utilizza la registrazione minima:

INSERT INTO TLOGDEMO
SELECT REPLICATE('B', 1000)
FROM master..spt_values t1
CROSS JOIN master..spt_values t2;

Dopo B:

╔═══════════════════╦════════════╦════════════════╗
 transaction_count  used_bytes  reserved_bytes 
╠═══════════════════╬════════════╬════════════════╣
                 1  7352935708      1613986255 
╚═══════════════════╩════════════╩════════════════╝

La query C modifica meno dati:

INSERT INTO TLOGDEMO
SELECT REPLICATE('C', 1000)
FROM master..spt_values c;

Dopo C:

╔═══════════════════╦════════════╦════════════════╗
 transaction_count  used_bytes  reserved_bytes 
╠═══════════════════╬════════════╬════════════════╣
                 1  7355821748      1614545331 
╚═══════════════════╩════════════╩════════════════╝

Ora emetterò un ROLLBACKe interrogherò il DMV mentre avviene il rollback. Di seguito è riportata una tabella di alcune istantanee:

╔═══════════════════╦════════════╦════════════════╗
 transaction_count  used_bytes  reserved_bytes 
╠═══════════════════╬════════════╬════════════════╣
 1                  7393305528  1573797677     
 1                  7458767420  1502635737     
 1                  7682482356  1259440979     
 1                  7803881368  1127471233     
 ...                ...         ...            
╚═══════════════════╩════════════╩════════════════╝

Durante il ROLLBACK, i byte usati aumentano e il numero riservato di byte diminuisce. Questo perché SQL Server sta utilizzando lo spazio riservato prima per annullare la transazione. Per annullare la transazione, è necessario modificare i dati in modo che scriva più dati nel registro.


8

Le modifiche alle tabelle del database vengono scritte prima nel file di registro, quindi nelle tabelle stesse, prima in memoria e quindi, con un processo asincrono chiamato CHECKPOINT, su disco. Questo meccanismo è noto come WAL (Write-Ahead Logging) ed è comune a tutti i database relazionali.

Il registro stesso viene prima scritto nella memoria (nel buffer di registro, precisamente) e poi sul disco, ma nulla viene toccato sulle tabelle del database fino a quando il registro non è stato scritto sul disco.

Questo meccanismo consente sia il roll forward delle transazioni impegnate sia il rollback delle transazioni senza commit durante il processo di recupero. Per quanto riguarda il tuo esempio, se in seguito è successo qualcosa di brutto statement Ce tu avessi un commitinvece di un rollback(non puoi saperlo in anticipo), senza salvare tutti i passaggi della transazione, RDBMS non avrebbe modo di ripristinare il database in modo coerente e la transazione non soddisferebbe la D(durabilità) in ACID.

Quando si esegue il rollback di alcune operazioni, è il file di dati a ricevere le modifiche nette (tramite CHECKPOINT), non il file di registro.


5

Comprendere 1 è corretto e spaghettidba e Joe hanno buone spiegazioni.

Se sei interessato a provare tu stesso (su un'istanza di prova per favore), puoi usare lo script seguente:

--create a database and table for testing
USE master
GO
CREATE DATABASE tranlogtest
GO
USE tranlogtest
GO
CREATE TABLE t1
(junk char(1))

CHECKPOINT
GO

BEGIN TRAN
INSERT t1 VALUES ('a')
INSERT t1 VALUES ('b')
INSERT t1 VALUES ('c')

ROLLBACK
INSERT t1 VALUES ('d')

SELECT *
FROM fn_dblog(NULL,NULL)

Vedrai che SQL Server registra tutto, anche i passaggi per annullare le operazioni.

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.