– Myten at DROP og AVKORTE TABELLEN er Ikke Logget

posted in: Articles | 0

Det er en vedvarende myte i SQL Server verden som både DROP TABLE og TRUNCATE TABLE talekommandoer er ikke logget inn.

det er De ikke. De er begge fullt logget, men effektivt logget.

Du kan enkelt bevise dette for deg selv., Kjøre følgende kode til å sette opp en test databasen og tabellen, og vise at vi har 10 000 rader i vår tabell.

Resultater:

RowCount
—-
10000

Og deretter følgende kode, som avkorter bord i en transaksjon og sjekker referansetype:

BEGIN TRAN;GOTRUNCATE TABLE ;GO SELECT COUNT (*) AS N'RowCount'FROM ;GO

Resultatene:

RowCount
—-
0

Nå tabellen er tom., Men jeg kan rulle tilbake til transaksjonen og sette alle data tilbake igjen:

ROLLBACK TRAN;GO SELECT COUNT (*) AS N'RowCount'FROM ;GO

Resultatene:

RowCount
—-
10000

helt Klart TRUNCATE drift må være logget ellers rulle tilbake drift ville ikke fungere.

Så hvor kommer den misforståelsen kommer fra?

Det kommer fra atferden til DROP og TRUNCATE operasjoner på store bord., De vil fullføre nesten umiddelbart, og hvis du ser i transaksjonen logg ved hjelp av fn_dblog rett etterpå, vil du bare se et lite antall av logg poster generert fra driften. Som lite antall ikke samsvarer med størrelsen på bordet blir avkortet eller droppet, så det virker som om DROP og TRUNCATE operasjoner er ikke logget inn.

Men de er fullt logget, som jeg viste til ovenfor. Så hvor er den log-poster for drift?,

svaret er at loggen postene vil bli opprettet, bare ikke umiddelbart, ved en mekanisme som kalles «utsatt drop», som ble lagt i SQL Server 2000 SP3.

Når en tabell er droppet eller avkortet, alle data file-sider som er allokert til bordet må være deallocated.,kreve en eksklusiv tildeling lås på den utstrekning
Probe siden lås for hver side i den utstrekning (kjøpe lås i eksklusiv modus, og umiddelbart slippe den, noe som gjør at ingen andre har siden låst)
IKKE slipp den grad lås, noe som garanterer at ingen andre kan bruke den utstrekning
Flytt til det neste grad
End

Som alle i den grad låser ble holdt frem til slutten av operasjonen, og hver lås tar en liten mengde minne, var det mulig for lock manager til å kjøre ut av minnet når en DROP eller TRUNCATE av en svært stor tabell oppstått., Noen SQL Server kunder i gang for å finne de kjørte inn i ut-av-minne på SQL Server 2000, som tabeller vokste svært store og svært enn veksten i system minne.

Den utsatte-slipp-mekanisme simulerer DROP eller TRUNCATE drift fullført umiddelbart, ved å unhooking bevilgningene til bordet og sette dem på «utsatt-slipp køen», for senere behandling av en bakgrunn for oppgaven. Dette heng-og-overføring drift skaper bare en håndfull av logg poster., Dette er den operasjonen som blir gjort, og rullet tilbake i min kode eksempelet ovenfor.
‘utsatt-slipp bakgrunn oppgave’ spinner opp hver få sekunder og deallocates alle sider og omfang på den utsatte-slipp køen i små grupper, noe som garanterer at driften vil ikke kjøre ut av minnet. Disse deallocations alle er fullt logget, men husk at deallocating en side full av data eller indeks registrerer ikke logge individuelle sletter av de postene; i stedet hele siden er bare markert som deallocated i relevante PFS (Side Ledig Plass) tildeling byte-kart.,

Fra SQL Server 2000 SP3 og utover, når du utfører en DROP eller TRUNCATE av et bord, vil du bare se et par logg poster som blir generert. Hvis du venter et minutt eller så, og se deretter i transaksjonen logg på nytt, vil du se tusenvis av logg poster har blitt generert av utsatt-slipp-operasjon, hver deallocating en side eller grad. Operasjonen er helt og effektivt logget.,

Her er et eksempel, ved hjelp av scenariet vi opprettet ovenfor:

CHECKPOINT;GOTRUNCATE TABLE ;GOSELECT COUNT (*) AS N'LogRecCount'FROM fn_dblog (NULL, NULL);GO

Resultatene:

LogRecCount
—-
25

Som du kan se, er det klart ikke-logg registrerer deallocating 10 000 sider, pluss 1,250 grad i TestTable bordet.

Hvis jeg vente et par sekunder, og deretter kan du kjøre fn_dblog – koden på nytt, får jeg:

LogRecCount
—-
3811

Du lurer kanskje på hvorfor det ikke er minst 10 000 logg poster, en for hver side som blir deallocated., Det er fordi siden deallocations er enda logget effektivt – med en log-posten reflekterer PFS side tildeling endringer for 8 etterfølgende data file-sider, i stedet for en log-post for hver datafil side som reflekterer dens fordeling status endring i PFS side.

SQL Server prøver alltid å produsere så lite transaksjonen logg som mulig, mens du fortsatt å overholde regler om full eller minimal logging basert på gjeldende recovery modell., Hvis du ønsker å se på den faktiske logg poster generert av heng-og-overføring og utsatt-slipp-mekanismer, bare erstatning * for COUNT (*) i fn_dblog koden ovenfor og se etter en transaksjon med Transaksjonen Navn satt til DeferredAllocUnitDrop::Process.

I fremtidige innlegg vil jeg diskutere det innvendige som understøtter andre vedvarende myter rundt ytelse aspekter av SQL Server for Lagring av Motoren.

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *