PostgreSQL Autovacuum 从不懂到专家 初识Autovacuum

2021-12-13 00:00:00 参数 文件 都是 触发 行数

弄清楚POSTGRESQL 的Autovacuum  he  vacuum 对于维护好POSTGRESQL 和 理解一些在基于POSTGRESQL 设计中的"点" 是有必要性的. 虽然数据库是有包容性的,但他有他自己的"脾气", 如果你非要和他过不去,那后面发生的事情或许是你不愿意见到的。


POSTGRESQL的使用的人员必须要知道的一件事情, 说起这个问题其实就和POSTGRESQL 数据库内部设计有关了,他并没有MYSQL 和ORACLE 的 undo log ,那么对于数据的回滚方面,必然要保留事务中的多版本操作的数据,在满足了MVCC的需求,事务COMMIT 后,必然会在数据表中留下曾经的痕迹,而这些痕迹的抹除的工作就是Autovacuum 需要进行的了. 换句话,PostgreSQL的undo 在每张表中。


另一点,频繁的更新和删除行对于POSTGRESQL 并没有什么好处,归并一些UPDATE 的操作对POSTGRESQL 是有利的。不加以控制,POSTGRESQL 会因为这样不恰当的操作导致表空间的bloating,当出现表膨胀后,就必须使用 autovacuum  的进程来标记和清理dead tuple.另外从性能的角度,不及时将这些dead tuple 进行清理,轻则影响磁盘空间的在利用,导致本来一张5G的表,终可能需要10G 甚至更大的空间来存储。同时每个dead tuple 还牵扯这index 的问题,以及多版本比对时造成的性能损耗,所以一个表的 dead tuple 越多,数据查询的性能也就越来越低。 这也是postgresql  核心问题之一。

下面我们看看相关的原理,回收操作对哪些系统或者文件进行了操作,这里牵扯到 visibility map  ,  Free space map , freeze tuple 这几个问题了。visibility map 是对数据页面文件的可读文件进行标记的文件,一个比特管理一个页面文件,标记为1 则说明这个页面包含的tuples 都是可见的有效的,如果这个bit设置为0, 说明对于所有的事务,这个页面都是不可见的。vm文件对于table 和 index 都是有效的, 一个数据文件对应一个vm文件,fm文件,记录数据表中的可用的空间记录。

下面我们做一个实验,通过pgbench 来产生一些测试数据

pgbench -n -r -T 60 -P 1 -c 500 -j 64


select schemaname,relname,n_tup_ins,n_tup_upd,n_tup_del,n_live_tup,n_dead_tup,last_autovacuum,autovacuum_count from pg_stat_all_tables where schemaname = 'public';


通过上面的语句我们可以先查看一下当前的postgresql 中的表的dead tuple 以及autovacuum 的情况。

从中这边可以发现,我们这些表中有的已经进行了autovacuum 有些没有,并且存在dead tuple.


提出问题


1  什么条件 autovacuum 对表进行vacuum  工作


2  autovacuum 进行了什么样的工作


3  autovacuum 是否可以被关闭


4  autovacuum 调整的参数有那些


5  autovacuum 针对某个特殊表进行调节


6  autovacuum 的工作情况怎么了解


以上问题会分期来进行解决和回答,本期先回答个问题


1  什么条件 autovacuum  对表进行vacuum 工作

实际上 autovacuum 本身并没有想象的简单,他需要完成的工作除了上面提到 cleanup dead tuples ,同时他还的想如何减少在工作期间对系统的用影响。那么什么时间,什么频率 autovacuum来出来进行工作就是一个要考虑的问题。


这里抛出一个问题,如果我们通过上面的语句来查询dead tuple ,每次查询某个表的 dead tuple 的数量都特别的大, 这说明一个问题, autovacuum 做的不够多 (当然也有可能是一些long transaction,这个问题不在这个问题的考虑范围)。


实际上什么时间对表进行autovacuum 这个问题,应该换成频率,什么样的情况下会触发 autovacuum对表进行操作。

这里有两个关键的参数

autovacuum_vacuum_threshold  这个参数主要是指定表中变动的tuple数,超过这个数字会触发autovacuum 对这个表进行整理

autovacuum_vacuum_scale_factor  这个参数主要指定表的变动行占整体表的百分之几,超过这个占用的比率会触发  autovacuum


在操作过程中,如果表符合上述的两个条件,被autovacuum 扫描到就开始进行整理。具体的过程为  修改表的行数 + 修改表的百分比*总的表的行数  <  实际修改的表的行数


举例: 我们本次修改的行数为 200行  , autovacuum_vacuum_threshold = 50   autovacuum_vacuum_scale_factor = 0.1 ,目前表的行数为1000000 一百万。

则 计算公式为 1000000 * 0.1 + 50 = 10万零50  当修改的表超过这个行数,才能触发autovacuum 。所以一个表随着数据行数越来越多,则会导致触发autovacuum 越来越少,终导致表的膨胀越来越大。所以调整autovacuum 的参数对于一个基于postgresql核心的数据库是非常重要的。


下期我们说说怎么针对表来改变参数,和PG对整体表的autovacuum 参数列表。



相关文章