siquellando

...scoperte e considerazioni Sql di uno sviluppista
(un po' sviluppatore e un po' sistemista)

Anche il TRUNCATE e' loggato

Spesso si sente dire che determinate operazioni (il truncate, per esempio) NON vengono loggate in Sql...  Tale affermazione e’ da prendere “con le pinze” in quanto e’ quasi sempre falsa. Wink

 

Sql Server (almeno in recovery model FULL o BULK_LOGGED)  logga tutte le operazioni che vengono effettuate sui dati e sugli oggetti del database in quanto, altrimenti, non potrebbe, durante il restoring, ricostruire correttamente e completamente lo stato del database.

 

Se mai quello che cambia e’ il modo in cui l’operazione viene loggata, ovvero quali informazioni vengono registrate nel log.

 

Un esempio “esemplare” di cio’ ci e’ proprio fornito dall’istruzione TRUNCATE: in questo caso SQL non ha la necessita’ di loggare ogni singolo delete (che in effetti non viene compiuto), ma registrera’ la singola operazione truncate (che corrisponde al deallocamento delle pagine su cui sono memorizzati i dati della tabella).

 

Questo “minimum logging” consente comunque a Sql di garantire la transazionalita’ dell'esecuzione e la possibilita' del restore.

 

Pertanto anche l'istruzione TRUNCATE puo' essere eseguita all’interno di una transazione e subisce la fase di Redo durante il restore.

 

Potete verificare facilmente entrambe le cose con il seguente codice.

 

USE [master]

GO

-- Creazione db e tabelle di test

IF EXISTS (SELECT name FROM sys.databases WHERE name = N'TestTruncate')

DROP DATABASE TestTruncate

GO

 

CREATE DATABASE TestTruncate ON PRIMARY

( NAME = N'TestTruncate', FILENAME = N'C:\Temp\TestTruncate.mdf' ,

SIZE = 5MB , MAXSIZE = UNLIMITED, FILEGROWTH = 1MB )

LOG ON

( NAME = N'TestTruncate_log', FILENAME = N'C:\Temp\TestTruncate_log.ldf' ,

SIZE = 1MB , MAXSIZE = UNLIMITED, FILEGROWTH = 1MB)

GO

-- setto il recovery model a FULL

alter database TestTruncate set recovery Full;

GO

 

use TestTruncate

go

-- Creo la tabella (con un campo identity) e inserisco dei record

create table dbo.ForTruncateExample

(Codice int identity (1,1),

Valore varchar(10))

go

insert into dbo.ForTruncateExample values ('Alfa');

insert into dbo.ForTruncateExample values ('Beta');

select * from dbo.ForTruncateExample;

-- truncate sotto transazione

begin tran;

truncate table dbo.ForTruncateExample ;

-- non ci sono piu' valori

select * from dbo.ForTruncateExample;

rollback;

-- la truncate e' stata "rollbackata" !!

select * from dbo.ForTruncateExample;

-- verifico che anche l'identity continua a funzionare

insert into dbo.ForTruncateExample values ('Gamma');

select * from dbo.ForTruncateExample;

 

-- backup dati

backup database TestTruncate to disk = 'c:\temp\TestTruncate_FULL01.bck' with init;

-- Effettuo la truncate e poi backupp il log

truncate table dbo.ForTruncateExample ;

backup log TestTruncate to disk = 'c:\temp\TestTruncate_Log01.bck' with init;

-- restore Dati + Log

use master;

go

restore database TestTruncate from disk = 'c:\temp\TestTruncate_FULL01.bck' with NORECOVERY , REPLACE;

restore log TestTruncate from disk = 'c:\temp\TestTruncate_Log01.bck' with RECOVERY;

-- la tabella e' troncata

select * from TestTruncate.dbo.ForTruncateExample;

 

Ulteriori interessanti notizie sulla TRUNCATE (e sulle differenze con la DELETE) le trovate in questo articolo http://www.sqlservercentral.com/links/335083/14505

Comments

dude80 said:

Ciao Franco,

ho messo il feed del tuo blog nel mio Feedreader. Così non mi perdo nemmeno una chicca.

Ciao!

Marco Parravano

# dicembre 10, 2007 10.48

orsocurioso said:

Felice di averti tra di noi "dude80" .. mo' mi tocca bloggare piu' spesso ...

# dicembre 10, 2007 2.39

bellagita said:

Però la diferenza con la delete è che nel transaction log vengono salvate delle informazioni che permettono solo la redo non la undo.

Simmetricamente è la select into con 'operazione di massa con registrazione minima' che permete solo operazioni di undo e non di redo.

Quindi è una registrazione nel transaction log solo parziale.

Giusto?

# gennaio 25, 2008 4.27

orsocurioso said:

Non esattamente (almeno se ho capito cosa intendi per undo, redo e registrazione minima)

La differenza tra la Truncate e la Delete consiste nel fatto che, mentre la delete lavora a livello di singolo record la truncate semplicemente svuota la pagina, apponendo un apposito flag. Entrambe le operazioni vengono loggate in modo "totale" indipendentemente dal modello di recovery. E, entrambe, possono essere, appoggiandosi sul log, annullate o riapplicate. La prima lavorera' a livello record e l'altra a livello pagina.

Anche con la Truncate hai la possibilita' del redo (tramite il restore del log) come dell'undo (se l'hai lanciata entro una transazione che termina con un rollback).

Il discorso della Select into e' differente in quanto le informazioni memorizzte nel transaction log sono diverse a seconda del modello di recovery, ma, anche in questo caso, hai la possibilita' di restorare pienamente le modifiche ai dati (redo)  o annullarle (se sotto transazione).

# gennaio 28, 2008 1.33