GaussDB(DWS)表膨胀原因有哪些?该如何处理?
表膨胀的原因
- 未开启autovacuum
GaussDB(DWS)提供自动执行VACUUM和ANALYZE命令的系统自动清理进程(autovacuum),用于回收被标识为删除状态的记录空间,并更新表的统计数据。
用户未开启autovacuum的同时又没有合理的自定义vacuum调度,导致表的脏数据没有及时回收,新的数据又不断插入或更新,膨胀是必然的。
- 资源回收不及时
开启了autovacuum,但是各种原因导致回收不及时,并且新的数据又不断产生,从而导致膨胀。回收不及时有以下原因:
- IO性能差
当数据库非常繁忙时,如果IO性能较差,会导致回收脏数据变慢,从而导致表膨胀。
这种情况一般出现在占用数据库内存较大的表上,并且这些表正在执行整表vacuum,因此产生大量IO,导致表自身或其他表膨胀。
- autovacuum触发较迟
- autovacuum线程繁忙
所有自动清理线程繁忙,某些表产生的脏数据超过阈值,但是在此期间没有autovacuum线程可以处理脏数据回收的事情,可能发生表膨胀。
如果数据库的表很多,而且都比较大,那么当需要vacuum的表超过了配置autovacuum_max_workers的数量,这些表就要等待空闲的autovacuum线程。这个阶段就容易出现表的膨胀。
- 数据库中存在长SQL或带XID的长事务
当DWS数据库中存在未结束的SQL语句或者未结束的持有事务ID的事务,在此SQL执行时间范围内或在此事务过程中产生的脏数据无法回收,导致数据库膨胀。
- 开启了autovacuum_vacuum_cost_delay
在开启了autovacuum_vacuum_cost_delay后,会使用基于成本的脏数据回收策略,可以有利于降低VACUUM带来的IO影响,但是对于IO性能高的系统,开启autovacuum_vacuum_cost_delay反而会使得垃圾回收的时间变长。
- autovacuum_naptime设置间隔时间过长
- 批量删除或更新大表
例如对于一个10GB的表,一条SQL或一个事务中删除或更新9GB的数据,这9GB的数据必须在事务结束后才能进行脏数据回收,无形中增加了膨胀的可能。
- IO性能差
减少或避免表膨胀
- 开启autovacuum。
- 提高系统的IO能力。
- 调整触发阈值,让触发阈值和记录数匹配。
- 增加autovacuum_max_workers和autovacuum_work_mem,同时增加系统内存。
- IO性能较好的系统,关闭autovacuum_vacuum_cost_delay。
- 设计应用程序时,避免使用大批量的更新、删除操作,可以切分为多个事务进行。
- 应用程序设计时,尽量避免下列操作:
- 打开游标后不关闭。
- 在不必要的场景使用repeatable read或serializable事务隔离级别。
- 对大的数据库执行gs_dump进行逻辑备份(隐式repeatable read隔离级别的全库备份)。
- 长时间不关闭申请了事务号的事务(增、删、改等DDL操作的SQL)。
相关空间回收参数说明
更多关于空间回收参数说明,参见自动清理。