Triggers and row versioning information

我只是一个虾纸丫 提交于 2020-01-23 10:45:10

问题


Under what circumstances will table triggers cause 14 bytes to be added to the end of the row for row versioning?

The "Space Used in Data Rows" section on this page clearly states "Each database row may use up to 14 bytes at the end of the row for row versioning information ... These 14 bytes are added the first time the row is modified, or when a new row is inserted, under any of these conditions ... The table has a trigger."

This didn't happen in my test (script below). When looking at the data page I don't see any of the versioning info that appears under snapshot isolation. Am I safe in assuming that the rows on data pages will never get bloated by this 14 bytes just because a trigger is on the table? If not when will this occur?

CREATE DATABASE D2

GO

ALTER DATABASE D2 SET ALLOW_SNAPSHOT_ISOLATION OFF

USE D2;

GO

CREATE TABLE T1
(
F1 INT IDENTITY(1,1) PRIMARY KEY,
F2 INT,
V1 VARCHAR(100)
)

INSERT INTO T1
SELECT TOP 80 ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS F2,
              REPLICATE(CHAR((ROW_NUMBER() OVER (ORDER BY (SELECT 0) -1) % 26) + ASCII('A')),100) AS V1
FROM sys.all_columns           

GO      

CREATE TRIGGER TR
   ON  T1
   AFTER INSERT,DELETE,UPDATE
AS 
BEGIN
    SET NOCOUNT ON;
    SELECT * FROM inserted

END
GO

UPDATE T1 SET F2=F2+1

GO

DECLARE @DBCCPAGE nvarchar(100)

SELECT TOP 1  @DBCCPAGE = 'DBCC PAGE(''D2'',' + CAST(file_id AS VARCHAR) + ',' + CAST(page_id AS VARCHAR) + ',3)'
FROM T1
CROSS APPLY sys.fn_PhysLocCracker(%%physloc%%) 

DBCC TRACEON(3604)
EXEC (@DBCCPAGE)


GO

回答1:


Paul Randal has a handy article called: "Inside the Storage Engine: When do versioning tags get added?". The clue is in the title :-)




回答2:


This is all explained in this blog post.

The reason why I did not see any versioning pointers in my original test is because of the table definition.

There is a performance optimization that can avoid adding row versioning information, but only if the table cannot generate ROW_OVERFLOW or LOB allocation units. This means that the definition of the table must not allow for LOBs or for the possibility of variable length columns moving off row. The actual size of the data stored is immaterial – it is the potential size that matters.

If I change the table definition to

CREATE TABLE T1
(
F1 INT IDENTITY(1,1) PRIMARY KEY,
F2 INT,
V1 VARCHAR(1000),
V2 VARCHAR(8000) NULL
)

So that potentially it might not all fit in row then I do see version pointers in the DBCC results. e.g. as below.

Record Type = PRIMARY_RECORD         Record Attributes =  NULL_BITMAP VARIABLE_COLUMNS VERSIONING_INFO
Record Size = 133                    
Memory Dump @0x63A4CC92

00000000:   70000c00 03000000 04000000 04004801 †p.............H.         
00000010:   00770044 44444444 44444444 44444444 †.w.DDDDDDDDDDDDD         
00000020:   44444444 44444444 44444444 44444444 †DDDDDDDDDDDDDDDD         
00000030:   44444444 44444444 44444444 44444444 †DDDDDDDDDDDDDDDD         
00000040:   44444444 44444444 44444444 44444444 †DDDDDDDDDDDDDDDD         
00000050:   44444444 44444444 44444444 44444444 †DDDDDDDDDDDDDDDD         
00000060:   44444444 44444444 44444444 44444444 †DDDDDDDDDDDDDDDD         
00000070:   44444444 444444c8 7b000001 000500b8 †DDDDDDDÈ{......¸         
00000080:   00000000 00††††††††††††††††††††††††††.....                    

Version Information = 
    Transaction Timestamp: 184
    Version Pointer: (file 1 page 31688 currentSlotId 5)


来源:https://stackoverflow.com/questions/5106372/triggers-and-row-versioning-information

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!