Greenplum中Heap表膨胀查看和解决方案

在某些情况下,因为底层存储架构的原因,GreenplumHeap表很容易出现膨胀(Bloat)Bloat会影响表的扫描性能,从而影响查询性能。

1.      什么是表膨胀?

表膨胀是指在一张表的数据文件中积累的自由空间(free space)被旧数据行使用。这些空间已经被之前删除或者不再访问的数据使用。不能做表的维护以重用这些空间,导致表数据文件越来越大,所以表扫描需要更长的时间。


2.      导致表膨胀的原因是什么?

Greenplum数据库的存储实现(MVCC-多版本并发控制)来自于Postgres。根据MVCC的原理,没有办法直接更新数据(更新操作(update)是通过先删除(delete)再插入(insert)实现的),被更新之前的行数据仍然在数据文件中,直到通过使用VACUUM命令使空间被标记为“free”。

一旦VACUUM将被删除的行数据标记为“free space”,这些空间就能够被将来的插入和更新操作使用。在更新操作后,VACCUM操作之前的这段时间,这些空间是没有标记为“free”,因此无法被重新使用,实际上这些空间为“dead space”。


3.      如何去识别表膨胀?

对于表膨胀,我们可以使用gp_toolkit的模式下面的几张表来查看。

A.    gp_toolkit.gp_bloat_diag

视图,显示膨胀表的诊断信息。

描述一下字段信息:

·        bdirelid:表的OID (pg_class.oid)

·        bdinspname:表所属Schema

·        bdirelname:表名

·        bdirelpages:当前表数据文件中的pages数量

·        bdiexppages:根据当前统计信息,期望的pages数量

·        bdidiagbloat诊断结果 (比率13表示:no bloat;比率从410表示:moderate bloat;比率从ratio大于10表示:significant bloat)


B.     gp_toolkit.gp_bloat_expected_pages

视图,显示数据库中所有表的page数据(currentpages/expected pages)

描述一下字段信息:

·        btdrelid:表的OID (pg_class.oid)

·        btdrelpages:表数据文件中,当前pages数量

·        btdexppages:根据当前统计信息,期望的pages数量

zy_db=# select *from gp_toolkit.gp_bloat_expected_pages limit 5;

btdrelid |btdrelpages | btdexppages

----------+-------------+-------------

10784 |           1 |          40

10789 |           1 |          40

10794 |           1 |          40

10799 |           1 |          40

5004 |           1 |          40

(5 rows)

 注意事项:

    这些视图依赖于表的统计信息进行计算bloat大小,因此表的统计信息要更新到最新的时间。

    Greenplum数据库的系统表是Heap表。因此很容易出现bloat。系统表对数据库的性能是很重要的,推荐定期对系统表进行vacumm

如果数据库中对象改变(create/drop/alter table)很少,建议每周vacuum,如果数据库中对象改变比较频繁,建议每天一次。



4.      如何避免和消除膨胀表

使用VACUUM命令去标记表的数据文件中被删除记录的空间为“free space”,用来重新使用这部分空间,因此我们需要消除表的膨胀。对于一张表来说,大量的update/delete/insert操作肯定会产生已删除行/空闲空间,这些空间将被新的数据重用。

通常情况下使用VACUUM可以保证被删除的数据行作为“free space”被重利用。但是这一些情况下,为了消除额外被占用的空间(如果从来没有被使用重新),需要使用VACUUM FULL命令,这个命令将会影响表数据,通过把表数据移动到数据文件的前面并且truncate数据文件末尾未被使用的空间,即涉及到空间合并操作。VACUUM FULL将会逐行操作,因此对大表来说,速度非常慢,并且在表上添加排它锁(exclusive lock)

VACUUM FULL建议在Greenplum数据库维护阶段执行,并且确保充分考虑运行时间和效果。

VACUUM FULL一旦运行不应该被用户终止掉。

相对VACUUM FULL来说,对用户数据表更好的选择是重分布表(不可以对系统表进行重分布),有效地在重构建表时消除膨胀。具体操作如下:

A. 查看表的分布键


B. ALTER TABLESET with (REORGANIZE=false) DISTRIBUTED randomly;

这一步仅仅标记表,并不会移动数据,命令立刻就执行完了。


C.     ALTER TABLE SET with (REORGANIZE=true)DISTRIBUTED BY (分布键字段);

重新写数据文件,因为分布键的原因,其实并没有在数据文件的层面发生变化,也不会通过网络发送数据,只会在本地发生数据重写。简单来说,就是表数据是根据分布键分布到Greenplum集群的每个segment上,这步操作不会移动一个segment数据到另一个segment上,只会在自身segment上重写数据文件。

注:

    VACUUM FULL和替代VACCUM FULL的表重分布仅在特殊的情况下才使用。

    定期在用户数据表(insert/update/delete)以及系统表上执行VACUUM

你可能感兴趣的:(Greenplum)