查看原文
其他

Tom Lane老师, 求求你别挤牙膏了, 先解决xid回卷的问题吧

digoal PostgreSQL码农集散地 2024-07-08

文中参考文档在github需点击阅读原文打开, 同时推荐2个学习环境: 

1、懒人Docker镜像, 已打包200+插件:《最好的PostgreSQL学习镜像

2、有web浏览器就能用的云起实验室: 《免费体验PolarDB开源数据库
3、PolarDB开源数据库内核、最佳实践等学习图谱:  https://www.aliyun.com/database/openpolardb/activity 
关注公众号, 持续发布PostgreSQL、PolarDB、DuckDB等相关文章. 


德哥邀你鞭策数据库第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) , 学习数据库不迷路.  

近期正在写公开课材料, 未来将通过视频号推出, 欢迎关注视频号:

文章中的参考文档请点击阅读原文获得. 


继续滑动看下一个
向上滑动看下一个

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存