日常系统维护任务

日常系统维护任务

要保持一个Greenplum数据库系统高效运行,必须对数据库定期清理过期数据并且更新表统计信息,这样查询优化器才能有准确的信息。

Greenplum数据库要求定期执行特定的任务来达到最优性能。这里讨论的任务都是必须的,但数据库管理员可以使用标准的UNIX工具(如cron脚本)来自动化这些任务。管理员建立适当的脚本并且检查它们是否成功执行。关于用来保持Greenplum系统最优化运行的额外建议维护活动,请见推荐的监控和维护任务

例行清理和分析

Greenplum数据库中使用的MVCC事务并发模型的设计意味着被删除或者被更新的数据行仍在磁盘上占据物理空间,即便它们已经对新事务不可见。如果数据库进行了很多更新和删除,会有很多过期行存在并且它们所使用的空间必须使用VACUUM命令来回收。VACUUM命令还会收集表级的统计信息,例如行数和页面数,因此即便无需从被更新或者被删除行回收空间,也还是有必要去清理追加优化表。

清理一个追加优化表遵循一种和清理堆表不同的处理。在每一个Segment上,会创建一个新的Segment文件并且把可见行从当前Segment复制到该文件中。当Segment文件被拷贝完时,将会安排删除原始的Segment文件并且让新的Segment文件变得可用。这要求足够的可用磁盘空间用于拷贝可见行,直到原始的Segment文件被删除为止。

如果一个Segment文件中隐藏行和所有行的比率低于一个阈值(默认是10),该Segment文件不会被紧缩。该阈值可以通过gp_appendonly_compaction_threshold服务器配置参数配置。VACUUM FULL忽略gp_appendonly_compaction_threshold的值并且不管该比率为多少都会重写Segment文件。

可以使用gp_toolkit方案中的__gp_aovisimap_compaction_info()函数来研究追加优化表上的VACUUM操作的效果。

有关__gp_aovisimap_compaction_info()函数的信息请见Greenplum数据库参考指南中的“检查追加优化表”。

可以使用gp_appendonly_compaction服务器配置参数为追加优化表禁用VACUUM

有关清理数据库的细节请见清理数据库

有关gp_appendonly_compaction_threshold服务器配置参数和VACUUM命令的信息请见Greenplum数据库参考指南

事务ID管理

Greenplum的MVCC事务语义依赖于比较事务ID(XID)号来判断对于其他事务的可见性。事务ID号使用一种模232的计算方法比较,因此一个运行了超过二十亿事务的Greenplum系统可能会遇到事务ID回卷,即过去的事务变成了未来的事务。这意味着过去的事务的输出变得不可见。因此,每过二十亿个事务就有必要VACUUM每个数据库中的每个表至少一次。

Greenplum数据库只对涉及DDL或者DML操作的事务分配XID值,通常也只有这些事务需要XID。

重要: Greenplum数据库会监控事务ID。如果没有定期清理数据库,Greenplum数据库将产生警告和错误。

当事务ID中相当多的一部分变得不再可用并且事务ID回卷还没有发生时,Greenplum数据库会发出下面的警告:

WARNING: database "database_name" must be vacuumed within number_of_transactions transactions

当这个警告被发出时,需要一次VACUUM操作。如果没有执行VACUUM操作,当Greenplum数据库在事务ID回卷发生前达到一个限制,它会停止创建新的事务。在停止创建事务以避免可能的数据丢失时,Greenplum数据库会发出这个错误:

FATAL: database is not accepting commands to avoid 
wraparound data loss in database "database_name"

Greenplum数据库配置参数xid_warn_limit控制何时显示该警告。参数xid_stop_limit控制何时Greenplum数据库停止创建事务。

从一次事务ID限制错误中恢复

当Greenplum数据库由于不频繁的VACUUM维护而达到xid_stop_limit事务ID限制时,它会变得没有响应。为了从这种情况中恢复过来,作为数据库管理员执行下面的步骤:

  1. 关闭Greenplum数据库。
  2. 临时将xid_stop_limit降低10,000,000。
  3. 启动Greenplum数据库。
  4. 在所有受影响的数据库上运行VACUUM FREEZE
  5. xid_stop_limit重置为原来的值。
  6. 重启Greenplum数据库。

有关这些配置参数的信息请见Greenplum数据库参考指南

有关事务ID回卷的信息请见PostgreSQL文档

系统目录维护

很多次使用CREATEDROP命令的数据库更新会增长系统目录尺寸并且影响系统性能。例如,运行很多次DROP TABLE语句会降低总体系统性能,因为在目录表上的元数据操作期间会需要过多的数据扫描。性能损失会在数千次或者数万次DROP TABLE语句之间发生,具体时机取决于系统。

应该定期地运行系统目录维护过程来回收已删除对象所占据的空间。如果很长时间没有运行这种定期过程,就可能需要运行一个更强的过程来清理系统目录。这个主题会描述这两种过程。

常规系统目录维护

推荐周期性地在系统目录上运行VACUUMREINDEX来清理系统表和索引中已删除对象所占用的空间。如果常规的数据库操作包括很多DROP语句,那么每天在非峰值时间用VACUUM运行一次系统目录维护过程是安全且合适的。用户可以在系统可用时执行这种操作。

