Greenplum 列存表(AO表)的膨胀和垃圾检查与空间收缩

1.Greenplum产生垃圾空间说明

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锁

2.查看表的储存类型

名字 引用 描述
regproc pg_proc 函数名字
reprocedure pg_proc 带参数类型的函数
regoper pg_operator 操作符名
regoperator pg_operator 带参数类型的操作符名
regclass pg_class 关系名

2.1 执行查看命令

analticdb=# \timing
Timing is on.
analticdb=# select distinct relstorage from pg_class ;
 relstorage 
------------
 x
 v
 h
 c
(4 rows)

Time: 6.256 ms
analticdb=# 

2.2 名词解释

timing 打开SQL的执行时间

h = 堆表(heap)、索引

a = append only row存储表

c = append only column存储表

x = 外部表(external table)

v = 视图

3.AO表分析

3.1 查看当前数据库中有哪些AO表

analticdb=# select t2.nspname, t1.relname from pg_class t1, pg_namespace t2 where t1.relnamespace=t2.oid and relstorage in ('c', 'a');
 nspname |         relname         
---------+-------------------------
 public  | dwm_order_goods_sales_c
 public  | dwm_order_c
(2 rows)

Time: 7.748 ms

可以看出来 dwm_order_goods_sales_cdwm_order_c为AO表

3.2 查看AO表的膨胀率

表的膨胀率也就是表中执行DELETEUPDATE产生的垃圾

3.2.1 执行查看命令

analticdb=# select * from gp_toolkit.__gp_aovisimap_compaction_info('public.dwm_order_c2'::regclass);
NOTICE:  gp_appendonly_compaction_threshold = 10
 content | datafile | compaction_possible | hidden_tupcount | total_tupcount | percent_hidden 
---------+----------+---------------------+-----------------+----------------+----------------
       2 |        2 | f                   |               0 |              0 |           0.00
       3 |        1 | t                   |               3 |              8 |          37.50
       3 |        2 | t                   |               5 |              7 |          71.43
       0 |        2 | f                   |               0 |              0 |           0.00
       1 |        2 | f                   |               0 |              0 |           0.00
(5 rows)

3.2.2 名词解释

public: schema的名字

dwm_order_c2:当前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值判断)。

在以上中可以看出在3节点上的第1号文件有8记录其中有3条记录被更新或删除,其中不可见的比例为37.50%

3.3 检查系统中膨胀率超过N的AO表

3.3.1 执行命令

analticdb=# 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;
NOTICE:  gp_appendonly_compaction_threshold = 10
 nspname |   relname    | content | datafile | compaction_possible | hidden_tupcount | total_tupcount | percent_hidden 
---------+--------------+---------+----------+---------------------+-----------------+----------------+----------------
 public  | dwm_order_c2 |       0 |        2 | t                   |               3 |              8 |          37.50
 public  | dwm_order_c2 |       1 |        2 | t                   |               5 |              7 |          71.43
(2 rows)

Time: 24.654 ms

以上命令是查询膨胀率超过千分之2的AO表

3.3.2 名词解释

nspname: 表示查询的schema的名字

relname: 是当前schema的表的名字

在以上数据中可以看出在每个节点上的膨胀率也不同

3.4 查看膨胀数据的占用大小

analticdb=# select pg_size_pretty(pg_relation_size('public.dwm_order_c2'));
 pg_size_pretty 
----------------
 31 kB
(1 row)

Time: 1.923 ms

在以上可以看出膨胀率占用了31KB的空间

3.5 查看表的行数

analticdb=# select count(*) from public.dwm_order_c2;
 count 
-------
     7
(1 row)

Time: 9.726 ms

3.6 释放膨胀的空间

在以上的数据中可以看出膨胀率大于了gp_appendonly_compaction_threshold的值可以直接使用vacuum命令进行收缩

analticdb=# vacuum public.dwm_order_c2;
VACUUM
Time: 127.505 ms

3.7 查看释放后的占用空间

3.7.1 释放膨胀空间

analticdb=# select pg_size_pretty(pg_relation_size('public.dwm_order_c2'));
 pg_size_pretty 
----------------
 7984 bytes
(1 row)

Time: 1.434 ms

以上可以看出已经释放了大部分的空间

