启用 hot_standby_feedback 的备用服务器和 VACUUM
通常,PostgreSQL 可以在一个行版本对任何事务不可见时立即清理该行。如果在带有一个备用节点的主节点上运行 PostgreSQL,在主节点上 VACUUM 要清理的行版本,可能是备用节点上的查询所需要用到的。这种情况叫做“复制冲突”,当检测到冲突时,备用节点上的查询会被取消掉。
为了防止备用节点上的查询因复制冲突而被取消,您可以将 hot_standby_feedback 设置为 on,这可以让备用服务器告知主服务器在其上面运行的最老事务。这样,主服务器可以避免清理备用服务器上的事务仍在使用的行。
但是,将hot_standby_feedback设置为 on,也意味着,备用服务器上长时间运行的查询,能够阻止主服务器上的行被清理。
列出备用服务器上的长事务
要查找所有备用服务器的xmin,可以在主服务器上运行下面的查询:
SELECT pid, application_name, client_addr, state, backend_xmin
FROM pg_stat_replication
WHERE backend_xmin IS NOT NULL
ORDER BY age(backend_xmin) DESC;
一旦确定了备用服务器,您可以通过运行下面命令,找到备用服务器中持有该xmin水位线的查询,及其连接对应的 pid:
SELECT pid, datname, usename, state, backend_xmin, backend_xid
FROM pg_stat_activity
WHERE backend_xmin IS NOT NULL OR backend_xid IS NOT NULL
ORDER BY greatest(age(backend_xmin), age(backend_xid)) DESC;
若要避免由于备用服务器上长时间运行的事务而导致主服务器过度膨胀,可以采用以下方法之一:
• 继续处理复制冲突,并将hot_standby_feedback设置为 off。
• 将 vacuum_defer_cleanup_age 设置为一个更高的值,以便将主服务器上的行的清理推迟到vacuum_defer_cleanup_age数量的事务处理结束后,从而为备用服务器上的查询提供更多的时间来完成,而不会遇到复制冲突。
• 最后,您还可以跟踪和终止备用数据库上长时间运行的查询,就像我们在对主服务器检查长时间运行的事务教程中讨论的一样。