第13期吐槽:十个中年人有九个发福的,数据库用久了也会变胖!这一期吐槽PG膨胀收缩之痛,tom lane啊您为啥不根治膨胀呢?
文中参考文档点击阅读原文打开, 同时推荐2个学习环境:
1、懒人Docker镜像, 已打包200+插件:《最好的PostgreSQL学习镜像》
2、有web浏览器就能用的云起实验室: 《免费体验PolarDB开源数据库》
3、PolarDB开源数据库内核、最佳实践等学习图谱: https://www.aliyun.com/database/openpolardb/activity
第13期吐槽:PG 减肥之痛
1、产品的问题点
当表膨胀后普通的vacuum 操作无法回收已经占用的磁盘空间, (仅末尾空块可从磁盘回收).
使用pg_repack(增量复制+数据文件filemap切换, 短暂锁表)或vacuum full(要锁全表, 影响业务)回收磁盘占用的空间都需要额外的磁盘来临时存储重组后的数据.
2、问题点背后涉及的技术原理
普通的vacuum只能truncate数据文件末尾的空block, 所以我们可以将末尾的tuple移动到前面, 从而从磁盘回收末尾的block.
为什么只能truncate数据文件末尾的空block?
因为非末尾的block被清掉之后, 这个存储在被清理的block之后的block里面的记录的寻址会发生变化, 例如第二个数据块回收掉, 那么2号数据块后面的数据块的编号都需要减1, 而索引的ctid指向的是原来的编号, 因此会导致索引内容错误. 当然, 我们可以在meta信息里增加1个bitmap文件存储真空块(已回收的中间blockid, 寻址时通过这个数据再进行block定位), 但是会增加寻址的复杂度, 性能可能下降. 而且PG使用的是文件系统管理, 可能还需要文件系统支持这样的"空间压缩技术".
3、这个问题将影响哪些行业以及业务场景
频繁更新的业务
《DB吐槽大会,第1期 - PG MVCC真头疼》
4、会导致什么问题?
如果你的环境已经拮据到无法提供额外的磁盘空间来存放整理后的数据, 那么将无法实施回收操作.
5、业务上应该如何避免这个坑
我之前写过一篇这样的文章, 《PostgreSQL 通过行迁移 无需额外空间 回收垃圾膨胀磁盘空间》
6、业务上避免这个坑牺牲了什么, 会引入什么新的问题
以上方法的维护成本较高, 一般用户不懂.
7、数据库未来产品迭代如何修复这个坑
希望内核层支持行迁移功能. 并且可以配合autovacuum, vacuum来进行使用.
希望内核层支持在线收缩表空间功能: pg_repack. 降低长期持有排他锁影响业务(因为膨胀表通常就是被频繁更新的表, 排他锁会堵塞所有的sql).
希望内核能尽量避免膨胀. 例如: 使用类似undo的回滚段代替多版本, 数据文件就不容易膨胀. 或者根据负载自动整理碎片(行迁移, 释放末尾块).
本期彩蛋-招商中...
大家喜欢这个周边吗,一个精美顺滑的魔方,准备去薅一些来送给公众号的粉丝们,谢谢你们的陪伴和支持。
文章中的参考文档请点击阅读原文获得.
欢迎关注我的github (https://github.com/digoal/blog) , 学习数据库不迷路.
近期正在写公开课材料, 未来将通过视频号推出, 欢迎关注视频号: