Greenplum支持行储存(HEAP储存)与列(append-only)储存,对于AO存储,虽然是appendonly,但实际上GP是支持DELETE和UPDATE的,被删除或更新的行,通过BITMAP来标记删除与修改。AO存储是块级组织,当一个块内的数据大部分都被删除或更新掉时,扫描它浪费的成本实际上是很高的。而PostgreSQL是通过HOT技术以及autovacuum来避免或减少垃圾的。但是Greenplum没有自动回收的worker进程,所以需要人为的触发。接下来就分析AO表与HEAP表的问题以及如何解答,执行空间的释放有3中方法分别是:
1、执行VACUUM。(当膨胀率大于gp_appendonly_compaction_threshold参数时),为共享锁。
2、执行VACUUM FULL。(不管gp_appendonly_compaction_threshold参数的设置,都会回收垃圾空间。),为DDL锁。
3、执行重分布。(不管gp_appendonly_compaction_threshold参数,都会回收垃圾空间。),为DDL锁。
stagging=# \timing
Timing is on.
stagging=# select distinct relstorage from pg_class ;
relstorage
------------
h
a
x
v
c
(5 rows)
Time: 6.132 ms
timing 打开SQL的执行时间
h = 堆表(heap)、索引
a = append only row存储表
c = append only column存储表
x = 外部表(external table)
v = 视图
stagging=# select t2.nspname, t1.relname from pg_class t1, pg_namespace t2 where t1.relnamespace=t2.oid and relstorage in ('c', 'a');
nspname | relname
---------+-------------------------------
test_ao | ao_table_test
(12 rows)
Time: 6.828 ms
可以看出来 ao_table_test为AO表
表的膨胀率也就是表中执行DELETE和UPDATE产生的垃圾
stagging=# select * from gp_toolkit.__gp_aovisimap_compaction_info('test_ao.ao_table_test'::regclass);
NOTICE: gp_appendonly_compaction_threshold = 10
(240 rows)
Time: 127.750 ms
test_ao : schema的名字
ao_table_test:当前schema下的表
gp_appendonly_compaction_threshold: AO的压缩进程,目前设置的是10
content:对应gp_configuration.content表示greenplum每个节点的唯一编号。
datafile:这条记录对应的这个表的其中一个数据文件的编号,每个数据文件假设1GB。
hidden_tupcount:有多少条记录已更新或删除(不可见)。
total_tupcount:总共有多少条记录(包括已更新或删除的记录)。
percent_hidden:不可见记录的占比。如果这个占比大于gp_appendonly_compaction_threshold参数,那么执行vacuum时,会收缩这个数据文件。
compaction_possible:这个数据文件是否可以被收缩。(通过gp_appendonly_compaction_threshold参数和percent_hidden值判断)。
在以上中可以看出在17节点上的第1号文件有2369294记录其中有671375条记录被更新或删除,其中不可见的比例为28.34%
stagging=# select * from (select t2.nspname, t1.relname, (gp_toolkit.__gp_aovisimap_compaction_info(t1.oid)).* from pg_class t1, pg_namespace t2 where t1.relnamespace=t2.oid and relstorage in ('c', 'a')) t where t.percent_hidden > 0.2;
(144 rows)
Time: 864.715 ms
以上命令是查询膨胀率超过千分之2的AO表
nspname: 表示查询的schema的名字
relname: 是当前schema的表的名字
在以上数据中可以看出在每个节点上的膨胀率也不同
stagging=# select pg_size_pretty(pg_relation_size('test_ao.ao_table_test'));
pg_size_pretty
----------------
16 GB
(1 row)
Time: 32.806 ms
在以上可以看出膨胀率占用了16G的空间
stagging=# select count(*) from test_ao.ao_table_test;
count
-----------
140324396
(1 row)
Time: 1842.706 ms
在以上的数据中可以看出膨胀率大于了gp_appendonly_compaction_threshold的值可以直接使用vacuum命令进行收缩
stagging=# vacuum test_ao.ao_table_test;
VACUUM
Time: 57800.144 ms
stagging=# select pg_size_pretty(pg_relation_size('test_ao.ao_table_test'));
pg_size_pretty
----------------
8859 MB
(1 row)
Time: 34.990 ms
以上可以看出已经释放了大部分的空间
stagging=# select * from (select t2.nspname, t1.relname, (gp_toolkit.__gp_aovisimap_compaction_info(t1.oid)).* from pg_class t1, pg_namespace t2 where t1.relnamespace=t2.oid and relstorage in ('c', 'a')) t where t.percent_hidden > 0.01;
以上命令是查询膨胀率超过万分之1的AO表
stagging=# select count(*) from test_ao.ao_table_test;
count
-----------
140324396
(1 row)
Time: 1680.919 ms
从以上可以看出与第一次查询出来的行数一直
stagging=# select * from (select t2.nspname, t1.relname, (gp_toolkit.__gp_aovisimap_compaction_info(t1.oid)).* from pg_class t1, pg_namespace t2 where t1.relnamespace=t2.oid and relstorage in ('c', 'a')) t where t.percent_hidden > 0.01;
stagging=# alter table test_ao.ao_table_test set with (reorganize=true) distributed randomly;
ALTER TABLE
Time: 81169.170 ms
stagging=# select * from (select t2.nspname, t1.relname, (gp_toolkit.__gp_aovisimap_compaction_info(t1.oid)).* from pg_class t1, pg_namespace t2 where t1.relnamespace=t2.oid and relstorage in ('c', 'a')) t where t.percent_hidden > 0.01;
注意在执行随机分布键是在非业务的时候执行,执行distribute会执行排它锁不,要堵塞业务。
stagging=# alter table test_ao.ao_table_test set with (reorganize=true) distributed by (pripid,s_ext_nodenum);
ALTER TABLE
Time: 82621.274 ms
stagging=# select * from (select t2.nspname, t1.relname, (gp_toolkit.__gp_aovisimap_compaction_info(t1.oid)).* from pg_class t1, pg_namespace t2 where t1.relnamespace=t2.oid and relstorage in ('c', 'a')) t where t.percent_hidden > 0.01;
注意在执行随机分布键是在非业务的时候执行,执行distribute会执行排它锁不,要堵塞业务。
stagging=# select count(*) from test_ao.ao_table_test;
count
-----------
140324396
(1 row)
Time: 1764.584 ms
stagging=# update test_ao.ao_table_test set alttime='2018-10-23 11:54:57.000000' where nodenum='850000';
受影响的行: 5701,7349
时间: 104.007s
stagging=# select * from (select t2.nspname, t1.relname, (gp_toolkit.__gp_aovisimap_compaction_info(t1.oid)).* from pg_class t1, pg_namespace t2 where t1.relnamespace=t2.oid and relstorage in ('c', 'a')) t where t.percent_hidden > 0.01;
(48 rows)
Time: 874.505 ms
在以上数据中可以看出57017349除以140324396大概是40% ,膨胀率大概是28.88左右。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。