GreenPlum中的vaccum操作及臃肿管理

Greenplum 数据库的堆表使用PostgreSQL 的多版本并发控制(MVCC)的存储实现方式。删除和更新的行仅仅是逻辑删除,其实际数据仍然存储在表中,只是不可见。这些删除的行,也称为过期行,由空闲空间映射表(FSM, Free Space Map)记录。 VACUUM 标记这些过期的行为空闲空间,并可以被后续插入操作重用。

VACUUM

VACUUM命令可以与其他查询并行运行。它会标记之前被过期行所占用的空间为空闲可用,如果剩余的空闲空间数量可观,它会把该页面加到该表的空闲空间映射中。当Greenplum数据库之后需要空间分配给新行时,它首先会参考该表的空闲空间映射以寻找有可用空间的页面。如果没有找到这样的页面,它会为该文件追加新的页面。

VACUUM不会合并页面或者减小表在磁盘上的尺寸,它回收的空间只是放在空闲空间映射中表示可用。为了阻止磁盘文件大小增长,重要的是足够频繁地运行VACUUM。运行VACUUM的频率取决于表中更新和删除(插入只会增加新行)的频率。重度更新的表可能每天需要运行几次VACUUM来确保通过空闲空间映射能找到可用的空闲空间。在运行了一个更新或者删除大量行的事务之后运行VACUUM也非常重要。

VACUUM FULL

VACUUM FULL命令会把表重写为没有过期行,并且将表减小到其最小尺寸。表中的每一页都会被检查,其中的可见行被移动到前面还没有完全填满的页面中,空页面会被丢弃。该表会被一直锁住直到VACUUM FULL完成。相对于常规的VACUUM命令来说,它是一种非常昂贵的操作,可以用定期的清理来避免或者推迟这种操作。最好是在一个维护期来运行VACUUM FULL。VACUUM FULL的一种替代方案是用一个CREATE TABLE AS语句重新创建该表并且删除掉旧表。
关于vaccum和vaccum full的实际应用,可参考链接:http://blog.itpub.net/29989552/viewspace-2128914/

空闲空间映射

运行VACUUM 时,堆表的过期行被加入到共享的空闲空间映射表(FSM)中。 FSM必须足够容纳过期行。如果不够大,则溢出FSM的空间不能被 VACUUM 回收。必须使用VACUUM FULL 或者其他方法回收溢出空间。
定期性运行VACUUM 可以避免FSM溢出。表越臃肿, FSM就需要记录越多的行。对于非常大的具有很多对象
的数据库,需要增加FSM 以避免溢出。
空闲空间映射位于共享内存中,它跟踪着所有表和索引的空闲空间。每一个表或者索引使用大约60字节的内存,每一个具有空闲空间的页面会使用6个字节。配置空闲空间映射尺寸的两个系统配置参数是:

max_fsm_pages

设置可以加入到共享空闲空间映射的磁盘页最大数量。每一个页槽需要消耗共享内存的6个字节。默认值是200000。这个参数必须被设置为max_fsm_relations值的至少16倍。

max_fsm_relations

设置共享内存中空闲空间映射所跟踪的关系的最大数量。这个参数应该被设置为一个大于表数量 + 索引数量 + 系统表数量总和的值。默认值为1000。在每个实例上每一个关系会消耗大约60字节的内存。这个参数值宜高不宜低。

如果空闲空间映射容量不足,一些具有可用空间的磁盘页将无法被加到其中,那么这些空间将无法被重用直至下一次VACUUM命令运行。这将会导致文件尺寸增长。

检测臃肿

用户可以运行VACUUM VERBOSE tablename来得到一份Segment上已移除的死亡行数量、受影响页面数以及有可用空闲空间页面数的报告。

查询pg_class系统表可以找出一个表在所有Segment上使用了多少页面。注意首先对该表执行ANALYZE确保得到的是准确的数据。

SELECT relname, relpages, reltuples FROM pg_class WHERE relname='tablename';

另一个有用的工具是gp_toolkit方案中的gp_bloat_diag视图,它通过比较一个表使用的实际页数和预期的页数来确定表膨胀。

SELECT * FROM gp_toolkit.gp_bloat_diag;

结果中包括中度或者严重膨胀的表。实际页数与期望页数之比位于4和10之间是中度膨胀,大于10为严重膨胀。
视图 gp_toolkit.gp_bloat_expected_pages 列出每个数据库对象实际使用的页数和期望使用的磁盘页数。

消除臃肿表

如果一个表膨胀严重,运行VACUUM 命令是不够的。对于小表,可以通过 VACUUM FULL <table_name>
回收溢出 FSM 的空间,降低表的大小。然而VACUUM FULL 操作需要 ACCESS EXCLUSIVE 锁,可能需要
非常久或者不可预测的时间才能完成。注意,消除大表膨胀的每种方法都是资源密集型操作,只有在极端情况下
才使用。
第一种方法是创建大表拷贝,删掉原表,然后重命名拷贝表。如:

gpadmin=# CREATE TABLE mytable_tmp AS SELECT * FROM mytable;
gpadmin=# DROP TABLE mytable;
gpadmin=# ALTER TABLE mytabe_tmp RENAME TO mytable;

第二种消除臃肿的方法是重分布。步骤为:
1.记录表的分布键;
2. 修改表的分布策略为随机分布;

ALTER TABLE mytable SET WITH (REORGANIZE=false)
DISTRIBUTED randomly;

此命令修改表的分布策略,但是不会移动数据。这个命令会瞬间完成。
3. 改回原来的分布策略

ALTER TABLE mytable SET WITH (REORGANIZE=true)
DISTRIBUTED BY (<original distribution columns>);

此命令会重新分布数据。因为和原来的分布策略相同,所以仅会在同一个段数据库上重写数据,并去掉过期行。

消除系统臃肿表

Greenplum数据库系统表(catalog)也是堆表,因为也会随着时间推移而变得臃肿。随着数据库对象的创建、修改和删除,系统表中会留下过期行。使用gpload 加载数据会造成臃肿,因为它会创建并删除外部表。(更建议使用gpfdist 加载数据)。
系统表膨胀会拉长表扫描所需的时间,例如生成解释计划时,需要频繁扫描系统表,如果它们变得臃肿,那么系统整体性能会下降。
建议每晚(至少每周)对系统表运VACUUM 。
如果系统表变得异常臃肿,则必须执行一次集中的系统表维护操作。对系统表不能使用CREATE TABLE AS SELECT 和上面介绍的重分布方法消除臃肿,只能在计划的停机期间运行VACUUM FULL 。在这个期间,停止系统上的所有系统表操作, VACUUM FULL 会对系统表使用排它锁。定期运行VACUUM 可以防止这种代价高昂的操作。

消除索引表臃肿

VACUUM 命令仅恢复数据表的空间,要恢复索引表的空间,使用REINDEX 重建索引。
使用REINDEX table_name 重建一个表的所有索引;使用REINDEX index_name 重建某个索引。

消除AO表索引、监控GreenPlum数据库日志文件,见参考3。

参考:
1.《GreenPlum数据库文档》–管理员指南章节–关于greenplum数据库中的并发控制小节
2.http://blog.itpub.net/29989552/viewspace-2128914/
3.《GreenPlum数据库最佳实践》

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值