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) 恢复至源表大小。

相关推荐
辞砚技术录19 小时前
MySQL面试题——索引2nd
数据库·mysql·面试
linweidong19 小时前
C++thread pool(线程池)设计应关注哪些扩展性问题?
java·数据库·c++
欧亚学术20 小时前
突发!刚刚新增17本期刊被剔除!
数据库·论文·sci·期刊·博士·scopus·发表
黑白极客20 小时前
怎么给字符串字段加索引?日志系统 一条更新语句是怎么执行的
java·数据库·sql·mysql·引擎
大厂技术总监下海20 小时前
数据湖加速、实时数仓、统一查询层:Apache Doris 如何成为现代数据架构的“高性能中枢”?
大数据·数据库·算法·apache
LeenixP21 小时前
RK3576-Debian12删除userdata分区
linux·运维·服务器·数据库·debian·开发板
a努力。21 小时前
国家电网Java面试被问:最小生成树的Kruskal和Prim算法
java·后端·算法·postgresql·面试·linq
知行合一。。。21 小时前
Python--03--函数入门
android·数据库·python
X***078821 小时前
理解 MySQL 的索引设计逻辑:从数据结构到实际查询性能的系统分析
数据库·mysql·sqlite
爬山算法21 小时前
Hibernate(31)Hibernate的原生SQL查询是什么?
数据库·sql·hibernate