Chapter 24. 日常数据库维护工作
和任何数据库软件一样,PostgreSQL需要定期执行特定的任务来达到最优的性能。这里讨论的任务是必需的,但它们本质上是重复性的并且可以很容易使用cron脚本或Windows的任务计划程序等标准工具来自动进行。建立合适的脚本并检查它们是否成功运行是数据库管理员的职责。
一个显而易见的维护任务是定期创建数据的后备拷贝。如果没有一个最近的备份,你就不可能在灾难(磁盘失败、或在、错误地删除一个关键表等)后进行恢复。PostgreSQL中的备份和恢复机制在Chapter 25中有详细的介绍。
另一种主要类型的维护任务是周期性地“清理”数据库。该活动在Section 24.1中讨论。与之相关,更新将被查询规划器使用的统计信息的活动将在Section 24.1.3中讨论。另一项需要周期性考虑的任务是日志文件管理。这在Section 24.3中讨论。
check_postgres1
可用于检测数据库的健康并报告异常情况。check_postgres
与Nagios和MRTG整合在一起,但也可以被单独运行。
相对于其他数据库管理系统,PostgreSQL的维护量较低。但是,适当对这些任务加以注意将大有助于愉快和高效地使用该系统。
24.1. 日常清理
PostgreSQL数据库要求周期性的清理维护。对于很多安装,让自动清理守护进程来执行清理已经足够,如Section 24.1.6所述。你可能需要调整其中描述的自动清理参数来获得最佳结果。某些数据库管理员会希望使用手动管理的VACUUM命令来对后台进程的活动进行补充或者替换,这通常使用cron或任务计划程序脚本来执行。要正确地设置手动管理的清理,最重要的是理解接下来几小节中讨论的问题。依赖自动清理的管理员最好也能略读该内容以帮助他们理解和调整自动清理。
24.1.1. 清理的基础知识
PostgreSQL的VACUUM命令出于几个原因必须定期处理每一个表:
- 恢复或重用被已更新或已删除行所占用的磁盘空间。
- 更新被PostgreSQL查询规划器使用的数据统计信息。
- 更新可见性映射,它可以加速只用索引的扫描。
- 保护老旧数据不会由于事务ID回卷或多事务ID回卷而丢失。
正如后续小节中解释的,每一个原因都将指示以不同的频率和范围执行VACUUM操作。有两种VACUUM的变体:标准VACUUM和VACUUM FULL。VACUUM FULL可以收回更多磁盘空间但是运行起来更慢。另外,标准形式的VACUUM可以和生产数据库操作并行运行(SELECT、INSERT、UPDATE和DELETE等命令将继续正常工作,但在清理期间你无法使用ALTER TABLE等命令来更新表的定义)。VACUUM FULL要求在其工作的表上得到一个排他锁,因此无法和对此表的其他使用并行。因此,通常管理员应该努力使用标准VACUUM并且避免VACUUM FULL。
VACUUM会产生大量I/O流量,这将导致其他活动会话性能变差。可以调整一些配置参数来后台清理活动造成的性能冲击 — 参阅Section 19.4.4。
24.1.2. 恢复磁盘空间
在PostgreSQL中,一次行的UPDATE或DELETE不会立即移除该行的旧版本。这种方法对于从多版本并发控制(MVCC,见Chapter 13)获益是必需的:当旧版本仍可能对其他事务可见时,它不能被删除。但是最后,任何事务都不会再对一个过时的或者被删除的行版本感兴趣。它所占用的空间必须被回收来用于新行,这样可避免磁盘空间需求的无限制增长。这通过运行VACUUM完成。
VACUUM的标准形式移除表和索引中的死亡行版本并将该空间标记为可在未来重用。不过,它将不会把该空间交还给操作系统,除非在特殊的情况中表尾部的一个或多个页面变成完全空闲并且能够很容易地得到一个排他表锁。相反,VACUUM FULL通过把死亡空间之外的内容写成一个完整的新版本表文件来主动紧缩表。这将最小化表的尺寸,但是要花较长的时间。它也需要额外的磁盘空间用于表的新副本,直到操作完成。
例行清理的一般目标是多做标准的VACUUM来避免需要VACUUM FULL。自动清理守护进程尝试这样工作,并且实际上永远不会发出VACUUM FULL。在这种方法中,其思想不是让表保持它们的最小尺寸,而是保持磁盘空间使用的稳定状态:每个表占用的空间等于其最小尺寸外加清理之间被用完的空间。尽管VACUUM FULL可被用来把一个表收缩回它的最小尺寸并将该磁盘空间交还给操作系统,但是如果该表将在未来再次增长这样就没什么意义。因此,对于维护频繁被更新的表,适度运行标准VACUUM运行比少量运行VACUUM FULL
要更好。
一些管理员更喜欢自己计划清理,例如在晚上负载低时做所有的工作。根据一个固定日程来做清理的难点在于,如果一个表有一次预期之外的更新活动尖峰,它可能膨胀得真正需要VACUUM FULL来回收空间。使用自动清理守护进程可以减轻这个问题,因为守护进程会根据更新活动动态规划清理操作。除非你的负载是完全可以预估的,完全禁用守护进程是不理智的。一种可能的折中方案是设置守护进程的参数,这样它将只对异常的大量更新活动做出反应,因而保证事情不会失控,而在负载正常时采用有计划的VACUUM来做批量工作。
对于那些不使用自动清理的用户,一种典型的方法是计划一个数据库范围的VACUUM,该操作每天在低使用量时段执行一次,并根据需要辅以在重度更