PostgreSQL将普通表转换为分区表插件之pg_rewrite

分区的原因

说到分区,我们首先想到的是表为啥要分区,分区有什么好处?

当前版本并不能对单表或者单个分区并行进行垃圾回收,包括单表的freeze也只能是单进程进行冻结和回收。但是对于多表或者多个分区就可以并行执行上述操作,所以在单表数据量过大会发生什么?

  • 1. 当进行autovacuum垃圾回收时,如果该表的DML操作非常频繁的话,可能导致垃圾回收不过来,进而导致表迅速膨胀,占用过多的空间从而导致故障。

  • 2. 单表过大会导致单表的freeze时间过长,可能会导致xid耗尽,此时就只能停库操作降低年龄之后才能正常运行。在PG 9.6以前的版本,大表的freeze带来的IOPS影响较大,体现在数据文件读写、WAL日志大量产生。但9.6及以后版本freeze有大幅改进,并不会产生大量的WAL日志了。

  • 3. 表没分区的话,当要清理历史数据时就只能delete了,大批量的delete会产生大量的wal日志,从而导致从库延迟。并且大批量数据的delete事务时间过长,可能会导致表膨胀发生。如果大表分区了,我们可以通过drop历史分区或者truncate历史分区的方式清理历史数据,不用担心大量wal日志的产生,而且执行时间很快。

  • 4. 单表的只能位于单个表空间,对应到单个目录,并不能像分区表那样将各个分区放到不同的表空间,不同的目录上去。这样就可能致某个目录对应的盘IO很繁忙,但其他目录就很空闲的情况。IO不能分散从而导致性能问题的发生

单表的逻辑备份恢复无法并行执行,数据全量同步时会很慢,并且异常中断后又需要重新开始这个大表的同步。

当然,pg_rewrite使用是有限制的:

  • 不支持外部表分区。

  • 非分区表一定要有PK。

  • 分区表建议约束和非分区表保持一致, 例如not null,default value 等约束。

pg_rewrite安装及使用

pg_rewrite是开源的,需要pg 13或更高版本才能安装。

下载路径如下:

https://github.com/cybertec-postgresql/pg_rewrite

1. 设置PG_CONFIG环境变量,安装时,我们必须确保路径中的pg_config 版本正确。

2. 编译安装:

3. 修改postgresql.conf 参数文件并重启生效。

wal_level = logical
max_replication_slots = 1             #或者在当前值上加1。
shared_preload_libraries = 'pg_rewrite'    #将pg_rewrite添加到现有库中

4. 使用超级用户创建扩展 pg_rewrite,目前该扩展只包含一个函数partition_table()。它可以将非分区表转换为分区表。

pg_rewrite用法测试案例

1. 创建普通表及结构相同的分区表

2. 普通表插入测试数据

3. 运行 partition_table() 函数将普通表的数据复制至分区表,并将普通表的表名修改成自定义表名用于备份。并将分表区的表名修改成与原普通表一致的表名。

pg_rewrite相关的变量

1. rewrite.check_constraints

在开始复制数据之前,它会检查目标表是否与源表具有相同的约束,如果发现差异则抛出错误。如果目标表上缺少约束,一旦处理完成,违反源表约束的数据将被允许出现在目标表中。甚至对目标表的额外约束也是一个问题,因为扩展只假设它复制的所有数据确实满足源表上的约束,但是它不会根据目标表上的额外约束来验证它们。

默认值是true,通过将 rewrite.check_constraints 设置为 false,用户可以关闭约束检查。但是不建议这么做,最好是提前检查目标表与源表的结构是否一致。

2. rewrite.max_xlock_time

尽管大多数时候正在处理的表可用于其他事务的读写操作,但需要排他锁来完成处理。如果过多地阻止对表的访问,请考虑设置“rewrite.max_xlock_time”参数。

例如:

set rewrite.max_xlock_time to 100;

表示排他锁的持有时间不应超过 0.1 秒(100 毫秒)。如果最后阶段需要更多时间,则特定函数会释放排他锁,处理中间其他事务提交的更改并再次尝试最后阶段。多次超过锁定时间会报错。如果发生这种情况,您应该增加设置或稍后在写入活动较低时尝试处理有问题的表。

默认值为 0,这意味着最后阶段可以根据需要花费尽可能多的时间。

备注:pg_rewrite 在执行全量过程中也是锁表的。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值