3.7.2 再次查看AO的膨胀率

analticdb=# 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;
NOTICE:  gp_appendonly_compaction_threshold = 10
NOTICE:  gp_appendonly_compaction_threshold = 10
NOTICE:  gp_appendonly_compaction_threshold = 10
NOTICE:  gp_appendonly_compaction_threshold = 10
NOTICE:  gp_appendonly_compaction_threshold = 10
NOTICE:  gp_appendonly_compaction_threshold = 10
NOTICE:  gp_appendonly_compaction_threshold = 10
NOTICE:  gp_appendonly_compaction_threshold = 10
NOTICE:  gp_appendonly_compaction_threshold = 10
NOTICE:  gp_appendonly_compaction_threshold = 10
NOTICE:  gp_appendonly_compaction_threshold = 10
NOTICE:  gp_appendonly_compaction_threshold = 10
NOTICE:  gp_appendonly_compaction_threshold = 10
NOTICE:  gp_appendonly_compaction_threshold = 10
NOTICE:  gp_appendonly_compaction_threshold = 10
NOTICE:  gp_appendonly_compaction_threshold = 10
NOTICE:  gp_appendonly_compaction_threshold = 10
NOTICE:  gp_appendonly_compaction_threshold = 10
 nspname | relname | content | datafile | compaction_possible | hidden_tupcount | total_tupcount | percent_hidden 
---------+---------+---------+----------+---------------------+-----------------+----------------+----------------
(0 rows)

Time: 22.552 ms

以上命令是查询膨胀率超过万分之1的AO表

3.8 再次查看表的行数

analticdb=# select count(*) from public.dwm_order_c2;
 count 
-------
     7
(1 row)

Time: 8.169 ms

从以上可以看出与第一次查询出来的行数一致。

3.9 使用更改随机的方式释放空间

3.9.1 查看膨胀占用空间

analticdb=# 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;
NOTICE:  gp_appendonly_compaction_threshold = 10
 nspname |   relname    | content | datafile | compaction_possible | hidden_tupcount | total_tupcount | percent_hidden 
---------+--------------+---------+----------+---------------------+-----------------+----------------+----------------
 public  | dwm_order_c2 |       2 |        4 | f                   |               5 |              0 |         100.00
 public  | dwm_order_c2 |       3 |        2 | f                   |               2 |              7 |         100.00
(2 rows)

Time: 22.410 ms

3.9.2 随机改变表的分布键

analticdb=# alter table public.dwm_order_c2 set with (reorganize=true) distributed randomly;
ALTER TABLE
Time: 85.755 ms

3.9.3 查看释放后的空间

analticdb=# 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;
NOTICE:  gp_appendonly_compaction_threshold = 10
 nspname | relname | content | datafile | compaction_possible | hidden_tupcount | total_tupcount | percent_hidden 
---------+---------+---------+----------+---------------------+-----------------+----------------+----------------
(0 rows)

Time: 28.697 ms

注意在执行随机分布键是在非业务的时候执行,执行distribute会执行排它锁不,要堵塞业务。

3.10 使用多分布键的形式释放空间

3.10.1 执行重新分布命令

analticdb=# alter table public.dwm_order_c2 set with (reorganize=true) distributed by (id_d_w_d);
ALTER TABLE
Time: 69.174 ms

3.10.2 查看数据的膨胀率

analticdb=# 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;
NOTICE:  gp_appendonly_compaction_threshold = 10
 nspname | relname | content | datafile | compaction_possible | hidden_tupcount | total_tupcount | percent_hidden 
---------+---------+---------+----------+---------------------+-----------------+----------------+----------------
(0 rows)

Time: 18.763 ms

注意在执行随机分布键是在非业务的时候执行,执行distribute会执行排它锁不,要堵塞业务。

4. AO表总结

4.1 查看表的行的个数

select count(*) from public.dwm_order_c2; 

4.2 更新数据的行数与占用大小

4.2.1 更新数据

analticdb=# update public.dwm_order_c2 set order_type='2' where order_type='1';
UPDATE 7
Time: 41.978 ms

Greenplum 列存表(AO表)的膨胀和垃圾检查与空间收缩
https://www.gmtgo.com/478.html
作者
大帅
发布于
2022年12月8日
许可协议