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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xfg0218/article/details/83031550

Greenplum释放表的空间

 

Greenplum释放表的空间 1

1 Greenplum产生垃圾空间说明 2

2 查看表的储存类型 2

2.1 执行查看命令 2

2.2 名词解释 3

3 AO表分析 3

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

3.1.1 查看当前数据库的所有AO表 3

3.1.2 查看制定schema下的AO表 3

3.2 查看AO表的膨胀率 4

扫描二维码关注公众号,回复: 3669476 查看本文章

3.2.1 执行查看命令 4

3.2.3 名词解释 4

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

3.3.1 执行命令 5

3.3.2 名词解释 5

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

3.5 查看表的行数 6

3.6 释放膨胀的空间 6

3.7 查看释放后的占用空间 6

3.7.1 释放膨胀空间 6

3.7.2 再次查看AO的膨胀率 7

3.8 再次查看表的行数 7

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

3.9.1 查看膨胀占用空间 7

3.9.2 随机改变表的分布键 8

3.9.3 查看释放后的空间 8

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

3.10.1 执行重新分布命令 8

3.10.2 查看数据的膨胀率 8

4 AO表总结 9

4.1 查看表的行的个数 9

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

4.2.1 更新数据 9

4.2.2 查看表的膨胀率 9

5 AO表释放空间SHELL脚本 10

 

 

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锁,慎用这个命令,会把CPU与IO沾满。

3、执行重分布。(不管gp_appendonly_compaction_threshold参数,都会回收垃圾空间。),为DDL锁。

2 查看表的储存类型

 

2.1 执行查看命令

stagging=# \timing

Timing is on.

 

stagging=# select distinct relstorage from pg_class ;

 relstorage

------------

 h

 a

 x

 v

 c

(5 rows)

 

Time: 6.132 ms

2.2 名词解释

timing 打开SQL的执行时间

h = 堆表(heap)、索引

a = append only row存储表  

c = append only column存储表  

x = 外部表(external table)  

v = 视图

3 AO表分析

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

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表

3.2 查看AO表的膨胀率

表的膨胀率也就是表中执行DELETE和UPDATE产生的垃圾

3.2.1 执行查看命令

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

3.2.3 名词解释

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%

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

3.3.1 执行命令

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表

3.3.2 名词解释

nspname: 表示查询的schema的名字

relname: 是当前schema的表的名字

 

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

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

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的空间

3.5 查看表的行数

stagging=# select count(*) from test_ao.ao_table_test;

   count   

-----------

 140324396

(1 row)

 

Time: 1842.706 ms

3.6 释放膨胀的空间

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

 

stagging=# vacuum test_ao.ao_table_test;

VACUUM

Time: 57800.144 ms

3.7 查看释放后的占用空间

3.7.1 释放膨胀空间

stagging=# select pg_size_pretty(pg_relation_size('test_ao.ao_table_test'));

 pg_size_pretty

----------------

 8859 MB

(1 row)

 

Time: 34.990 ms

 

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

3.7.2 再次查看AO的膨胀率

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表

3.8 再次查看表的行数

stagging=# select count(*) from test_ao.ao_table_test;

   count   

-----------

 140324396

(1 row)

 

Time: 1680.919 ms

 

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

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

3.9.1 查看膨胀占用空间

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;

 

3.9.2 随机改变表的分布键

stagging=# alter table test_ao.ao_table_test  set with (reorganize=true) distributed randomly;

ALTER TABLE

Time: 81169.170 ms

3.9.3 查看释放后的空间

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会执行排它锁不,要堵塞业务。

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

3.10.1 执行重新分布命令

stagging=# alter table test_ao.ao_table_test set with (reorganize=true) distributed by (pripid,s_ext_nodenum);

ALTER TABLE

Time: 82621.274 ms

3.10.2 查看数据的膨胀率

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会执行排它锁不,要堵塞业务。

4 AO表总结

4.1 查看表的行的个数

stagging=# select count(*) from test_ao.ao_table_test;                                                                                                                             

   count   

-----------

 140324396

(1 row)

 

Time: 1764.584 ms

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

4.2.1 更新数据

stagging=# update test_ao.ao_table_test  set alttime='2018-10-23 11:54:57.000000' where nodenum='850000';

 

受影响的行: 5701,7349

时间: 104.007s

4.2.2 查看表的膨胀率

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左右。

5 AO表释放空间SHELL脚本

下载地址: https://download.csdn.net/download/xfg0218/10726255

