PostgreSQL普通表转换成分区表

本文涉及的产品
云原生数据库 PolarDB MySQL 版,通用型 2核4GB 50GB
云原生数据库 PolarDB PostgreSQL 版,标准版 2核4GB 50GB
简介: 如何使用pg_rewrite扩展将普遍表转换成分区表

pg_rewrite扩展是CyberTec公司开发的PostgreSQL扩展,可以很方便的在线将普通表转换成分区表。

一、安装配置

pg_rewrite只支持PostgreSQL 13及以上版本

git clone https://github.com/cybertec-postgresql/pg_rewrite.git
cd pg_rewrite
makemake install
#修改配置文件wal_level = logical
#因为是在线转换,所以如果在转换过程中源表的数据发生变化,pg_rewrite通过逻辑复制获取变化数据#因此需要复制槽max_replication_slots =1#需要预加载,但我在使用中发现不加入预加载项中也能正常使用shared_preload_libraries ='pg_rewrite'#安装配置完成后需要重启数据库。然后以超级用户身份创建扩展create extension pg_rewrite;

二、使用方法举例

假设普通表定义了如下:

CREATETABLE measurement (    id              serial,    city_id         intnotnull,    logdate         datenotnull,    peaktemp        int,    unitsales       int,    PRIMARY KEY(id, logdate)-- pg分区的要求,分区字段必须是主键或者唯一索引的一部分);

现在需要将上表转换成分区表,先创建分区表,pg_rewrite要求分区表跟普通表必须一模一样,包括字段、约束、索引......

CREATETABLE measurement_aux (    id              serial,    city_id         intnotnull,    logdate         datenotnull,    peaktemp        int,    unitsales       int,    PRIMARY KEY(id, logdate)) PARTITION BY RANGE (logdate);

接下来创建分区(本例创建range分区)

CREATETABLE measurement_y2006m02 PARTITION OF measurement_aux
    FOR VALUESFROM('2006-02-01') TO ('2006-03-01');CREATETABLE measurement_y2006m03 PARTITION OF measurement_aux
    FOR VALUESFROM('2006-03-01') TO ('2006-04-01');-- ...

使用pg_rewrite的partition_table函数转换分区,总共三个参数,参数一是源表、参数二是目的表,参数三指定转换完成后源表的新表名。

SELECT partition_table('measurement','measurement_aux','measurement_old');

执行些函数将数据从measurement(源表)复制到measurement_aux(目的表),然后它将以独占方式锁定measurement表,然后执行如下操作:

(1)将measurement重命名为measurement_old;

(2)将measurement_aux重命名为measurement

转换完成后,measurement最终是分区表,而measurement_old是原来未分区的表。

三、过程监控

如果 partition_table() 需要很长时间才能完成,此间你可能想了解转换进度。pg_rewrite提供了pg_rewrite_progress视图。src_tablesrc_tablesrc_table_new 列包含partition_table() 函数的参数。ins_initial 是在“初始加载阶段”插入到新表中的元组的数量,即在处理开始之前存在于表中的元组的数量。另一方面, ins, upddel 是在表转换过程中插入、更新和删除的元组的数量。这些“转换中发生的数据变更”也必须合并到分区表中,否则它们会丢失。

四、限制

  • 不支持外表;
  • 被转换的表不能有外键;

五、参数

以下是对影响此扩展的函数行为的配置变量的说明。


rewrite.check_constraints

在开始复制数据之前,检查目标表是否与源表具有相同的约束,如果发现不同则抛出错误。通过将rewrite.check_constraints设置为false,可以关闭约束检查。在这样做之前,请非常小心。

默认值为true。


rewrite.max_xlock_time

尽管其他事务在大多数情况下都可以对正在处理的表进行读写操作,但需要使用独占锁来完成处理(即处理剩余的并发更改并重命名这些表)。如果扩展阻止了太多对表的访问,可以考虑设置rewrite.max_xlock_time 参数。例如:


SET rewrite.max_xlock_time TO 100;

告知独占锁的持有时间不应超过0.1秒(100毫秒)。如果最后处理阶段需要更多时间,则释放排他锁,处理转换期间其他事务提交的更改,然后再次尝试最后阶段。如果超过锁定持续时间,则会报告错误。如果发生这种情况,应该增加该值,或者稍后在写入活动较少时尝试处理有问题的表。默认值为0,这意味着最终阶段可以根据需要花费任意长的时间。

六、并发

该扩展不会阻止其他事务在转换的某些阶段更改表。如果转换完成之前有其他进程执行了破坏性命令(比如ALTER TABLE...),则转换会中止,并且回滚所做的所有更改。

此扩展允许MVCC-Caveats第一段中描述的MVCC不安全行为。

七、锁

