pgcompacttable + 使用pg_repack实现在线vacuum + 安装pg_repack +pg_repack可能跟流复制有冲突,建议使用pgcompacttable

1. Postgresql通过数据多版本实现mvcc,删除数据并不会真正删除数据,

而是修改标识,更新是通过删除+插入的方式进行,所以在频繁更新的系统,数据膨胀是个头疼的问题,如果不进行处理,数据膨胀倍数可能达到十几倍。

 

2. repack的原理

原理其实和vacuum full是类似的,都是新建一个文件,然后将老文件数据拷贝过来,然后进行文件切换,
它不阻塞读写的秘诀就是新建文件和拷贝的过程是在线做的,在没有完成拷贝之前,原来的文件还是可以读写的,只有在切表那一瞬间可能会有影响。

 

原理: 新建一个一模一样的影子表,然后拷贝原表的数据,最后rename替换原表。 安装pg_repack:

参考:使用pg_repack 回收表体积 - 云+社区 - 腾讯云 (tencent.com)

 

 

参考:使用pg_repack实现在线vacuum - 云+社区 - 腾讯云 (tencent.com)

 

3. pgcompacttable

#!/bin/bash
###########################################################
#红牛数据维护pg_repack
#20210908 changed to repack all database
###########################################################
pg_repack_log=/home/pg_repack_log
# 处理日期
backup_date=`date  "+%Y-%m-%d"`
#存放路径
log_file=pg_repack_${backup_date}.txt
#开始时间
echo  `date` >${pg_repack_log}/${log_file}


for x in  $(/usr/pgsql-10/bin/psql -U postgres -h 127.0.0.1 -d zuhu_512990 -c "select datname from pg_database where datname not in ('postgres','template0','template1'); "    -A -t)

do
#         if  [ `/usr/pgsql-10/bin/psql -U postgres -h 127.0.0.1 -d ${x}  -c "select count(1) from pg_extension  where extname='pg_repack'; "  -A -t` == 1 ]
#        then
##避免错误可直接写死路径
echo  `date` >> ${pg_repack_log}/${log_file}
 /home/pgback/pgcompacttable/bin/pgcompacttable -U postgres -h 127.0.0.1 -d ${x} >> ${pg_repack_log}/${log_file} 2>&1
echo "pg_compatch ${x} success!!"  >> ${pg_repack_log}/${log_file}
echo  `date` >> ${pg_repack_log}/${log_file}
       # else
       #         create_ext=`psql -U postgres -h 127.0.0.1 -d ${d} << EOF
       #         create extension pg_repack;
#EOF`
#        fi

done

 4. pg_repack

#!/bin/bash
###########################################################
#红牛数据维护pg_repack
#可能存在处理偶数天的表完成时已跨天了,可能接着把奇数天的表也处理了。
#注意监控实际处理时长;
###########################################################
pg_repack_log=/home/pg_repack_log
# 处理日期
backup_date=`date  "+%Y-%m-%d"`
#存放路径
log_file=pg_repack_${backup_date}.txt
#开始时间
echo  `date` >${pg_repack_log}/${log_file}
 #取当前的具体日期,用来取模求余
ls_date=`date +%d`
 if [[ ${ls_date}%2 -eq 0 ]]
 then

# 偶数天处理核心表清单;
for x in  $(psql -U postgres -h 127.0.0.1 -d
zuhu_512110
-c "select relname from pg_class where relname in ( 'kx_test_store','kx_test_actual' ); " -A -t) do ##避免错误可直接写死路径 echo `date` >> ${pg_repack_log}/${log_file} ` /usr/pgsql-10/bin/pg_repack -Upostgres -h127.0.0.1 -d tenant_1008446 -t ${x} >> ${pg_repack_log}/${log_file} 2>&1 ` echo "pg_repack ${x} success!!" >> ${pg_repack_log}/${log_file} echo `date` >> ${pg_repack_log}/${log_file} done elif [[ ${ls_date}%2 -eq 1 ]]; then # 奇数天处理表清单; for x in $(psql -U postgres -h 127.0.0.1 -d tenant_1008446 -c "select relname from pg_class where relname NOT in ( 'do_test_store','do_test_actual' ) and relkind='r' and relpersistence='p' and relnamespace=2200; " -A -t) do ##2200 对应pg_namespace 的oid 为public ##避免错误可直接写死路径 echo `date` >> ${pg_repack_log}/${log_file} ` /usr/pgsql-10/bin/pg_repack -Upostgres -h127.0.0.1 -d zuhu_512110 -t ${x} >> ${pg_repack_log}/${log_file} 2>&1 ` echo "pg_repack ${x} success!!" >> ${pg_repack_log}/${log_file} echo `date` >> ${pg_repack_log}/${log_file} done else dd=`date` echo "***** ${dd} no shell need to run.*****" >> ${pg_repack_log}/${log_file} fi

 

posted @ 2021-08-06 11:09  littlevigra  阅读(283)  评论(1编辑  收藏  举报