
惰性模式
举个例子,如果在执行 VACUUM 命令时,还有其他三个事务正在运行,且其 txid 分别为
100,101,102,那么当前 txid 就是 100。
例子:表由三个页面组成,每个页面包含三条元组。 执行 VACUUM 命令时,当前 txid 为
50,002,500。经过计算元组 t_xmin 最大值为 2500,小于 2500 的元组将被冻结。冻结步骤如
下:
1. 第 0 页:三条元组被冻结,因为所有元组的 t_xmin 值都小于 2500。此外,因为
Tuple_1 是一条死元组,因而在该清理过程中被移除。
2. 第 1 页:通过查看可见性映射(从 VM 中发现该页面所有元组都可见),清理跳过了
对该页面的清理。
3. 第 2 页:Tuple_7 和 Tuple_8 被冻结,且 Tuple_7 被移除。
在完成清理之前,与清理相关的统计数据会被更新,例如 pg_stat_all_tables 视图中的
n_live_tup,n_dead_tup,last_vacuum,vacuum_count 等字段。
因为惰性模式可能会跳过页面,所以它无法冻结所有需要冻结的元组。
迫切模式
迫切模式弥补了惰性模式的缺陷。它会扫描所有页面,检查表中的所有元组,更新相关的系统
视图,并在可能时删除非必需的 clog 文件与页面。
当满足以下条件时,会执行迫切模式:当前 txid - pg_database.datfrozenxid >
vacuum_freeze_table_age(默认为 150,000,000)
pg_database.datfrozenxid 保存着每个数据库中最老的已冻结的事务标识。
例子:执行 VACUUM 命令时的事务 ID 为 150,002,000,因此,当前 txid=150,002,000,
经过计算元组 t_xmin 最大值为 100,002,000,小于 100,002,000 的元组将被冻结。因为当前
txid(150002000)-1821 > 150000000) ,因而冻结以迫切模式执行,如下所示。
评论