PostgreSQL如何标记冻结行?如何查看已冻结行及对应xmin取值?
关于PostgreSQL VACUUM冻结行的问题解答
冻结行的xmin是否有特定取值?
确实存在特殊标识,分两种场景:
- PostgreSQL核心预留了特殊事务ID
2(即FrozenTransactionId),这个ID对所有事务永远可见。常规VACUUM FREEZE操作会将符合条件的旧行的xmin直接更新为2,这是最常见的冻结标识。 - 更早版本的PostgreSQL还支持元组头冻结位标记:不会修改原有
xmin取值,而是在数据行的头部新增冻结标记位,系统读取时只要识别到这个标记,就会认为该行的xmin是全局可见的,不会参与XID的可见性比较。
如何查看已被冻结的行?
你可以根据场景选择不同的查询方式:
逐行查询指定表的冻结行
PostgreSQL 12及以上版本可以直接用系统提供的元组检测函数,查询语句如下:
-- 替换your_table为你要查询的表名 SELECT * FROM your_table WHERE xmin = 2 OR pg_tuple_xmin_is_frozen(your_table.*);
如果是更低版本的PostgreSQL,也可以通过xmin的年龄判断:
SELECT * FROM your_table WHERE age(xmin) = (2^31 - 1)::xid;
查看表级别的冻结统计
如果不需要逐行定位,只想了解某张表的整体冻结情况,可以查询系统表pg_class:
-- 替换your_table为你要查询的表名 SELECT relname, relfrozenxid, age(relfrozenxid) AS frozen_xid_age FROM pg_class WHERE relname = 'your_table';
也可以在执行VACUUM时加上VERBOSE参数,直接输出本次VACUUM过程中冻结的行数统计。
内容的提问来源于stack exchange,提问作者SGiux
相关产品推荐
相关产品推荐

