GaussDB for DWS表膨胀原理(上)

举报
不爱问问题 发表于 2020/06/19 15:12:39 2020/06/19
【摘要】 DWS表膨胀原理1 背景对GaussDB for DWS数据库有一定了解的朋友都知道GaussDB for DWS的UPDATE, DELETE操作是通过新增tuple版本提供高并发处理的. 这样带来一个问题是需要经常vacuum 表, 回收老版本占用的存储空间. 只有回收的空间才能被重复利用, 如果回收不及时将会造成表的膨胀效应。2 表膨胀的原因经常看到有人说表又膨胀了,那么导致对象膨胀的...

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 threshfactor,那么默认使用参数文件配置的值。如下:

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:活跃行数;

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。