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 空闲空间的百分比 ![](https://file.jishuzhan.net/article/1687716331794731009/d5b9948258cb44f68ef3bdceb1c63bf9.png) ![](https://file.jishuzhan.net/article/1687716331794731009/e397f081ad1742258be797f2537db16c.png) --查看表的大小 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 ![](https://file.jishuzhan.net/article/1687716331794731009/41ef4ccdd1144529b822e58cc30b359f.png) --查看压缩后的表 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) 恢复至源表大小。

相关推荐
广州智造1 小时前
OptiStruct实例:3D实体转子分析
数据库·人工智能·算法·机器学习·数学建模·3d·性能优化
技术宝哥4 小时前
Redis(2):Redis + Lua为什么可以实现原子性
数据库·redis·lua
学地理的小胖砸6 小时前
【Python 操作 MySQL 数据库】
数据库·python·mysql
dddaidai1236 小时前
Redis解析
数据库·redis·缓存
数据库幼崽6 小时前
MySQL 8.0 OCP 1Z0-908 121-130题
数据库·mysql·ocp
Amctwd7 小时前
【SQL】如何在 SQL 中统计结构化字符串的特征频率
数据库·sql
betazhou7 小时前
基于Linux环境实现Oracle goldengate远程抽取MySQL同步数据到MySQL
linux·数据库·mysql·oracle·ogg
lyrhhhhhhhh8 小时前
Spring 框架 JDBC 模板技术详解
java·数据库·spring
喝醉的小喵9 小时前
【mysql】并发 Insert 的死锁问题 第二弹
数据库·后端·mysql·死锁
付出不多9 小时前
Linux——mysql主从复制与读写分离
数据库·mysql