日常清理

本文档介绍了如何正确、有效地进行周期性的 YMatrix 数据库表清理与维护及其基本原理。

1 什么是 YMatrix 的清理与维护?

YMatrix 强烈建议在生产系统中对数据库表进行周期性的清理维护。

周期性的清理依靠 VACUUM 命令实现,主要用于回收死元组(Dead Tuples)占用的存储空间。在正常的 YMatrix 操作中,通过更新删除或废弃的元组不会从其表中物理删除,它们会一直存在,直到 VACUUM 完成为止。因此有必要定期执行 VACUUM,特别是对于频繁更新的表。

大多数情况下,让自动清理守护进程(Autovacuum)来执行清理已经足够,你可能需要调整其中描述的自动清理参数来获得最佳结果。不过在一些情况下,也需要你能够使用手动管理的 VACUUM 等命令来对后台进程的活动进行补充或者替换,这通常使用 cron 脚本或任务计划程序脚本来执行。

2 为什么要进行周期性的清理与维护?

出于以下原因,必须定期清理与维护 YMatrix 数据库中的每一张表:

  • 恢复或重用被已更新或已删除行所占用的磁盘空间。在 YMatrix 中,一次行的 UPDATEDELETE 不会立即移除该行的旧版本。这种方法对于从多版本并发控制(MVCC)获益是必需的:当旧版本仍可能对其他事务可见时,它不能被删除。但是最后,任何事务都不会再对一个过时的或者被删除的行版本感兴趣。它所占用的空间必须被回收来用于新行,这样可避免磁盘空间需求的无限制增长。
  • 更新被优化器使用的数据统计信息。
  • 更新可见性映射,它可以加速只用索引的扫描。
  • 保护老旧数据不会由于事务 ID 回卷或多事务 ID 回卷而丢失。

3 怎么进行有效的清理与维护?

3.1 手动清理

手动清理通过运行 VACUUM SQL 语句完成。

例如,清理某一张表:

=# VACUUM <tablename>;

清理所有表:

=# VACUUM;

除标准 VACUUM 语句外,还可以使用 VACUUM FULL 语句进行清理维护。VACUUM FULL 可以收回更多磁盘空间但是运行起来更慢。另外,标准形式的 VACUUM 可以和生产数据库操作并行运行(SELECTINSERTUPDATEDELETE 等命令将继续正常工作,但在清理期间你无法使用 ALTER TABLE 等命令来更新表的定义)。但 VACUUM FULL 要求在其工作的表上得到一个排他锁,因此无法和对此表的其他使用并行。因此,通常管理员应该努力使用标准 VACUUM 并且避免 VACUUM FULL

对于不同存储表而言,在其执行 VACUUM 清理命令的过程中,对其他 SQL 语句的阻塞程度有以下差别:

存储引擎 INSERT UPDATE DELETE ALTER SELECT 物理文件大小
HEAP 不阻塞 不阻塞 不阻塞 阻塞 不阻塞 不变
AO 不阻塞 不阻塞 不阻塞 阻塞 不阻塞 收缩
MARS2/MARS3 不阻塞 不阻塞 不阻塞 阻塞 不阻塞 收缩

注意!
VACUUM 会产生大量 I/O 流量,这将导致其他活动会话性能变差。可以调整一些配置参数来后台清理活动造成的性能冲击,详见基于代价的清理延迟

3.2 自动清理

自动清理通过 Autovacuum 守护进程完成,其目的是自动执行 VACUUMANALYZE 命令。当被启用时:

  • Autovacuum 会检查被大量插入、更新或删除元组的表,两次检查操作的间隔时间由参数 autovacuum_naptime 定义。
  • Autovacuum 守护进程实际上由多个进程组成,那么一次可以同时运行多少个进程,则由 autovacuum_max_workers 参数定义,默认调用 3 个 工作者进程进行工作。
  • Autovacuum 进程什么时候触发 VACUUM
    • 如果由于更新或删除操作,某表实际死亡元组数(Dead Tuples)超过下方公式所计算出的有效阈值,则该表将成为 Autovacuum 候选表:autovacuum_vacuum_scale_factor * 该表总元组数 + autovacuum_vacuum_threshold
  • Autovacuum 进程什么时候触发 ANALYZE
    • 自上次分析操作结束后,进行了插入/删除/更新操作的元组数超过下方公式所计算出的有效阈值的任何表都有资格进行 Autovacuum 分析:autovacuum_analyze_scale_factor * 该表总元组数 + autovacuum_analyze_threshold

开启自动清理功能并重新加载配置文件即可生效:

$ gpconfig -c autovacuum -v on
$ mxstop -u

注意!
需同时保证 track_counts 开启(SET track_counts TO on;)自动清理进程才能生效,此参数默认开启。

注意!
自动清理相关配置参数详见自动清理参数