This is a question I was sent a week or so ago - if a table is truncated inside a transaction, what protects the integrity of the table's pages in case the transaction rolls back? Let's find out.
First off I'll create a simple table to experiment with.
CREATE TABLE TruncateTest (c1 INT IDENTITY, c2 CHAR (8000) DEFAULT 'A');GO SET NOCOUNT ON;GO DECLARE @a INT;SELECT @a = 1;WHILE (@a < 20)BEGIN INSERT INTO TruncateTest DEFAULT VALUES;SELECT @a = @a + 1;
CREATE
SET
DECLARE
END
We can see what pages and extents are allocated to the table using the undocumented DBCC IND command:
DBCC IND (test, TruncateTest, 0);GO PageFID PagePID------- ---------1 1931 1921 1941 1951 1961 1971 1981 1991 2001 2241 2251 2261 2271 2281 2291 2301 2311 2321 2331 234 DBCC execution completed. If DBCC printed error messages, contact your system administrator.
DBCC
PageFID PagePID------- ---------1 1931 1921 1941 1951 1961 1971 1981 1991 2001 2241 2251 2261 2271 2281 2291 2301 2311 2321 2331 234
DBCC execution completed. If DBCC printed error messages, contact your system administrator.
I've curtailed the output to just the page IDs and we can see that there are 4 extents used by this table (starting on pages (1:192), (1:200), (1:224), and (1:232)). Now if we truncate the table in a transaction, what will DBCC IND show?
BEGIN TRAN;GO TRUNCATE TABLE TruncateTest;GO DBCC IND (test, TruncateTest, 0);GO DBCC execution completed. If DBCC printed error messages, contact your system administrator.
BEGIN
TRUNCATE
Looks like there are no pages allocated to the table. So where are they? Let's check what locks there are. Instead of using sp_lock, I'm going to use it's replacement DMV, sys.dm_tran_locks:
SELECT resource_type, resource_description, request_mode FROM sys.dm_tran_locks WHERE resource_type IN ('EXTENT', 'PAGE');GO resource_type resource_description request_mode--------------- ---------------------- --------------EXTENT 1:200 XPAGE 1:198 XPAGE 1:199 XPAGE 1:196 XPAGE 1:197 XPAGE 1:194 XPAGE 1:195 XPAGE 1:192 XPAGE 1:193 XEXTENT 1:192 XPAGE 1:200 XEXTENT 1:232 XEXTENT 1:224 X
SELECT
resource_type resource_description request_mode--------------- ---------------------- --------------EXTENT 1:200 XPAGE 1:198 XPAGE 1:199 XPAGE 1:196 XPAGE 1:197 XPAGE 1:194 XPAGE 1:195 XPAGE 1:192 XPAGE 1:193 XEXTENT 1:192 XPAGE 1:200 XEXTENT 1:232 XEXTENT 1:224 X
Ah - all the pages and extents are locked. The table doesn't show them as allocated any more but because they're exclusively locked, the allocation subsystem can't really deallocate them until the locks are dropped (when the transaction commits). That's the answer - they can't be reused until they're really deallocated. If a transaction rollback happens, the pages are just marked as allocated again.
Remember Me
a@href@title, strike
Theme design by Jelle Druyts
Pick a theme: BlogXP sqlx BlogXP sqlx
Powered by: newtelligence dasBlog 2.0.7226.0
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.
© Copyright 2008, Paul S. Randal
E-mail