postgresql表膨胀处理之pgcompacttable部署及使用

环境:

1)redhat-release:CentOS Linux release 7.6.1810 (Core)

2)database version:postgresql 14.6

一、添加pgstattuple

pgcompacttable工具使用过程中需要依赖pgstattuple,因此需先添加pgstattuple。如果是源码安装的postgresql,则源码里包含了postgresql-contrib,因此,进行编译及安装即可。

--编译

cd /postgresql/soft/postgresql-14.6/contrib/pgstattuple

make

make install

本次实验没有编译也可以直接使用。

--在所需要使用的数据库里添加pgstattuple。

postgres@tencent \~$ psql -d testdb -Utest

psql (14.6)

Type "help" for help.

testdb=# select * from pg_available_extensions where name like 'pgstat%';

name | default_version | installed_version | comment

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

pgstattuple | 1.5 | | show tuple-level statistics

(1 row)

testdb=#create extension pgstattuple;

CREATE EXTENSION

testdb=# select * from pg_available_extensions where name like 'pgstat%';

name | default_version | installed_version | comment

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

pgstattuple | 1.5 | 1.5 | show tuple-level statistics

(1 row)

安装完成后,installed_version显示安装的版本

--查看pgstattuple可使用的函数

testdb=# \dxS+ pgstattuple

Objects in extension "pgstattuple"

Object description


function pg_relpages(regclass)

function pg_relpages(text)

function pgstatginindex(regclass)

function pgstathashindex(regclass)

function pgstatindex(regclass)

function pgstatindex(text)

function pgstattuple_approx(regclass)

function pgstattuple(regclass)

function pgstattuple(text)

(9 rows)

二、部署pgcompacttable

安装前需要安装pgstattuple插件,因为要基于该插件去查找膨胀的表,所以如果有大表的情况下,因为pgstattuple会扫全表,所以会比较耗时,这个在使用的时候一定要注意一下。

原理:

从表的头部填充新的行,在普通vacuum时候,截断表末尾的空page,达到收缩空间的效果。不需要占用额外的空间,使得表文件更加紧凑。而且不会加比较重的锁。对性能影响较小。

--安装依赖包

root@tencent \~# yum install perl-Time-HiRes perl-DBI perl-DBD-Pg --y

--上传解压安装包

上传pgcompacttable-master.zip 到/postgresql/soft目录,unzippgcompacttable-master.zip

--查看文件

postgres@tencent soft$ cd pgcompacttable-master/

postgres@tencent pgcompacttable-master$ ls

bin README.md

postgres@tencent pgcompacttable-master$ cd bin

postgres@tencent bin$ ls

Pgcompacttable

三、准备测试环境

3.1 创建表

--创建表

testdb=#create table test (id in,sex char(2),name varchar(10),now_address text,address text);

--插入数据

testdb=# insert into test values(generate_series(1,10000),repeat(chr(int4(random()*26)+65),1),repeat(chr(int4(random()*26)+65),6),repeat(chr(int4(random()*26)+65),30),repeat(chr(int4(random()*26)+65),30));

INSERT 0 10000

--创建索引

testdb=# create index on test(id,sex);

CREATE INDEX

testdb=# create index on test(name,now_address,address);

CREATE INDEX

--查看表大小

testdb=# select pg_size_pretty(pg_relation_size('test'));

pg_size_pretty


1072 kB

(1 row)

testdb=# select count(*) from test;

count


10000

(1 row)

3.2 模拟修改数据

创建脚本:

postgres@tencent scripts$ vi test_mod.sh

#!/bin/bash

#version: 1.0

#function: bulk update data

for((i=1;i<=10000;i++));

do

a=`tr -dc A-Z[ < /dev/urandom | head -c1`

psql -Utest -h 127.0.0.1 -d testdb -c "update test set name=repeat( chr(int4(random()*26)+65),6),now_address=repeat( chr(int4(random()*26)+65),30),address=repeat( chr(int4(random()*26)+65),30) where sex='$a';" >>/dev/null

if $? == 0

then

echo "$a is ok" >>update.log

else

echo "$a is close" >>update.err.log

exit 1;

fi

done

