Skip to content

Files

Latest commit

Dec 15, 2023
f400df2 · Dec 15, 2023

History

History
74 lines (44 loc) · 3.76 KB

20210818_01.md

File metadata and controls

74 lines (44 loc) · 3.76 KB

如何使用5why分析法发现数据库膨胀现象背后的本质?

作者

digoal

日期

2021-08-18

标签

PostgreSQL , 膨胀


背景

1、 什么是膨胀?

  • 实际占用空间超过需要的空间

2、 为什么会膨胀?

  • 更新或写入时无可用空间存放新的tuple

3、 为什么无可用空间存放新的tuple? 实际占用空间不是超过需要的空间吗?

  • 因为那些看似可用的空间里有tuple.

4、 为什么会有tuple存在? 不是已经delete或update的老版本吗? autovacuum不是会去清理吗?

  • 因为有未结束的2pc, 有未结束的事务, 有执行中的query, 这些query或事务可能是long long ago就开在那的. 这些已删除的老版本可能是在这些事务之后被删除的, 可能还要被访问到. 所以autovacuum不能清除它们.
  • 或者 autovacuum回收太慢(比如你花钱雇了个工人, 但是他在休息.)
  • 或者 autovacuum回收时index被扫描了若干遍. 《PostgreSQL 垃圾回收参数优化之 - maintenance_work_mem , autovacuum_work_mem》
  • 或者 磁盘性能太烂
  • 或者 autovacuum worker数量太少

5、 为什么它们可能还要被访问? 不是已经delete的dead tuple吗?

  • rr, ssi事务隔离级别了解一下好吗, 访问到的必须是事务开启时的状态.

6、 那不是1个状态吗? 为什么要保留所有dead tuple呢?

  • 嗯, 这个是PG的vacuum代码偷懒了, 实际上可以只保留需要的tuple版本. 那么如果1个tuple不管被更新了多少个版本, 膨胀概率也可以降低.

7、 那么有没有办法避免dead tuple无法被回收?

  • snapshot too old参数配置.
  • 设置参数, 不让autovacuum休息或者少休息.
  • 设置参数或监控, 别产生长事务, 2pc, long long ago query.
  • 调大存放临时dead tuple head的内存, 别让一次垃圾回收过程收集的dead tuple head存储超过内存maintenance_work_mem or autovacuum_work_mem
  • 分区, 同样也是解决上面这个问题.
  • 使用IO延迟较小的ssd.
  • 优化PG内核, 这个不适合所有人.

其他参考:
《解读用户最常问的PostgreSQL垃圾回收、膨胀、多版本管理、存储引擎等疑惑 - 经典》

您的愿望将传达给PG kernel hacker、数据库厂商等, 帮助提高数据库产品质量和功能, 说不定下一个PG版本就有您提出的功能点. 针对非常好的提议,奖励限量版PG文化衫、纪念品、贴纸、PG热门书籍等,奖品丰富,快来许愿。开不开森.

digoal's wechat