PolarDB PostgreSQL版运维——浅谈事务回卷
关于 PolarDB PostgreSQL 版
PolarDB PostgreSQL 版是一款阿里云自主研发的云原生关系型数据库产品,100% 兼容 PostgreSQL,高度兼容Oracle语法;采用基于 Shared-Storage 的存储计算分离架构,具有极致弹性、毫秒级延迟、HTAP 、Ganos全空间数据处理能力和高可靠、高可用、弹性扩展等企业级数据库特性。同时,PolarDB PostgreSQL 版具有大规模并行计算能力,可以应对 OLTP 与 OLAP 混合负载。
什么是事务回卷
PolarDB PostgreSQL 的多版本并发控制(MVCC)通过为每一行(元组)创建多个版本来实现多个事务的同时进行而不会相互阻塞,其中每个版本对应于不同的时间点。在 MVCC 中,每个事务被分配一个唯一的事务 ID(XID),代表了事务执行的顺序,在MVCC中将通过事务id和事务的状态、提交顺序等关系来做可见性判断。而PostgreSQL 的事务 ID 是 32 位无符号整数,它们被分配给每个事务并且会递增。当它们达到最大值的一半(20亿)时,会环绕到零(类似于环形缓冲区),此时称之为发生了“事务回卷”。
事务回卷的危害
如果发生事务回卷后老事务id还存在,则这个事务id将会被认为“突然”出现在未来,使得MVCC机制判断错误,导致数据丢失。因此,为了避免数据丢失的风险,PolarDB PostgreSQL会记录下每个对象最老的事务id。后台定期发起autovacuum,进行自动清理任务将老事务标记为frozen状态,从而回收事务id。
一旦autovacuum回收的速度赶不上事务id消耗的速度,距离回卷点只剩下 3 百万个事务时,PolarDB PostgreSQL将会关闭并且拒绝开始任何新的事务。此时整个数据库实例都无法处理写请求。必须通过单用户模式执行vacuum命令冻结旧事务,才能重新将实例恢复可用。也就是说一旦年龄回卷,实例会立刻处于几乎不可用状态且恢复时间长,危害很大。
事务回卷预防性处理
合理配置实例autovacuum年龄回收相关参数
autovacuum_freeze_max_age\autovacuum_multixact_freeze_max_age(代表当表达到参数配置的年龄时,强制发起autovacuum开始回收年龄)如果实例压力大,事务id消耗快,这个配置需要配置的更小,让autovacuum更早的开始回收年龄。反之则可以配置的更大。
vacuum_failsafe_age(代表当表达到参数配置的年龄时,vacuum/autovacuum会跳过索引清理和堆表清理,仅仅只做回收年龄的事情,尽最快速度回收掉老事务),这个值要配置的比autovacuum_freeze_max_age\autovacuum_multixact_freeze_max_age更大一些,如果实例中表数据量较大,则要配置的偏小一些,让autovacuum更早的强制回收年龄。
关注实例大表autovacuum回收情况,针对大表单独配置相关参数,当表达到TB级别大小时,vacuum回收通常都需要不短的时间,如果实例事务id消耗较快,可以单独给大表配置参数
alter table my_big_table set(autovacuum_freeze_max_age = 200000000,autovacuum_multixact_freeze_max_age = 200000000);
复制
需要注意此命令需要获取4级锁
事务回卷后处理
进入单用户模式
查询所有数据库的年龄,定位年龄超限的数据库
SELECT datname, age(datfrozenxid) FROM pg_database;
复制
SELECT oid, relname, relfrozenxid, age(relfrozenxid) FROM pg_class where relfrozenxid != 0 order by age(relfrozenxid) desc limit 20;
复制