Der er en vedvarende myte i s .l-serververdenen, at både DROP TABLE
og TRUNCATE TABLE
kommandoer ikke er logget.
de er ikke. De er begge fuldt logget, men effektivt logget.
Du kan nemt bevise dette for dig selv., Kør følgende kode til at oprette en test-database og tabel, og vise, at vi har 10.000 rækker i vores tabel:
Resultater:
—-
10000
Og derefter følgende kode, som afkorter bordet i en transaktion og kontrol rækken tæller:
BEGIN TRAN;GOTRUNCATE TABLE ;GO SELECT COUNT (*) AS N'RowCount'FROM ;GO
Resultater:
—-
0
Nu er tabellen er tom., Men jeg kan rulle tilbage transaktionen og sætte alle data tilbage igen:
ROLLBACK TRAN;GO SELECT COUNT (*) AS N'RowCount'FROM ;GO
Resultater:
—-
10000
det er Klart, at TRUNCATE
operation skal være logget ellers rulle tilbage operation ikke ville arbejde.
så hvor kommer misforståelsen fra?
det kommer fra opførslen af DROP
og TRUNCATE
operationer på store tabeller., De afsluttes næsten øjeblikkeligt, og hvis du kigger i transaktionsloggen ved hjælp af fn_dblog
lige bagefter, ser du kun et lille antal logposter genereret fra operationen. Det lille antal korrelerer ikke med størrelsen på tabellen, der afkortes eller tabes, så det ser ud som om DROP
og TRUNCATE
operationer ikke er logget.
men de er fuldt logget, som jeg demonstrerede ovenfor. Så hvor er logoptegnelserne for operationerne?,
svaret er, at logposterne oprettes, bare ikke med det samme, af en mekanisme kaldet ‘udskudt drop’, som blev tilføjet i s .l Server 2000 SP3.
når en tabel tabes eller afkortet, skal alle de datafilsider, der er tildelt til tabellen, være deallocated.,uire en eksklusiv allokering af lås på det omfang,
Probe page lock for hver side i det omfang, (erhverve låsen i eksklusive mode, og straks slippe det, der gør sikker på, at ingen andre har den side, låst)
slip IKKE, i det omfang lås, som sikrer, at ingen andre kan bruge det omfang,
gå til den næste grad
Afslut
Som alle i det omfang, låse blev holdt indtil slutningen af drift, og hver lås tager en lille mængde hukommelse, var det muligt for de lock manager til at køre tør for hukommelse, når en DROP
eller TRUNCATE
af et meget stort bord opstod., Nogle s .l Server-kunder begyndte at finde ud af, at de løb ud af hukommelsesforholdene på s .l Server 2000, da tabeller voksede meget store og langt oversteg væksten i systemhukommelsen.
den udskudte drop-mekanisme simulererDROP
ellerTRUNCATE
operation, der afsluttes øjeblikkeligt ved at fjerne tildelingerne til tabellen og sætte dem på ‘udskudt-drop-køen’ til senere behandling af en baggrundsopgave. Denne unhook-and-transfer operation genererer kun en håndfuld log poster., Dette er den operation, der udføres og rulles tilbage i mit kodeeksempel ovenfor.
‘deferred-drop baggrund opgave’ spins op hvert par sekunder og deallocates alle sider og omfang på den udskudte-drop kø i små partier, garanterer, at operationen ikke vil løbe tør for hukommelse. Disse deallocations er alle fuldt logget ind, men husk, at deallocating en side fuld af data eller indekset registrerer ikke logge enkelte sletter af disse registreringer; i stedet hele siden er blot markeret som deallocated i de relevante PFS (Side Gratis Plads) fordeling byte-kort.,
Fra SQL Server 2000 SP3 og fremefter, når du udfører en DROP
eller TRUNCATE
af en tabel, vil du kun se et par poster i loggen bliver genereret. Hvis du venter et minut eller deromkring, og derefter ser i transaktionsloggen igen, vil du se tusindvis af logposter er blevet genereret af udskudt-drop operation, hver deallocating en side eller omfang. Handlingen er fuldt og effektivt logget.,
Her er et eksempel, ved hjælp af det scenarie, som vi har oprettet ovenfor:
CHECKPOINT;GOTRUNCATE TABLE ;GOSELECT COUNT (*) AS N'LogRecCount'FROM fn_dblog (NULL, NULL);GO
Resultater:
—-
25
Som du kan se, er der klart ikke er poster i loggen i deallocating de 10.000 sider, plus 1,250 omfang i TestTable bordet.
Hvis jeg venter et par sekunder, og derefter køre fn_dblog
koden igen, får jeg:
—-
3811
Du vil måske undre, hvorfor der ikke er mindst 10.000 log records – en for hver side, der er deallocated., Det skyldes, at sidedallokationerne endda logges effektivt-med en logrekord, der afspejler PFS-sideallokeringsændringer for 8 på hinanden følgende datafilsider, i stedet for en logrekord for hver datafilside, der afspejler dens allokeringsstatus, der ændres på PFS-siden.
s .l Server forsøger altid at producere så lidt transaktionslog som muligt, mens du stadig overholder reglerne om fuld eller minimal logning baseret på den aktuelle gendannelsesmodel., Hvis du ønsker at se på den faktiske log registreringer, der er genereret af hægte-og-overførsel og udskudt-drop mekanismer, simpelthen erstatter * for COUNT (*) i fn_dblog koden ovenfor, og se efter en transaktion med Transaktionen Navn sat til DeferredAllocUnitDrop::Process
.
i fremtidige indlæg vil jeg diskutere de interne, der understøtter andre vedvarende myter omkring præstationsaspekter af S .l Server Storage Engine.
Skriv et svar