下面的示例脚本在一个Greenplum数据库系统目录上执行一次VACUUMREINDEX以及ANALYZE

#!/bin/bash
DBNAME="<database-name>"
SYSTABLES="' pg_catalog.' || relname || ';' from pg_class a, pg_namespace b 
where a.relnamespace=b.oid and b.nspname='pg_catalog' and a.relkind='r'"
psql -tc "SELECT 'VACUUM' || $SYSTABLES" $DBNAME | psql -a $DBNAME
reindexdb --system -d $DBNAME
analyzedb -s pg_catalog -d $DBNAME

深度系统目录维护

如果很长时间都没有指定一次系统目录维护过程,该目录可能因为死亡空间而膨胀。这会导致简单的元数据操作都会出现很长的等待时间。列举用户表(例如在psql中用\d元命令)需要超过两秒的等待,就是目录膨胀的一种征兆。

如果发现系统目录膨胀的征兆,就必须在计划好的停机时段用VACUUM FULL执行一次深度系统目录维护过程。在这一时段中,停止系统上的所有目录活动,这种FULL系统目录维护过程会对系统目录取排他锁。

运行定期系统目录维护过程可以防止对这种更高开销过程的需求。

为查询优化进行清理和分析

Greenplum数据库使用一种基于代价的查询优化器,它依赖于数据库的统计信息。准确的统计信息允许查询优化器更好的估计选择度以及一个查询操作检索的行数。这些估计会帮助它选择最有效的查询计划。ANALYZE命令会为查询优化器收集列级的统计信息。

可以在同一个命令中运行VACUUMANALYZE操作。例如:

=# VACUUM ANALYZE mytable;

VACUUM ANALYZE命令被运行在一个显著膨胀的表(显著数量的表磁盘空间被已删除或者已废弃行占据)上时,该命令可能会产生不正确的统计信息。对于大型的表,ANALYZE命令会从行的一个随机采样中计算统计信息。它会通过计算采样中每页的平均行数与表中实际页数的成绩来估算表中的总行数。如果采样包含很多空页,估计出的行计数可能会不准确。

对于一个表,可以在gp_toolkit视图gp_bloat_diag中查看有关未使用磁盘空间(被已删除或者已废弃行占据的空间)量的信息。如果一个表的bdidiag列包含值significant amount of bloat suspected,那么相当多的表磁盘空间由未使用空间组成。在一个表被清理后,相关项会被加入到gp_bloat_diag视图中。

要从表中移除未使用的磁盘空间,可以在该表上运行命令VACUUM FULL。由于对表锁的需求,VACUUM FULL可能无法在非维护时段运行。

作为一种临时的变通方案,可以运行ANALYZE来计算列统计信息,然后在该表上运行VACUUM来生成准确的行计数。这个例子在cust_info表上先运行ANALYZE,然后运行VACUUM
ANALYZE cust_info;
VACUUM cust_info;
重要: 如果想要在启用了GPORCA(默认启用)的情况下对分区表执行查询,必须用ANALYZE ROOTPARTITION命令在分区表根分区上收集统计信息。有关GPORCA的信息,请见GPORCA概述
注意: 可以使用Greenplum数据库工具analyzedb来更新表统计信息。表可以被并行地分析。对于追加优化表,只有统计信息不是当前值时,analyzedb才会更新统计信息。有关analyzedb工具的信息,请见Greenplum数据库工具指南

例行的重新索引

对于B-树索引,一个刚刚构建的索引访问起来比一个已经更新过很多次的索引要快一点,因为在新构建的索引中逻辑上相邻的页面在物理上也相邻。定期地重新索引旧的索引可以提升访问速度。如果一个页面上除了节索引键之外的所有东西都已经被删除,该索引页面上将会有被浪费的空间。一次重新索引将会回收那些被浪费的空间。在Greenplum数据库中先删除一个索引(DROP INDEX)再创建它(CREATE INDEX)常常比使用REINDEX命令更快。

对于有索引的表列,批量更新或者插入之类的一些操作可能会执行得更慢,因为需要更新索引。为了提高带有索引的表上的批量操作性能,可以先删除掉索引,然后执行批量操作,最后再重建索引。

管理Greenplum数据库日志文件

数据库服务器日志文件

Greenplum数据库的日志输出常常会体量很大,尤其是在较高的调试级别时,用户不需要无限期保存它。管理员可以定期地轮转日志文件,这样会创建新的日志文件并且删除掉旧的日志文件。

Greenplum数据库在Master和所有的Segment实例上都启用了日志文件轮转。每日的日志文件被创建在Master以及每个Segment的数据目录中的pg_log子目录下,这些文件使用下面的命名习惯: gpdb-YYYY-MM-DD_hhmmss.csv。尽管日志文件每日都会轮转,但它们不会被自动截断或者删除。管理员需要实现脚本或者程序来定期清理Master和每个Segment实例的pg_log目录中的旧日志文件。

有关查看数据库服务器日志文件的信息,请见查看数据库服务器日志文件

管理工具日志文件

Greenplum数据库管理工具的日志文件默认被写入到~/gpAdminLogs。管理日志文件的命名习惯是:

script_name_date.log

日志项的格式是:

timestamp:utility:host:user:[INFO|WARN|FATAL]:message

每次一个工具运行时,就会向其每日的日志文件中增加与其执行相关的日志信息。