GaussDB for DWS表膨胀原理(上)

网友投稿 835 2022-05-29

DWS表膨胀原理(上)

1 背景

对GaussDB for DWS数据库有一定了解的朋友都知道GaussDB for DWS的UPDATE, DELETE操作是通过新增tuple版本提供高并发处理的. 这样带来一个问题是需要经常vacuum 表, 回收老版本占用的存储空间. 只有回收的空间才能被重复利用, 如果回收不及时将会造成表的膨胀效应。

2 表膨胀的原因

经常看到有人说表又膨胀了,那么导致对象膨胀的常见原因有哪些呢?

2.1未开启autovacuum

对于未开启autovacuum的用户,同时又没有合理的自定义vacuum调度的话,表的垃圾没有及时回收,新的数据又不断进来,膨胀是必然的。(新的数据包括插入和更新,更新产生新版本的记录)

2.2 资源回收不及时

开启了autovacuum, 但是各种原因导致回收不及时,并且新的数据又不断产生,从而导致膨胀。回收不及时的原因:

当数据库非常繁忙时,如果IO比较差,会导致回收垃圾变慢,从而导致膨胀。

这种一般出现在数据库中存在非常巨大的表,并且这些表在执行whole table vacuum (prevent xid wrapped, 或当表的年龄大于vacuum_freeze_table_age时会全表扫),因此产生大量IO,这期间很容易导致自身或其他表膨胀。

什么情况会触发autovacuum呢?

* A table needs to be vacuumed if the number of dead tuples exceeds a

* threshold.  This threshold is calculated as

* threshold = vac_base_thresh + vac_scale_factor * reltuples

GaussDB for DWS表膨胀原理(上)

如果没有设置表级别的autovacuum thresh和factor,那么默认使用参数文件配置的值。如下:

int                     autovacuum_vac_thresh;  // 默认50

double          autovacuum_vac_scale;  // 默认0.2

也就是说dead tuple达到约为表的20%时,才触发autovacuum。然后回收又需要一定的时间,所以最终表的膨胀应该是超过20%的。

所有worker繁忙,某些表产生的垃圾如果超过阈值,但是在此期间没有worker可以为它处理垃圾回收的事情。导致可能发生膨胀。

如果数据库的表很多,而且都比较大,那么当需要vacuum的表超过了配置autovacuum_max_workers的数量,某些表就要等待空闲的worker。这个阶段就容易出现表的膨胀。

通过pg_stat_activity.backend_xid和backend_xmin来观察。

backend_xid表示已申请事务号的事务,例如有增删改,DLL等操作的事务。backend_xid从申请事务号开始持续到事务结束。

backend_xmin表示SQL执行时的snapshot,即可见的最大已提交事务。例如查询语句,查询游标。backend_xmin从SQL开始持续到SQL结束,如果是游标的话,持续到游标关闭。

当DWS数据库中存在未结束的SQL语句或者未结束的持有事务ID的事务,在此事务过程中,或在此SQL执行时间范围内产生垃圾的话,这些垃圾无法回收,导致数据库膨胀。

也即是判断当前数据库中backend_xid和backend_xmin最小的值,凡是超过这个最小值的事务产生的垃圾都不能回收。

在开启了autovacuum_vacuum_cost_delay后,会使用基于成本的垃圾回收,这个可以有利于降低VACUUM带来的IO影响,但是对于IO没有问题的系统,就没有必要开启autovacuum_vacuum_cost_delay,因为这会使得垃圾回收的时间变长。

唤醒时间由参数autovacuum_naptime决定,autovacuum launcher进程负责告诉postmaster需要fork worker进程来进行垃圾回收,但是如果autovacuum launcher进程一直在睡觉的话,那完蛋了,有垃圾了它还在睡觉,那不就等着膨胀吗?

例如对于一个10GB的表,一条SQL或一个事务中删除或更新9GB的数据,这9GB的数据必须在事务结束后才能进行垃圾回收,无形中增加了膨胀的可能。

大量的非HOT更新,会导致索引膨胀,对于BTREE索引来说,整个索引页没有任何引用才能被回收利用,因此索引比较容易膨胀。

专业名词

Relpages:以页(大小为BLCKSZ)为单位的此表在磁盘上的大小,它只是优化器用的一个近似值;

PageData:每个 page 头包含24字节固定长度;

PageNum:page的数量;

n_live_tup:估计活跃行数;

live tuple:活跃行数;

SQL 数据仓库服务 GaussDB(DWS)

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:自己动手写Python虚拟机读书会笔记
下一篇:死锁&活锁
相关文章