前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >PG使用插件pg_squeeze解决表和索引的膨胀问题

PG使用插件pg_squeeze解决表和索引的膨胀问题

作者头像
AiDBA宝典
发布2023-04-27 13:59:45
1.5K0
发布2023-04-27 13:59:45
举报
文章被收录于专栏:小麦苗的DB宝专栏

简介

PostgreSQL中大量更新或者删除记录后,加上autovacuum参数未做优化或设置不当,会导致表及索引膨胀。生产环境除了手动使用vacuum之外,还有两个比较常用的工具:一个是pg_repack,另外一个是pg_squeeze。

使用pg_repack或pg_squeeze对表做重组时,比vacuum full对系统的影响小,且性能更高。

安装pg_squeeze

GitHub:https://github.com/cybertec-postgresql/pg_squeeze

代码语言:javascript
复制
-- yum安装(PG源就有)
yum list pg_squeeze*
yum install -y  pg_squeeze_14


-- 编译安装
wget https://github.com/cybertec-postgresql/pg_squeeze/archive/refs/tags/REL1_5_0.tar.gz
tar -zxvf REL1_5_0.tar.gz
cd pg_squeeze-REL1_5_0/
make && make install

vi /var/lib/pgsql/14/data/postgresql.conf
wal_level = logical
max_replication_slots = 10
shared_preload_libraries = 'pg_squeeze'

pg_ctl restart


CREATE EXTENSION pg_squeeze;

过程:

代码语言:javascript
复制
postgres=# create extension pg_squeeze ;
CREATE EXTENSION
postgres=# set search_path to 'squeeze';
SET
postgres=# \dt
              List of relations
 Schema  |      Name       | Type  |  Owner   
---------+-----------------+-------+----------
 squeeze | errors          | table | postgres
 squeeze | log             | table | postgres
 squeeze | tables          | table | postgres
 squeeze | tables_internal | table | postgres
 squeeze | tasks           | table | postgres
(5 rows)

postgres=# \dn
  List of schemas
  Name   |  Owner   
---------+----------
 public  | postgres
 repack  | postgres
 squeeze | postgres
(3 rows)

pg_repack使用例子

对test数据库下的foo和bar表做在线vacuum full

代码语言:javascript
复制
$ pg_repack --no-order --table foo --table bar test

转移foo表的索引到tbs表空间

代码语言:javascript
复制
$ pg_repack -d test --table foo --only-indexes --tablespace tbs

pg_squeeze使用例子

以注册表方式crontab定期运行“squeeze挤压”

代码语言:javascript
复制
INSERT INTO squeeze.tables (tabschema, tabname, schedule)
VALUES ('public', 'foo', ('{30}', '{22}', NULL, NULL, '{3, 5}'));

手工对public模式下的pgbench_accounts表“squeeze挤压”

代码语言:javascript
复制
SELECT squeeze.squeeze_table('public', 'pgbench_accounts', null, null, null);

pg_squeeze测试

创建测试表

代码语言:javascript
复制
create table public.test(id int primary key);
insert into public.test select generate_series(1,2000000);

查看表的大小

代码语言:javascript
复制
postgres=# SELECT pg_size_pretty(pg_total_relation_size('test'));
 pg_size_pretty 
----------------
 112 MB
(1 row)

postgres=# 

向squeeze.tables插入一条数据,定期清理test表,每天的0点、2点、6点的10、30和50分别执行1次,空闲空间超过10%就会对表进行重建.

代码语言:javascript
复制
postgres=# insert into squeeze.tables (tabschema, tabname, schedule, free_space_extra) values ('public', 'test', ('{10,30,50}', '{00,02,06}', NULL, NULL, NULL), '10');
INSERT 0 1
postgres=# select * from squeeze.tables;
 id | tabschema | tabname | clustering_index | rel_tablespace | ind_tablespaces | free_space_extra | min_size | vacuum_max_age | max_retry | skip_analyze |        schedule        
----+-----------+---------+------------------+----------------+-----------------+------------------+----------+----------------+-----------+--------------+------------------------
  1 | public    | test    |                  |                |                 |               10 |        8 | 01:00:00       |         0 | f            | ("{0,59}","{0,23}",,,)
(1 row)

postgres=# 


-- schedule的几个列表示:分钟、小时、天、月、周

“minutes”(0到59)和“hours”(0到23)指定了一天内检查的时间,而“days_of_month”(1到31)、“months”(1到12)和“days_of_week”(0到7,其中0和7都代表星期日)确定了检查的日期。 如果“minute”、“hour”和“month”都与当前时间戳匹配,则进行检查,而NULL值分别表示任何分钟、小时和月份。 至于“days_of_month”和“days_of_week”,至少有一个需要与当前时间戳匹配,或者两者都为NULL才会进行检查。

启动pg_squeeze的进程需要调用

代码语言:javascript
复制
SELECT squeeze.start_worker();

关闭命令:SELECT squeeze.stop_worker();

查看当前表的膨胀情况

代码语言:javascript
复制
postgres=# select * from squeeze.tables_internal;
 table_id | last_task_finished 
----------+--------------------
        1 | 
(1 row)

删除test表数据:

代码语言:javascript
复制
postgres=# SELECT pg_size_pretty(pg_total_relation_size('test'));
 pg_size_pretty 
----------------
 112 MB
(1 row)

postgres=# delete from test where id < 800000;
DELETE 799999
postgres=# SELECT pg_size_pretty(pg_total_relation_size('test'));
 pg_size_pretty 
----------------
 112 MB
(1 row)

再次查看表的膨胀情况

代码语言:javascript
复制
select * from squeeze.tables_internal;

pg_repack与pg_squeeze对比

1.支持的PostgreSQL版本

pg_repack 1.4.5 PostgreSQL >= 9.1

pg_repack 1.4.6 PostgreSQL >= 9.4

pg_squeeze PostgreSQL >= 9.4

2.重组表的方式

pg_repack 基于触发器方式实现,对被重组的表,有一定的DML性能影响。

pg_squeeze 基于逻辑复制槽实现,重组时对原表的DML几乎没有性能影响,可能有复制槽争用,注意设置复制槽参数。

3.其它

pg_repack和pg_squeeze都需要表有主键或者非空唯一约束。

pg_squeeze目前支持的功能比pg_repack更灵活些,除了可手工或自动处理,也可以设置参数降低对后端进程的影响。

pg_squeeze当前版本1.3.1测试发现pg_show_plans不能同时使用。

参考

https://www.cnblogs.com/hxlasky/p/16951464.html

https://pgfans.cn/a/1174

https://www.xmmup.com/pgshiyongchajianpg_repackjiejuebiaohesuoyindepengzhangwenti.html

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-04-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 DB宝 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 简介
  • 安装pg_squeeze
  • pg_repack使用例子
  • pg_squeeze使用例子
  • pg_squeeze测试
  • pg_repack与pg_squeeze对比
    • 1.支持的PostgreSQL版本
      • 2.重组表的方式
        • 3.其它
        • 参考
        相关产品与服务
        腾讯云服务器利旧
        云服务器(Cloud Virtual Machine,CVM)提供安全可靠的弹性计算服务。 您可以实时扩展或缩减计算资源,适应变化的业务需求,并只需按实际使用的资源计费。使用 CVM 可以极大降低您的软硬件采购成本,简化 IT 运维工作。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档