GaussDB for DWS表膨胀原理(上)
DWS表膨胀原理(上)
1 背景
对GaussDB for DWS数据库有一定了解的朋友都知道GaussDB for DWS的UPDATE, DELETE操作是通过新增tuple版本提供高并发处理的. 这样带来一个问题是需要经常vacuum 表, 回收老版本占用的存储空间. 只有回收的空间才能被重复利用, 如果回收不及时将会造成表的膨胀效应。
2 表膨胀的原因
经常看到有人说表又膨胀了,那么导致对象膨胀的常见原因有哪些呢?
2.1未开启autovacuum
对于未开启autovacuum的用户,同时又没有合理的自定义vacuum调度的话,表的垃圾没有及时回收,新的数据又不断进来,膨胀是必然的。(新的数据包括插入和更新,更新产生新版本的记录)
2.2 资源回收不及时
开启了autovacuum, 但是各种原因导致回收不及时,并且新的数据又不断产生,从而导致膨胀。回收不及时的原因:
2.2.1 IO差
当数据库非常繁忙时,如果IO比较差,会导致回收垃圾变慢,从而导致膨胀。
这种一般出现在数据库中存在非常巨大的表,并且这些表在执行whole table vacuum (prevent xid wrapped, 或当表的年龄大于vacuum_freeze_table_age时会全表扫),因此产生大量IO,这期间很容易导致自身或其他表膨胀。
2.2.2 autovacuum触发较迟
什么情况会触发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
如果没有设置表级别的autovacuum thresh和factor,那么默认使用参数文件配置的值。如下:
int autovacuum_vac_thresh; // 默认50
double autovacuum_vac_scale; // 默认0.2
也就是说dead tuple达到约为表的20%时,才触发autovacuum。然后回收又需要一定的时间,所以最终表的膨胀应该是超过20%的。
2.2.3 Worker繁忙
所有worker繁忙,某些表产生的垃圾如果超过阈值,但是在此期间没有worker可以为它处理垃圾回收的事情。导致可能发生膨胀。
如果数据库的表很多,而且都比较大,那么当需要vacuum的表超过了配置autovacuum_max_workers的数量,某些表就要等待空闲的worker。这个阶段就容易出现表的膨胀。
2.2.4 数据库中存在长SQL或带XID的长事务
通过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最小的值,凡是超过这个最小值的事务产生的垃圾都不能回收。
2.2.5开启了autovacuum_vacuum_cost_delay
在开启了autovacuum_vacuum_cost_delay后,会使用基于成本的垃圾回收,这个可以有利于降低VACUUM带来的IO影响,但是对于IO没有问题的系统,就没有必要开启autovacuum_vacuum_cost_delay,因为这会使得垃圾回收的时间变长。
2.2.6 autovacuum launcher process 唤醒时间太长
唤醒时间由参数autovacuum_naptime决定,autovacuum launcher进程负责告诉postmaster需要fork worker进程来进行垃圾回收,但是如果autovacuum launcher进程一直在睡觉的话,那完蛋了,有垃圾了它还在睡觉,那不就等着膨胀吗?
2.2.7批量删除或批量更新
例如对于一个10GB的表,一条SQL或一个事务中删除或更新9GB的数据,这9GB的数据必须在事务结束后才能进行垃圾回收,无形中增加了膨胀的可能。
2.2.8大量的非HOT更新
大量的非HOT更新,会导致索引膨胀,对于BTREE索引来说,整个索引页没有任何引用才能被回收利用,因此索引比较容易膨胀。
专业名词
Relpages:以页(大小为BLCKSZ)为单位的此表在磁盘上的大小,它只是优化器用的一个近似值;
PageData:每个 page 头包含24字节固定长度;
PageNum:page的数量;
n_live_tup:估计活跃行数;
live tuple:活跃行数;
- 点赞
- 收藏
- 关注作者
评论(0)