Tom Lane老师, 求求你别挤牙膏了, 先解决xid回卷的问题吧
文中参考文档在github需点击阅读原文打开, 同时推荐2个学习环境:
1、懒人Docker镜像, 已打包200+插件:《最好的PostgreSQL学习镜像》
德哥邀你鞭策数据库第2期 - PG, 求求你别挤牙膏了, 先解决一下xid回卷的问题吧
开源技术沙龙杭州站预告:
「杭州*康恩贝」4月26日PolarDB开源数据库沙龙,开启报名!
第2期视频回放地址: https://www.bilibili.com/video/BV15U4y1j7Ud/
1、产品的问题点
事务号xid是uint32类型, 最多只能存储40亿个事务号, 事务号必须循环使用.
2、问题点背后涉及的技术原理
事务号是事务的标记, 在row的头信息中存储着这条记录是由哪个事务写入、更新、删除的. 数据库需要通过事务号来判断事务是过去的还是未来的事务.
大于当前事务号、或者大于当前事务快照最小未分配事务号的都是未来的事务, 对当前query不可见.
由于xid只能存储40亿个事务, 所以很快就会耗尽, PG为了解决耗尽问题, XID就需要重复使用, 怎么重复使用呢?
通过设置一个全局的frozenxid, 将XID的40亿切成2半, 把XID的可用空间想象成一个圆, frozenxid就在这个圆上移动, 处于它顺时针方向的一半属于已消耗的事务号(在过去), 处于它逆时针方向的一半属于可分配的事务号(在未来).
随着数据库事务发起xid不断消耗, 这个 frozenxid 必须在事务号消耗20亿之前发生移动, 否则就变成全部都是已分配事务了.
frozenxid怎么移动呢?
为了让frozenxid移动, 我们必须对全集群的表进行扫描, 把已有的记录头信息中设置对应的bit位, 表示这条记录已经是frozen的, 因此这个集群的frozenxid就在圆上往前移动了. 它可以使用的事务号半圆内又有足够的事务号可以分配.
frozenxid在圆上 老的位置 与 新的位置 这段区间内的xid就是被标记了了bit的事务.
什么时候会触发frozen操作呢?
autovacuum会定时(参数设定)扫描系统表, 发现达到阈值的表会触发frozen操作.
3、这个问题将影响哪些行业以及业务场景
频繁更新的业务. 和MVCC那一期一样.
4、会导致什么问题?
frozen操作需要扫描全表, 会产生较大IO.
如果frozen不及时, 严重的(如剩余可分配事务号低于100万时)要停库进入单用户模式执行frozen.
如果大量的表在一个较小的时间窗口内都触发了frozen, 那么会发生frozen风暴, 主库IO使用量暴增, 导致性能问题, 同时如果产生大量wal日志, 会导致从库复制延迟.
5、业务上应该如何避免这个坑
PG 内核的优化: 对于已frozen后没有变化过的PAGE可以跳过以减少扫描. 所以更新不频繁的系统frozen发生时系统的消耗并不高.
海量静态数据写入时即设置为freeze标记位, 避免二次freeze.
使用更好的SSD, 加速frozen, 降低frozen IO影响.
主、从库之间采用更大带宽的网络
设置autovacuum sleep间隙, 降低frozen IO影响.
不同的表, 或者分区, 不同分区设置不同的frozen阈值, 避免同时发生frozen操作产生风暴.
《PostgreSQL Freeze 风暴预测续 - 珍藏级SQL》
《PostgreSQL freeze 风暴导致的IOPS飙升 - 事后追溯》
《PostgreSQL的"天气预报" - 如何预测Freeze IO风暴》
《PostgreSQL 大表自动 freeze 优化思路》
6、业务上避免这个坑牺牲了什么, 会引入什么新的问题
增加了管理成本
增加了硬件成本
7、数据库未来产品迭代如何修复这个坑
64位xid
例如 zedstore, zheap, postgrespro 等引擎.
欢迎关注我的github (https://github.com/digoal/blog) , 学习数据库不迷路.
近期正在写公开课材料, 未来将通过视频号推出, 欢迎关注视频号:
文章中的参考文档请点击阅读原文获得.