文档

普通表在线转换为分区表

更新时间:

PolarDB PostgreSQL版(兼容Oracle)支持将普通表转换为分区表,从而不阻塞该表上其他业务的查询操作。

前提条件

支持的PolarDB PostgreSQL版(兼容Oracle)的版本如下:

Oracle 2.0(内核小版本2.0.14.20.0及以上)

说明

您可通过如下语句查看PolarDB PostgreSQL版(兼容Oracle)的内核小版本的版本号:

SHOW polar_version; 

背景信息

分区表相比于普通表有一些独特的优势。例如,相比较于普通表的批量数据删除,直接删除分区将会更加高效;分区表可以有效避免普通表的TOSAT OID回卷问题;使用分区键进行查询可以对分区剪枝,加速数据查找等。

PolarDB PostgreSQL版(兼容Oracle)支持将普通表转换为分区表,从而不阻塞该表上其他业务的查询操作。

注意事项

  • 在创建目标分区表时请创建与原表一致的索引,否则可能会在增量数据转换阶段出现性能问题,回放增量永远追不上。

  • 如果转换失败或者出错,转换进程将会自动退出,在错误日志中将会打印相关信息。

  • 最终是否转换成功,需要查看您要转换的表是否已经变成了分区表,如果没有则说明失败。

  • 转换进程最多可以开启max_worker_processes个,即最多可以同时转换max_worker_processes张表。

  • 转换开始时,允许新分区表中有数据,但这将会导致新旧两张表数据不一致。请您根据需求对新表进行检查,建议在转换前TRUNCATE新分区表。

使用限制

普通表转换为分区表功能依赖polar_ddl_manager插件的2.0版本。您可以通过以下命令,查询polar_ddl_manager插件的版本信息。

CREATE EXTENSION polar_ddl_manager;
=> \dx
                                 List of installed extensions
        Name         | Version |      Schema       |                Description
---------------------+---------+-------------------+-------------------------------------------
 polar_ddl_manager   | 2.0     | polar_ddl_manager | Optimize the logic of some ddl operations

使用示例

假设您有一张表pgbench_accounts,现在需要将其转换为分区表。

复刻表结构

创建一张分区表,和pgbench_accounts具有相同的结构及索引。

CREATE TABLE pgbench_accounts_parted(LIKE pgbench_accounts)
  PARTITION BY HASH(aid);
CREATE TABLE pgbench_accounts_p1
  PARTITION OF pgbench_accounts_parted
  FOR VALUES WITH (MODULUS 2, REMAINDER 0);
CREATE TABLE pgbench_accounts_p2
  PARTITION OF pgbench_accounts_parted
  FOR VALUES WITH (MODULUS 2, REMAINDER 1);
ALTER TABLE pgbench_accounts_parted ADD PRIMARY KEY(aid);

开始表类型转换

调用polar_ddl_manager.polar_convert_to_parted函数进行转换。

polar_ddl_manager.polar_convert_to_parted
(
  source_table REGCLASS,
  target_table REGCLASS,
  IN check_data BOOLEAN DEFAULT false
) RETURNS pg_catalog.int4

参数说明:

参数

说明

source_table

被转换的表名,即示例中的pgbench_accounts

target_table

转换后的目标表名,即示例中的pgbench_accounts_parted

check_data

在转换完成后是否进行数据比对校验,检查两个表的数据是否一致。取值如下:

  • false(默认值):不进行数据校验。

  • true:进行数据校验。

说明

如果表非常大,该过程将会非常缓慢,且该过程会锁表阻塞其他业务,通常用于测试环境,不建议生产环境使用。

返回值为后台转换进程的进程ID。示例如下:

SELECT polar_ddl_manager.polar_convert_to_parted(
    'pgbench_accounts',
    'pgbench_accounts_parted'
   );
 polar_convert_to_parted
-------------------------
                 2511638

polar_ddl_manager.polar_convert_to_parted函数的原理是启动一个后台进程进行转换,转换完成后该后台进程将会自动退出。此过程的进度快慢与这张表上的业务繁忙程度相关,业务越繁忙,转换进度越慢。

转换完成后,会自动将表pgbench_accounts和表pgbench_accounts_parted的名称交换,表名交换过程需要短暂锁表。交换完成后,pgbench_accounts成为分区表,而pgbench_accounts_parted成为普通表。后续的业务将会继续使用pgbench_accounts,而pgbench_accounts_parted将不再起作用,可以删除。

监控转换过程

通过polar_ddl_manager.polar_show_convert_parted_tasks()视图函数对转换过程进行监控。

polar_ddl_manager.polar_show_convert_parted_tasks()
RETURNS (
  username REGROLE,
  pid INT,
  dbid OID,
  source_table REGCLASS,
  target_table REGCLASS,
  status TEXT
);

参数说明:

参数

说明

username

发起转换的用户。

pid

转换后台进程pid。

dbid

转换表所在的数据库ID。

source_table

被转换表(普通表)。

target_table

目标转换表(分区表)。

status

转换进程的状态。取值如下:

  • starting:开始阶段,发起转换任务,后台进程启动。

  • copy table:存量数据拷贝阶段,将被转换表的存量数据转移到分区表中。

  • replay increment:增量数据转换阶段,将被转换表的增量数据不断转移到分区表中,此过程的持续时间通常根据表上的事务数量决定,事务数据越多,持续时间越长。

  • change table name:表名交换阶段,通常会很快结束,到达此阶段说明即将成功。

转换后结果示例如下:

SELECT * FROM polar_ddl_manager.polar_show_convert_parted_tasks();
  userid  |   pid   | dbid  |    source_oid    |       target_oid        |   status
----------+---------+-------+------------------+-------------------------+------------
 postgres | 2511638 | 14074 | pgbench_accounts | pgbench_accounts_parted | copy table
(1 row)

  • 本页导读