全部产品
Search
文档中心

云原生数据库 PolarDB:自定义数据复制键

更新时间:Mar 27, 2026

IMCI 功能默认使用主键来同步数据的更新和删除。然而,当表没有主键,或主键无序(如UUID),数据同步会引发大量随机 I/O,导致同步效率低下时,默认策略便不再适用。本实践将介绍如何通过自定义复制键,解决这些问题,从而大幅提升数据同步性能。

前提条件

表中存在一个值在物理存储上具有单调递增特性的列。

注意事项

在实施前,请务必关注以下几点:

  • 必须基于唯一索引:自定义复制键必须通过 USING INDEX 指定一个唯一索引(Unique Index)。

  • 索引列必须非空:用于复制键的唯一索引,其包含的列必须定义为 NOT NULL

  • 推荐使用有序索引:为达到最佳性能,强烈建议该唯一索引建立在单调递增的列上(如 SERIAL 或 BIGSERIAL 类型的自增列)。

工作原理

REPLICA IDENTITY 机制

通过 REPLICA IDENTITY 属性来决定在逻辑复制的 WAL(Write-Ahead Log)中记录哪些信息,以便下游能够唯一标识发生变更的行。IMCI 正是利用此机制来定位并更新列存中的数据。REPLICA IDENTITY 支持以下四种模式:

模式

含义

适用场景

DEFAULT

使用主键(Primary Key)作为标识。

默认推荐。只要表有主键,通常无需修改。

USING INDEX

使用指定的唯一索引(Unique Index)作为标识。

当表无主键或主键无序时,可指定一个有序的唯一索引来提升效率。

FULL

将整行所有列的值都写入 WAL 作为标识。

仅在表既无主键也无唯一索引,且必须支持更新/删除时使用。

NOTHING

不记录任何标识信息。

仅适用于只进不出(INSERT)的表,不支持更新或删除。

使用有序唯一索引作为复制键

本实践的核心思想是利用 USING INDEX 模式,将一个基于有序字段(如自增列)创建的唯一索引指定为复制键。

工作流程如下:

  1. 创建有序唯一索引:为一个在物理存储上有序的列(如 SERIAL 类型的自增 ID)创建一个唯一索引。

  2. 更改复制标识:使用 ALTER TABLE ... REPLICA IDENTITY USING INDEX ... 命令,将表的复制键切换到新创建的唯一索引。

  3. 高效逻辑解码:逻辑复制时,系统会高效地从 WAL 中解码出有序索引键的值。

  4. 加速数据同步: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;
  • 步骤四:对比测试

    我们通过一个实验来验证其性能提升效果。

    • 测试设置:

      1. 创建一张包含无序主键(random_id)和有序自增列(serial_id)的表。

        create table t (random_id text primary key, serial_id serial, a text);
      2. 插入 1000 万行数据。

        insert into t(random_id, a)
          select md5(i::text), i::text
            from generate_series(1, 10000000) i;
      3. 创建列存索引和有序唯一索引 idx_a(serial_id)

        create unique index idx_a on t(serial_id);
        create index on t using csi;
    • 测试过程:

      1. 默认模式测试(使用无序主键 random_id 作为复制键):

        -- 更新 10000 行数据
        UPDATE t SET a = '0' WHERE serial_id <= 10000;
      2. 自定义模式测试(切换复制键为有序唯一索引 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 数据同步效率方面的关键作用。