因为更改表名需要排他锁,所以更改表名时在很短的时间内将无法访问该表。

八、转换流程总结

1.用pg_dump -s -t 表名导出需要转换的表到指定sql文件中;

2.修改导出的sql文件,将原表名、主键、索引等内容修改为合适的值,一定不能与原表冲突,然后在create table语句里加上分区相关的内容;

3.在psql中执行修改后的sql文件;

4.根据分区表类型创建相应的分区,可以写成脚本,比如创建hash分区:

do language plpgsql $$
declare
  parts int:=32;--分区数量begin  for i in0..parts-1 loop
    execute format('create table zmd_sell_product_par_p%s partition of zmd_sell_product_par for values with(MODULUS %s, REMAINDER %s)',i, parts, i);  end loop;end;$$;

5.执行partition_table,如果出错,根据错误提示修改表结构。


相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
相关文章
|
6月前
|
关系型数据库 数据库 PostgreSQL
|
存储 SQL JSON
大分区表高并发性能提升100倍?阿里云 RDS PostgreSQL 12 特性解读
世界上几乎最强大的开源数据库系统 PostgreSQL,于 2019 年 10 月 3 日发布了 12 版本,该版本已经在阿里云正式发布。PostgreSQL 12 在功能和性能上都有很大提升,如大分区表高并发性能提升百倍,B-tree 索引空间和性能优化,实现 SQL 2016 标准的 JSON 特性,支持多列 MCV(Most-Common-Value)统计,内联 CTE(Common table expressions)以及可插拔的表存储访问接口等。本文对部分特性进行解读。
2897 0
大分区表高并发性能提升100倍?阿里云 RDS PostgreSQL 12 特性解读
|
SQL 弹性计算 算法
PostgreSQL 普通表在线转换为分区表 - online exchange to partition table
标签 PostgreSQL , 分区表 , 在线转换 背景 非分区表,如何在线(不影响业务)转换为分区表? 方法1,pg_pathman分区插件 《PostgreSQL 9.5+ 高效分区表实现 - pg_pathman》 使用非堵塞式的迁移接口 partition_table_concurrently( relation REGCLASS,
2730 0
|
存储 SQL 监控
16PostgreSQL 本地分区表的用法和优化|学习笔记
快速学习16PostgreSQL 本地分区表的用法和优化
886 0
16PostgreSQL 本地分区表的用法和优化|学习笔记
|
SQL 算法 关系型数据库
PostgreSQL 普通表在线转换为分区表 - online exchange to partition table
PostgreSQL 普通表在线转换为分区表 - online exchange to partition table
2788 0
|
SQL 弹性计算 Oracle
PostgreSQL native partition 分区表性能优化之 - 动态SQL+服务端绑定变量
标签 PostgreSQL , 分区表 , native partition , 性能 , pg_pathman , plpgsql , 动态SQL , 服务端绑定变量 , prepare , execute 背景 目前PG的native partition分区性能不佳,一种解决方法是使用pg_pathman插件,另一种方法是业务上直接插分区,还有一种方法是使用UDF函数接口(函数内部使
1434 0
|
弹性计算 关系型数据库 测试技术
PostgreSQL 分区表如何支持多列唯一约束 - 枚举、hash哈希 分区, 多列唯一, insert into on conflict, update, upsert, merge insert
标签 PostgreSQL , 分区表 , native partition , 唯一 , 非分区键唯一 , 组合唯一 , insert into on conflict , upsert , merge insert 背景 PG 11开始支持HASH分区,10的分区如果要支持hash分区,可以通过枚举绕道实现。 《PostgreSQL 9.x, 10, 11 hash分区表 用法举例
3115 0
|
关系型数据库 数据库 PostgreSQL
PostgreSQL使用表继承实现分区表
PostgreSQL9.6支持基本表的分区。这部分将描述为什么以及如何来实现表分区作为你数据库设计的一部分。 概述 分区指的是将逻辑上一的一个大表分成多个小的物理上的片(子表),分区可以提供以下好处: .在某些情况下查询性能能够显著提升,特别是当那些访问压力大的行在一个分区或者少数几个分区时。
1282 0
|
关系型数据库 PostgreSQL 机器学习/深度学习
PostgreSQL 12: 新增 pg_partition_tree() 函数显示分区表信息
PostgreSQL 12 新增三个分区查询函数,如下: pg_partition_tree(regclass): 返回分区表详细信息,例如分区名称、上一级分区名称、是否叶子结点、层级,层级 0 表示顶层父表。
6501 0
|
关系型数据库 分布式数据库 PolarDB
《阿里云产品手册2022-2023 版》——PolarDB for PostgreSQL
《阿里云产品手册2022-2023 版》——PolarDB for PostgreSQL
363 0