文档首页/ 数据仓库服务 GaussDB(DWS)/ 常见问题/ 数据库性能/ GaussDB(DWS)表膨胀原因有哪些?该如何处理?
更新时间:2024-04-30 GMT+08:00
分享

GaussDB(DWS)表膨胀原因有哪些?该如何处理?

表膨胀的原因

  • 未开启autovacuum

    GaussDB(DWS)提供自动执行VACUUM和ANALYZE命令的系统自动清理进程(autovacuum),用于回收被标识为删除状态的记录空间,并更新表的统计数据。

    用户未开启autovacuum的同时又没有合理的自定义vacuum调度,导致表的脏数据没有及时回收,新的数据又不断插入或更新,膨胀是必然的。

  • 资源回收不及时

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

    • IO性能差

      当数据库非常繁忙时,如果IO性能较差,会导致回收脏数据变慢,从而导致表膨胀。

      这种情况一般出现在占用数据库内存较大的表上,并且这些表正在执行整表vacuum,因此产生大量IO,导致表自身或其他表膨胀。

    • autovacuum触发较迟

      触发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的数据必须在事务结束后才能进行脏数据回收,无形中增加了膨胀的可能。

减少或避免表膨胀

  • 开启autovacuum。
  • 提高系统的IO能力。
  • 调整触发阈值,让触发阈值和记录数匹配。
  • 增加autovacuum_max_workers和autovacuum_work_mem,同时增加系统内存。
  • IO性能较好的系统,关闭autovacuum_vacuum_cost_delay。
  • 设计应用程序时,避免使用大批量的更新、删除操作,可以切分为多个事务进行。
  • 应用程序设计时,尽量避免下列操作:
    • 打开游标后不关闭。
    • 在不必要的场景使用repeatable read或serializable事务隔离级别。
    • 对大的数据库执行gs_dump进行逻辑备份(隐式repeatable read隔离级别的全库备份)。
    • 长时间不关闭申请了事务号的事务(增、删、改等DDL操作的SQL)。

相关空间回收参数说明

  • autovacuum = on

    控制数据库自动清理进程(autovacuum)的启动。自动清理进程运行的前提是将track_counts设置为on。

  • log_autovacuum_min_duration = 0

    当自动清理的执行时间大于或者等于某个特定的值时,向服务器日志中记录自动清理执行的每一步操作。设置此选项有助于追踪自动清理的行为。

  • autovacuum_max_workers = 10

    设置能同时运行的自动清理线程的最大数量。

  • autovacuum_naptime = 1

    设置两次自动清理操作的时间间隔。

  • autovacuum_vacuum_cost_delay = 0

    设置在自动VACUUM操作里使用的开销延迟数值。

更多关于空间回收参数说明,参见自动清理

相关文档