虚影清理过程指南

虚影清理是一个后台进程,它以物理方式删除标记为由 DML 语句删除的行。 以下文章概述了此过程。

幽灵行

从索引的叶级页面中删除的行并不会被实际移出该页面。 而是将行标记为将来删除或标记为删除。 这意味着该行仍保留在页面上,但在行标题中进行了一些更改,以指示该行是幽灵行。 这是为了在删除操作期间优化性能。 对于行级锁定和快照隔离事务,数据库引擎必须维护旧行版本所必需的虚影。

虚影清理任务

标记为删除或 虚影的行在不再需要时,后台虚影清理过程将对其进行清理。 虚影清理会定期运行,并检查是否有任何页面存在虚影行。 如果找到任何行,它会以物理方式删除这些行。 在数据库引擎实例中,所有数据库共用一个幽灵清理线程。

当一行被标记为已删除时,数据库将被标记含有未彻底删除的条目。 虚影清理过程仅扫描此类数据库。 虚影清理过程还会将数据库标记为在删除所有虚影行后没有虚影行,并在下次运行时跳过此数据库。 如果无法获取数据库的共享锁,此过程也会跳过任何数据库。 下次运行时,它会对数据库重试锁定获取。

以下查询返回数据库中的大致虚影行数。

SELECT SUM(ghost_record_count) AS total_ghost_records,
       DB_NAME(database_id) AS database_name
FROM sys.dm_db_index_physical_stats(NULL, NULL, NULL, NULL, 'SAMPLED')
GROUP BY database_id
ORDER BY total_ghost_records DESC;

禁用虚影清理

在高负载系统中,存在许多删除操作时,如果幻影清理过程将缓冲池中许多经常访问的页面替换为包含幻影行的其他页面,则其性能可能会降低。 因此,经常访问的页面必须从磁盘中重新读取,生成额外的磁盘 I/O 并增加查询延迟。 如果发生这种情况,可以使用 跟踪标志 661 禁用虚影清理。

如果没有虚影清理,数据库可能会增长到不必要的大,从而导致额外的 I/O 和内存消耗,并降低性能。 由于虚影清理进程删除标记为虚影的行,因此禁用进程会在页面上保留这些行,从而阻止数据库引擎重用此空间。 这会强制数据库引擎将数据添加到新页面,从而导致数据库文件膨胀,也可能导致 页面拆分。 分页会增加磁盘 I/O,这可以减少查询性能。 如果禁用幽灵清理,数据库可能会耗尽空间。

警告

不建议永久禁用虚影清理过程。

若要在禁用虚影清理时删除虚影行,请在删除行的表上重新生成索引。 重新生成索引会基于现有数据创建新页面,省略进程中的虚影行。