3.3 膨胀再现

为了执行脚本不输入密码,创建了.pgpass文件

--查看postgres家目录

postgres@tencent bin$ grep postgres /etc/passwd

postgres:x:601:601::/home/postgres:/bin/bash

--创建.pgpass

touch /home/postgres/.pgpass

chown postgres. /home/postgres/.pgpass

chmod 600 /home/postgres/.pgpass

--配置.pgpass

postgres@tencent \~$ echo "127.0.0.1:4519:testdb:test:test" >>./.pgpass

--连接测试

postgres@tencent \~$ psql -h 127.0.0.1 -d testdb -Utest

psql (14.6)

Type "help" for help.

testdb=#

连接成功。

--执行批量修改脚本

postgres@tencent scripts$ sh test_mod.sh

--查看元组的统计信息

testdb=# SELECT * FROM pgstattuple('test');

table_len | tuple_count | tuple_len | tuple_percent | dead_tuple_count | dead_tuple_len | dead_tuple_percent | free_space | free_percent

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

27795456 | 10258 | 1025800 | 3.69 | 19617 | 1961700 | 7.06 | 24071216 | 86.6

(1 row)

pgstattuple 输出列如下:

字段 类型 描述

table_len bigint 物理关系长度,以字节计

tuple_count bigint 活的元组的数量

tuple_len bigint 活的元组的总长度,以字节计

tuple_percent float8 活的元组的百分比

dead_tuple_count bigint 死的元组的数量

dead_tuple_len bigint 死的元组的总长度,以字节计

dead_tuple_percent float8 死的元组的百分比

free_space bigint 空闲空间总量,以字节计

free_percent float8 空闲空间的百分比

--查看表的大小

testdb=# select pg_size_pretty(pg_relation_size('test'));

pg_size_pretty


27 MB

(1 row)

存1w条数据原表大小1096 KB,目前27MB

四、pgcompacttable使用

pgcompacttable可以对database级别、schema级别、table级别进行压缩

./pgcompacttable -h localhost -U postgres -d testdb

./pgcompacttable -h localhost -U postgres -d testdb -n test

./pgcompacttable -h localhost -U postgres -d testdb -n test -t test

postgres@tencent bin$ ./pgcompacttable -h 127.0.0.1 -U test -d testdb

--查看压缩后的表

testdb=# SELECT * FROM pgstattuple('test');

table_len | tuple_count | tuple_len | tuple_percent | dead_tuple_count | dead_tuple_len | dead_tuple_percent | free_space | free_percent

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

1114112 | 10000 | 1000000 | 89.76 | 0 | 0 | 0 | 12456 | 1.12

(1 row)

testdb=# select pg_size_pretty(pg_relation_size('test'));

pg_size_pretty


1088 kB

(1 row)

恢复至源表大小。

相关推荐
朝阳5815 分钟前
MySQL 主从复制 — 双服务器灾备方案(原生安装)
服务器·数据库·mysql
是狐狸吖6 分钟前
Redis分布式锁进阶第十六篇
数据库·redis·分布式
闪电悠米7 分钟前
黑马点评-优惠券秒杀-04_one_user_one_order
服务器·网络·数据库
YL200404267 分钟前
【Redis实战篇】基于Redis的分布式锁的原理及实现
数据库·redis·缓存
兔子宇航员03019 分钟前
HiveSQL 中 NULL 与空字符串的区别与注意事项
数据库·数据仓库·sql
杨云龙UP16 分钟前
Oracle CDB巡检脚本使用SOP:从HTML原始报告到Word正式交付_2026-05-29
运维·服务器·数据库·oracle·架构·html·巡检
保定公民17 分钟前
Oracle 层次查询(CONNECT BY)完全指南:从入门到精通
数据库·sql·oracle·达梦数据库·层次查询
闪电悠米24 分钟前
黑马点评-优惠券秒杀-03_basic_seckill_and_oversell
java·数据库·spring boot·spring·缓存·oracle·面试
逍遥德26 分钟前
PostgreSQL --- 数组函数详解
数据库·sql·postgresql
.Cnn26 分钟前
MySQL事务和Spring事务
数据库·后端·mysql·spring