$ cat   greenplum-inspect-ao.sh

#!bin/bash

# 1、把改脚本放到任意目录下

# 2、inspect-ao-sql文件夹存放的是查询AO表的SQL与查询膨胀率的SQL

# 3、log文件夹则是存放临时生成的schema与table的文件,还有存放每个AO表的膨胀率详细的信息

# 4、释放空间使用的是vacuum schema.tablename

 

 

#当前该脚本的路径

bashpath=$(cd `dirname $0`;pwd)

 

# 执行查看AO表的SQL脚本

inspect_ao_sql_ori=$bashpath"/inspect-ao-sql/inspect-ao-ori.sql"

inspect_ao_sql=$bashpath"/inspect-ao-sql/inspect-ao.sql"

 

# 查看表膨胀率的SQL脚本

inspect_ao_expansivity_ori=$bashpath"/inspect-ao-sql/inspect-ao-percent-hidden-ori.sql"

inspect_ao_expansivity=$bashpath"/inspect-ao-sql/inspect-ao-percent-hidden.sql"

 

# 所产生的日志路径

inspect_ao_log=$bashpath"/log"

 

#当前的日期

currentDate=`date +%Y%m%d`

 

#创建生成结果的临时目录

temp_inspect_results=$inspect_ao_log"/"$currentDate"/temp-inspect-results"

 

# 查看表膨胀率的详细信息

table_percent_hidden=$inspect_ao_log"/"$currentDate"/table-percent-hidden"

 

# 数据库名字

gpdatabase='****'

 

# scheam 名字

scheamname='main'

 

# gp服务器ip

gpip='192.168.***.11'

 

#gp port

gpport='5432'

 

# gp user

gpuser='gpadmin'

 

# gp password

gppassword='gpadmin'

 

# 需要检查的schema

schema_inspect='main,ods'

 

# 删除日志文件并创建新文件

if [ -d $inspect_ao_log ];then

     rm -rf $inspect_ao_log

  fi

 

mkdir -p  $temp_inspect_results

mkdir -p  $table_percent_hidden

 

# 导入GP密码环境标量

export PGPASSWORD=$gppassword

 

# 获取数据并处理为需要的格式

array=(${schema_inspect//,/ })

for schema_var in ${array[@]}

do

   cp $inspect_ao_sql_ori $inspect_ao_sql

   sed -i 's/schemaName/'$schema_var'/g' $inspect_ao_sql

 

   export PGPASSWORD=$gppassword

   psql -d $gpdatabase  -h $gpip -p $gpport -U $gpuser -f  $inspect_ao_sql >> $temp_inspect_results/$currentDate-$schema_var".txt"   

   

   sed -i '1,2d' $temp_inspect_results/$currentDate-$schema_var".txt"

   sed -i '$d' $temp_inspect_results/$currentDate-$schema_var".txt"

   sed -i '$d' $temp_inspect_results/$currentDate-$schema_var".txt"

 

   cat $temp_inspect_results/$currentDate-$schema_var".txt" |awk -F '|' '{print $1,$2}'|awk -F '\t' '{print $1"."$2}' >> $temp_inspect_results/$currentDate"-tra.txt"

   

   if [ -f $inspect_ao_sql ];then

     rm -rf $inspect_ao_sql

  fi

done

 

# 生成带有schema与AO表的文件

cat $temp_inspect_results/$currentDate"-tra.txt"|awk '{print $1"."$2}'|awk '{sub(/.$/,"")}1' >> $temp_inspect_results/$currentDate"-finish.txt"

 

# 遍历带有schema与表名的文件

for schema_tablename in `cat $temp_inspect_results/$currentDate"-finish.txt"`

do

  echo $schema_tablename

  cp $inspect_ao_expansivity_ori $inspect_ao_expansivity

  sed -i 's/tablepath/'$schema_tablename'/g' $inspect_ao_expansivity

  

  export PGPASSWORD=$gppassword

  psql -d $gpdatabase  -h $gpip -p $gpport -U $gpuser -f  $inspect_ao_expansivity  >> $table_percent_hidden"/"$schema_tablename".txt";

  psql -d $gpdatabase  -h $gpip -p $gpport -U $gpuser -c "vacuum $schema_tablename";

  

  if [ -f $inspect_ao_expansivity ];then

     rm -rf $inspect_ao_expansivity

  fi

done

# 正确退出脚本

exit 0

 

猜你喜欢

转载自blog.csdn.net/xfg0218/article/details/83031550