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

相关推荐
XiaoLeisj28 分钟前
【MyBatis】深入解析 MyBatis XML 开发:增删改查操作和方法命名规范、@Param 重命名参数、XML 返回自增主键方法
xml·java·数据库·spring boot·sql·intellij-idea·mybatis
dleei1 小时前
MySql安装及SQL语句
数据库·后端·mysql
信徒_2 小时前
Mysql 在什么样的情况下会产生死锁?
android·数据库·mysql
嘴对嘴编程3 小时前
oracle数据泵操作
数据库·oracle
豆芽脚脚6 小时前
合并相同 patient_id 的 JSON 数据为数组
postgresql·json
·薯条大王9 小时前
MySQL联合查询
数据库·mysql
morris13110 小时前
【redis】redis实现分布式锁
数据库·redis·缓存·分布式锁
hycccccch11 小时前
Canal+RabbitMQ实现MySQL数据增量同步
java·数据库·后端·rabbitmq
这个懒人12 小时前
深入解析Translog机制:Elasticsearch的数据守护者
数据库·elasticsearch·nosql·translog
Yan-英杰12 小时前
【百日精通JAVA | SQL篇 | 第二篇】数据库操作
服务器·数据库·sql