触发器和行版本控制信息

发布于 2024-10-19 10:53:56 字数 1198 浏览 1 评论 0 原文

在什么情况下表触发器会导致在行尾添加 14 个字节以进行行版本控制?

本页的“数据行中使用的空间”部分明确指出“每个数据库行可以在行末尾使用最多 14 个字节来存储行版本控制信息...这 14 个字节是在第一次修改行时添加的,或者在插入新行时,在任何这些条件下... 该表有一个触发器。”

这在我的测试中没有发生(下面的脚本)。查看数据页面时,我没有看到快照隔离下出现的任何版本控制信息。我是否可以安全地假设数据页上的行永远不会仅仅因为表上有一个触发器而因这 14 个字节而变得臃肿?如果不是的话,什么时候会发生这种情况?

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

作业与我同在 2024-10-26 10:53:56

Paul Randal 有一篇方便的文章,名为:“存储引擎内部:何时添加版本控制标签?”。线索就在标题中:-)

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

听闻余生 2024-10-26 10:53:56

这一切都已解释 在这篇博文中

我在原始测试中没有看到任何版本控制指针的原因是因为表定义。

有一个性能优化,可以避免添加行
版本控制信息,但仅当表无法生成时
ROW_OVERFLOWLOB 分配单元。这意味着定义
表的内容不得允许 LOB 或以下可能性:
可变长度的列移出行。数据的实际大小
存储并不重要——重要的是潜在的大小。

如果我将表定义更改为

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

“因此可能无法全部适合行”,那么我确实会在 DBCC 结果中看到版本指针。例如如下。

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)

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)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文