在RDS PostgreSQL中进行某些数据定义语言(DDL)操作时,例如将INT类型变更为BIGINT,原生的ALTER COLUMN TYPE
操作会因二进制不兼容而重写整个表,期间会长时间锁定表,中断业务读写。为了解决这一问题,RDS PostgreSQL提供了rds_online_ddl
插件,该插件支持在线修改列类型,从而在不影响业务连续性的前提下完成表结构变更。
功能简介
虽然PostgreSQL的许多DDL操作(如CREATE INDEX CONCURRENTLY
)已支持并发执行,但对于二进制不兼容的列类型修改,仍需要进行锁表重写,这是数据库运维中一个常见且影响较大的场景。
rds_online_ddl插件通过创建临时表并以在线方式同步数据,从而避免长时间阻塞。整个过程大致如下:
创建临时表:创建与原表结构相同的临时表。
修改结构:在临时表上执行您指定的
ALTER COLUMN TYPE
操作。同步存量数据:将原表的存量数据高效地导入到临时表中。
构建索引:在临时表上创建与原表一致的所有索引。
同步增量数据:通过逻辑解码将上述操作期间产生的增量数据同步至临时表,确保数据最终一致。
修改原表结构:获取原表的最高级锁,并对原表结构进行修改。
交换文件:交换原表与临时表(包括索引)的底层文件。
提交事务:删除临时表并提交事务,完成整个在线DDL过程。
前提条件
目标RDS PostgreSQL实例满足以下条件:
注意事项
验证及备份:在生产环境使用前,强烈建议您在测试环境中进行充分验证,并确保已具备有效的备份。
存储空间:在执行期间需额外预留存储空间,其大小约为原表及其索引总和的两倍。请确保实例具备足够的可用空间。
表限制:
该功能不支持包含外键约束的表。
该功能仅支持常规表(Regular Table),不支持分区表(Partitioned Table)。
ALTER TABLE
的USING
子句因逻辑复制限制可能无法完全支持,使用时请进行测试。整个操作过程是原子性的。如果中途失败或被中断,表结构将回滚至原始状态,不会造成数据损坏。
计费说明
此插件免费。
创建和删除插件
请使用高权限账号执行如下命令。
创建插件
CREATE EXTENSION rds_online_ddl;
说明通过
SELECT * FROM pg_extension;
可以查看已安装的插件。删除插件
DROP EXTENSION rds_online_ddl;
使用示例
例如,将test表的id列从int4修改为int8。
执行以下命令,创建测试表test,并插入测试数据。
CREATE TABLE test(id int4 PRIMARY KEY, info TEXT); INSERT INTO test SELECT x, repeat(x::text, 2) FROM generate_series(1, 1000000) AS x;
调用rds_online_ddl.alter_table函数,执行在线DDL操作。该函数的第一个参数为目标表名,第二个参数为标准的
ALTER TABLE
命令。SELECT rds_online_ddl.alter_table('public.test', 'ALTER COLUMN id TYPE int8');
(可选)查看进度。
对于数据量较大的表,操作可能需要较长时间。您可以通过查询以下视图来监控任务进度:
SELECT * FROM rds_online_ddl.pg_stat_progress_online_ddl;
视图中,关键字段说明:
insert_initial:表示已经导入的存量数据行数。
nindexes_built:表示已完成构建的索引数量。
nindexes_total:表示索引总数。
insert_applied/update_applied/delete_applied:表示对应操作类型已应用的增量数据数量。
insert_decoded/update_decoded/delete_decoded:表示对应操作类型已解码的增量数据数量。