IMCI 功能默认使用主键来同步数据的更新和删除。然而,当表没有主键,或主键无序(如UUID),数据同步会引发大量随机 I/O,导致同步效率低下时,默认策略便不再适用。本实践将介绍如何通过自定义复制键,解决这些问题,从而大幅提升数据同步性能。
前提条件
表中存在一个值在物理存储上具有单调递增特性的列。
注意事项
在实施前,请务必关注以下几点:
必须基于唯一索引:自定义复制键必须通过
USING INDEX指定一个唯一索引(Unique Index)。索引列必须非空:用于复制键的唯一索引,其包含的列必须定义为
NOT NULL。推荐使用有序索引:为达到最佳性能,强烈建议该唯一索引建立在单调递增的列上(如
SERIAL或BIGSERIAL类型的自增列)。
工作原理
REPLICA IDENTITY 机制
通过 REPLICA IDENTITY 属性来决定在逻辑复制的 WAL(Write-Ahead Log)中记录哪些信息,以便下游能够唯一标识发生变更的行。IMCI 正是利用此机制来定位并更新列存中的数据。REPLICA IDENTITY 支持以下四种模式:
模式 | 含义 | 适用场景 |
| 使用主键(Primary Key)作为标识。 | 默认推荐。只要表有主键,通常无需修改。 |
| 使用指定的唯一索引(Unique Index)作为标识。 | 当表无主键或主键无序时,可指定一个有序的唯一索引来提升效率。 |
| 将整行所有列的值都写入 WAL 作为标识。 | 仅在表既无主键也无唯一索引,且必须支持更新/删除时使用。 |
| 不记录任何标识信息。 | 仅适用于只进不出(INSERT)的表,不支持更新或删除。 |
使用有序唯一索引作为复制键
本实践的核心思想是利用 USING INDEX 模式,将一个基于有序字段(如自增列)创建的唯一索引指定为复制键。
工作流程如下:
创建有序唯一索引:为一个在物理存储上有序的列(如
SERIAL类型的自增 ID)创建一个唯一索引。更改复制标识:使用
ALTER TABLE ... REPLICA IDENTITY USING INDEX ...命令,将表的复制键切换到新创建的唯一索引。高效逻辑解码:逻辑复制时,系统会高效地从 WAL 中解码出有序索引键的值。
加速数据同步:IMCI 利用这个有序的键值在列存中进行数据定位和更新。由于键值有序,操作将变为高效的顺序 I/O,从而大幅提升数据同步效率。
操作指南
步骤一:创建唯一索引
为您的有序自增列创建一个唯一索引。
-- 假设表 t 中存在一个名为 serial_id 的自增列 CREATE UNIQUE INDEX idx_t_serial_id ON t(serial_id);步骤二:更改表的复制标识
将表的
REPLICA IDENTITY切换到上一步创建的唯一索引。ALTER TABLE t REPLICA IDENTITY USING INDEX idx_t_serial_id;步骤三:创建或重建列存索引
确保您的列存索引(CSI)包含了作为复制键的列。如果已有列存索引,建议重建以获得最佳性能。
-- 创建一个包含所有列的列存索引 CREATE INDEX ON t USING csi;步骤四:对比测试
我们通过一个实验来验证其性能提升效果。
测试设置:
创建一张包含无序主键(
random_id)和有序自增列(serial_id)的表。create table t (random_id text primary key, serial_id serial, a text);插入 1000 万行数据。
insert into t(random_id, a) select md5(i::text), i::text from generate_series(1, 10000000) i;创建列存索引和有序唯一索引
idx_a(serial_id)。create unique index idx_a on t(serial_id); create index on t using csi;
测试过程:
默认模式测试(使用无序主键
random_id作为复制键):-- 更新 10000 行数据 UPDATE t SET a = '0' WHERE serial_id <= 10000;自定义模式测试(切换复制键为有序唯一索引
idx_a):ALTER TABLE t REPLICA IDENTITY USING INDEX idx_a; -- 再次更新 10000 行数据 UPDATE t SET a = '1' WHERE serial_id <= 10000;
测试结果:
复制键类型
默认主键(无序)
自定义唯一索引(有序)
同步耗时(1万条)
~0.5 秒
~0.01 秒
结论分析
测试结果表明,通过将复制键从无序的 Primary Key 切换到基于自增列的 Unique Index,数据同步性能获得了约 50 倍 的巨大提升。这充分证明了自定义有序复制键在提升 IMCI 数据同步效率方面的关键作用。