管理变更跟踪 (SQL Server)

适用于:SQL ServerAzure SQL 数据库Azure SQL 托管实例Microsoft Fabric 中的 SQL 数据库

本文介绍如何管理更改跟踪。 本主题还说明如何配置安全性以及如何确定使用更改跟踪时对存储和性能的影响。

管理变更跟踪

以下各节列出了与管理更改跟踪相关的目录视图、权限和设置。

目录视图

若要确定哪些表和数据库已启用更改跟踪,请使用以下目录视图:

此外, sys.internal_tables 目录视图还列出了对用户表启用更改跟踪时所创建的内部表。

安全性

若要使用 更改跟踪函数访问更改跟踪信息,主体必须拥有以下权限:

  • SELECT 对要查询的表的更改跟踪表上至少主键列的权限。

  • VIEW CHANGE TRACKING 获取数据表时需要的权限。 需要 VIEW CHANGE TRACKING 权限,原因如下:

    • 更改跟踪记录包括有关已删除的行的信息。 记录使用已删除的行的主键值。 删除某些敏感数据后,可能会向 SELECT 主体授予更改跟踪表的权限。 在这种情况下,你不会希望该主体通过更改跟踪来访问已删除的信息。

    • 更改跟踪信息可以存储有关通过更新操作更改哪些列的信息。 主体可能会被拒绝授予对包含敏感信息的列的访问权限。 但是,由于更改跟踪信息可用,主体可以确定列值已更新,但主体无法确定列的值。

了解更改跟踪开销

为表启用更改跟踪时,会影响某些管理操作。 下表列出了应当注意的操作和影响。

操作 启用更改跟踪时
DROP TABLE 会删除已删除表的所有更改跟踪信息。
ALTER TABLE DROP CONSTRAINT 尝试删除 PRIMARY KEY 约束失败。 必须先禁用更改跟踪,然后才能删除 PRIMARY KEY 约束。
ALTER TABLE DROP COLUMN 如果要删除的列是主键的一部分,则无论更改跟踪如何,都不允许删除该列。

如果要删除的列不是主键的一部分,则删除列会成功。 但是,应首先了解对正在同步此数据的任何应用程序的影响。 如果为该表启用了列更改跟踪,则可能仍会将已删除的列作为更改跟踪信息的一部分返回。 应用程序负责处理已删除的列。
ALTER TABLE ADD COLUMN 如果将新列添加到更改跟踪表,则不会跟踪该列的添加。 只会跟踪对新列所做的更新和更改。
ALTER TABLE ALTER COLUMN 不会跟踪非主键列的数据类型更改。
ALTER TABLE SWITCH 如果一个表或两个表都启用了更改跟踪,则切换分区失败。
DROP INDEX, or ALTER INDEX DISABLE 无法删除或禁用强制实施主键的索引。
TRUNCATE TABLE 可以截断已启用更改跟踪的表。 但是,被该操作删除的行不会被跟踪,并且最低有效版本也会被更新。 当应用程序检查其版本时,检查结果会表明该版本太陈旧,需要进行重新初始化。 此条件与禁用更改跟踪相同,然后为表重新启用。

使用更改跟踪会增加 DML 操作的开销,因为该操作存储更改跟踪信息。

对 DML 的影响

更改跟踪经过优化,可最大程度地减少 DML 操作的性能开销。 对表使用更改跟踪带来的增量性能开销类似于为表创建和维护索引时遇到的开销。

对于 DML 操作更改的每一行,系统都会向内部变更跟踪表中添加一行记录。 此操作相对于 DML 操作的影响取决于各种因素,例如:

  • 主键列数

  • 用户表行中已更改的数据量

  • 事务中执行的操作数

快照隔离(如果使用)也会影响所有 DML 操作的性能,无论是否启用更改跟踪。

对存储的影响

更改跟踪数据存储在以下类型的内部表中:

  • 内部更改表

    已启用更改跟踪的每个用户表都将获取其自己的内部更改表。

  • 内部事务表

    数据库有一个内部事务表。

这些内部表对存储要求有下列影响:

  • 每当用户表中的某一行发生更改时,更改跟踪都会在内部更改表中添加一行记录。 该行有一个较小的固定开销,外加一个大小等于主键列大小的可变开销。 该行可以包含由应用程序设置的可选上下文信息。 如果启用列跟踪,则每个更改的列都需要跟踪表中的 4 个字节。

  • 对于每个已提交的事务,更改跟踪都会在内部事务表中添加一行。

对于其他内部表,可以使用 sp_spaceused 存储过程来确定用于更改跟踪表的空间。 可以使用 sys.internal_tables 目录视图获取内部表的名称,如以下示例所示。

sp_spaceused 'sys.change_tracking_309576141'  
sp_spaceused 'sys.syscommittab'