Teleport 最佳实践与问题排查

Teleport 最佳实践与问题排查

本文按照创建数据同步作业的步骤,介绍每一步的推荐配置、原因和常见风险,并给出高频问题的排查方法。第一次使用 Teleport 时,建议先阅读数据同步快速入门

创建作业前

明确同步目标

创建作业前,先确认以下信息:

  • 同步是一次性迁移,还是需要长期保持增量同步。
  • 需要同步哪些 Database、Schema 和 Table,是否需要自动同步以后新增的表。
  • 目标端是新建表还是使用已有表,是否允许其他应用同时写入目标表。
  • 是否需要重命名对象、合并分库分表、裁剪字段或转换字段类型。
  • 业务可接受的同步延迟、迁移窗口和源端日志保留时间。

对于长期同步,通常选择“全量 + 增量”:先同步存量数据,再持续同步新产生的变更。只选择增量同步不会自动补齐启动前已经存在的数据。

先用少量对象验证链路

建议先选择一张数据量较小、结构具有代表性的表创建测试作业,验证以下内容后再扩大同步范围:

  • 源端和目标端网络、账户权限正常。
  • 目标对象名称和字段映射符合预期。
  • INSERTUPDATEDELETE 的结果正确。
  • 目标表的主键、唯一索引和字段类型满足业务要求。
  • 同步吞吐和延迟满足预期。

测试作业和正式作业不要同时同步相同的源表到相同的目标表。

推荐配置步骤

1. 创建作业

使用能够表达“源端、目标端和用途”的名称,例如 mysql-order-to-protonbase。同一业务有测试和正式作业时,建议在名称中增加环境标识,便于告警和问题排查。

2. 配置连接

  • 为 Teleport 创建专用数据库账户,并按照数据同步权限规划授予所需的最小权限。
  • 源端使用域名连接时,确认域名解析结果稳定,且解析出的地址都已配置网络放行规则。
  • 使用公网或 Tunnel 接入时,只放行实际需要的地址和端口。详细接入方式请参见数据同步网络配置
  • 源端和目标端都完成“连接测试”后再进入下一步。连接测试成功只表示当时能够建立连接,仍需通过作业预检查验证权限、对象和配置。
  • 不要让同步账户的密码在作业运行期间过期;轮换密码后,应及时修改作业配置并重新运行预检查。

3. 选择同步对象

  • 对象较少且范围固定时,优先显式选择需要同步的对象,减少误同步系统表、临时表和历史表的风险。
  • 对象较多且命名有稳定规律时,可以使用正则规则。正则规则应尽量限定 Database、Schema 和 Table,避免使用范围过大的全匹配表达式。
  • 如果希望以后新增的表自动进入同步范围,应使用能够覆盖未来表名的规则:excludes 会同步所有未被排除的新表;includes 则需要配置能够命中新表的正则。详细语义请参见选择同步对象
  • 修改筛选规则后,应重新检查实际命中的对象列表。详细配置方法请参见选择同步对象

4. 设置映射规则

目标表名优先使用变量

在 Database、Schema、TABLES 或批量应用的表级规则中,建议使用 SOURCE_OBJECT 表示源表名,而不是把目标表名写成固定常量。例如:

concat('target_database', '.', 'public', '.', SOURCE_OBJECT)

不建议在包含多张表的节点上配置以下规则:

concat('target_database', '.', 'public', '.', 'orders')

固定常量会让该节点下的多张源表映射到同一张目标表,容易造成非预期合表、主键冲突或数据相互覆盖。使用 SOURCE_OBJECT 还能让以后进入同步范围的新表继承相同规则,减少逐表维护成本。

只有以下场景建议使用固定目标表名:

  • 明确将某一张源表重命名到指定目标表。
  • 经过数据模型和键冲突评估后,明确需要将多张分表合并到一张目标表。

合表前必须确认各源表结构兼容,并检查主键和唯一索引在所有源表之间是否全局唯一。具体方法请参见数据同步分库分表最佳实践

让规则保留安全的默认分支

使用 case when 或正则处理部分表时,建议在 else 中保留同名映射:

case
  when regexp_match(SOURCE_OBJECT, '(.*)_[0-9]{3}$')
    then concat('target_database.public.', $1)
  else concat('target_database.public.', SOURCE_OBJECT)
end

这样没有命中特殊规则的表仍会映射到独立的同名目标表。不要在没有确认完整命中范围时,把 else 指向某一张固定目标表。

修改映射后检查最终结果

映射规则具有继承和覆盖关系。子节点配置会覆盖上级节点,因此不能只检查当前编辑的表达式。完成配置后,在预检查结果中打开表映射列表,确认每一张源表最终对应的目标 Database、Schema 和 Table。

重点检查:

  • 是否有多张不相关的源表落到同一目标表。
  • 目标对象名称是否包含错误的 Database 或 Schema。
  • 正则分组是否正确,是否意外命中临时表或历史表。
  • 目标端已有表时,字段名称、类型、主键和唯一索引是否兼容。

更多语法和示例请参见设置映射规则

5. 设置同步属性

  • 长期增量同步建议保留业务需要的 INSERTUPDATEDELETE 事件。关闭某类事件前,应确认目标端允许与源端产生相应差异。
  • 只开启业务实际需要的 DDL 事件。开启 Schema Evolution 前,应确认源端变更方式和目标端对象依赖满足要求。
  • 对 PostgreSQL 增量同步,建议同步表具有主键。无主键表需要结合 Replica Identity 和实际更新、删除需求进行评估。
  • 对新增表使用继承配置时,在上级节点统一设置属性,避免新表未继承到逐表配置。

详细说明请参见设置同步属性数据同步 Schema Evolution 原理解析

6. 选择同步策略和规格

  • 一次性迁移且迁移完成后不再追踪源端变化时,选择全量同步。
  • 只需要从当前日志位置开始接收未来变更、并且目标端已有完整基线数据时,才选择增量同步。
  • 需要迁移存量数据并长期保持同步时,选择“全量 + 增量”。
  • 规格评估应同时考虑数据量、源端读取能力、网络带宽和目标端写入能力。单独扩大 Teleport 规格不能消除源端、目标端或网络瓶颈。

可先按数据同步容量规划选择初始规格,再根据实际 RPS、延迟和上下游负载调整。

7. 运行预检查

启动前必须检查最新一次预检查结果,重点关注:

  • 源端和目标端连接及账户权限。
  • 源端版本、日志配置和同步所需的前置条件。
  • 目标端对象和写入权限。
  • 最终表映射和字段映射。
  • 可能产生的脏数据或数据冲突风险。

修改连接、对象范围、映射规则或同步属性后,之前的结果不能代表当前配置,应重新运行预检查。对于错误项,建议修复后再启动;对于警告项,应理解影响并完成业务确认后再决定是否继续。

8. 启动并验证

作业启动后不要只检查状态。建议同时完成以下验证:

  1. 检查作业实例是否进入“运行中”,全量阶段进度是否持续变化。
  2. 抽查源端和目标端的记录数及关键业务字段。
  3. 在源端执行一组可识别的 INSERTUPDATEDELETE,确认目标端结果。
  4. 检查目标表结构、主键、唯一索引和字段类型。
  5. 观察 RPS、BPS、Idle Time 和 Emit Event Time,建立正常运行时的指标基线。

Schema Evolution 最佳实践

Schema Evolution 用于让运行中的增量同步作业跟随源端表结构变化。它不是简单地把源端 DDL 原样发送到目标端,而是经过以下处理:

  1. 源端 Connector 从增量日志、DDL 捕获事件或 Relation 消息中识别结构变化。
  2. Teleport 获取变更后的表结构,与当前元数据快照比较,生成表结构差异。
  3. 映射规则基于新结构重新计算,并把带位点的元数据版本写入状态。
  4. 对数据库等结构化目标,Teleport 将结构差异转换为目标端 DDL 后执行;对 Kafka 等非结构化目标,只更新元数据和消息映射,不在目标端执行 DDL。

元数据版本与增量位点一同保存,因此作业恢复或从历史位点继续消费时,可以使用对应时刻的表结构解析数据。DDL 和同一事务内的 DML 也会按照源端顺序处理。

不同捕获方式的能力差异

源端与捕获方式识别机制推荐用法与能力边界
MySQL从 binlog 获取 DDL,并解析为结构差异能够支持绝大多数常用 Schema Evolution,包括表的创建、删除、重命名和清空,列的增加、删除、重命名与属性修改,以及常见的主键、索引和约束变更。仍需满足目标端类型兼容性和 DDL 能力。
PostgreSQL Event TriggerEvent Trigger 捕获 DDL,并读取变更后的完整表结构能够支持绝大多数常用 Schema Evolution。建议使用此方式;同步账户需要有权创建所需函数和 Event Trigger,或由管理员提前创建。预检查会提示缺少的权限与对象。
PostgreSQL Relation Message比较 Relation 消息中的列形状与已有元数据不需要创建 Event Trigger,但只能可靠识别会改变行结构的部分变更,能力明显少于 Trigger 方式。仅建议用于不能部署 Event Trigger、且 DDL 变更范围受控的场景。
ProtonBase 导出当前通过 Relation 消息探测列形状,并在需要时重新读取源表元数据支持范围见下表。由于没有完整 DDL 语义,不能把所有结构差异都安全地还原为目标端 DDL。

这里的“支持”还取决于目标端:即使源端可以准确识别 DDL,目标数据库不支持相应语法、字段类型无法转换,或者映射后的多张源表结构不兼容,仍可能成为不支持的演进。

ProtonBase 导出的支持范围

ProtonBase 源端变化导出到 Kafka导出到 PostgreSQL 等数据库
新增表新表命中 includes,或未被 excludes 排除时,自动进入同步范围同左,并在目标端创建映射后的表
新增列支持;后续消息按新结构输出新增字段支持;在目标端执行加列
修改列类型、长度或精度支持元数据和消息结构更新,不需要执行目标端 DDL在目标端类型兼容且能够安全转换时支持
删除列支持 Meta-only Evolution;后续消息不再输出该字段,表不会下线当前不支持;受影响的表会下线
重命名列按消息结构变化更新元数据;Kafka 侧表现为旧字段消失、新字段出现,表不会因为无法还原 RENAME COLUMN 而下线当前不能仅凭 Relation 消息安全地区分重命名与删列加列;受影响的表会下线
TRUNCATE TABLE支持;输出相应的清空事件,具体表现取决于 Kafka 消息格式支持;在目标端执行清空表操作
删除表、重命名表,以及只改变默认值、注释、键、索引或约束的操作Relation 消息不能完整表达这些 DDL,不保证自动传播;Kafka 不需要执行目标端 DDL,也不会仅因不支持该 DDL 而下线表当前不保证自动传播;不要依赖这些变化自动应用到目标数据库

变更前的建议

  • MySQL 或 PostgreSQL 源端需要频繁做 DDL 时,优先使用能够捕获完整 DDL 的方式;PostgreSQL 建议使用 Event Trigger,不要为了减少初始化对象而退回 Relation Message。
  • 先在测试表验证源端 DDL、映射规则和目标端类型转换。特别关注缩小字段长度、降低数值精度、修改主键,以及多张源表合并到同一目标表的场景。
  • ProtonBase 导出到数据库时,避免在线删除或重命名列。确需变更时,先暂停作业,在源端和目标端完成兼容性变更,再按平台流程恢复或重新初始化受影响的表。
  • ProtonBase 导出到 Kafka 时,下游消费者仍需能够处理字段增加、消失和类型变化。Teleport 不下线表不代表消费者一定兼容新消息结构。
  • DDL 后检查作业事件和目标表结构。发现单表因不支持的演进而下线后,不要直接重启整个作业;先确认源端变化、目标端能力和映射结果,再处理受影响的表。

更完整的原理说明请参见数据同步 Schema Evolution 原理解析

运行期间的最佳实践

避免多方写入同一目标数据

持续同步期间,尽量避免应用、人工脚本或另一个同步作业同时写入 Teleport 管理的目标数据。多方写入可能产生数据覆盖、唯一键冲突以及源端和目标端不一致。

区分恢复和重启

  • 恢复:保留已有同步状态,从暂停位置继续同步。
  • 重启:清除已有作业状态并从头开始同步。

临时停机后通常应选择恢复。只有明确需要重新执行全量同步,并且已经评估目标端存量数据处理方式时才使用重启。

不要长时间暂停增量作业

增量作业暂停后,源端仍可能持续产生变更日志。尤其是 PostgreSQL 源端,复制槽可能使 WAL 持续保留并占用磁盘。暂停期间应监控源端日志空间,并尽快恢复或按计划结束作业。

变更配置后重新验证

调整对象范围、映射规则、同步属性、连接信息或目标表结构后,应重新运行预检查,并再次检查最终表映射。配置变更和数据库 DDL 尽量安排在受控变更窗口内完成。

常见问题排查

连接测试失败

按以下顺序检查:

  1. 地址、端口、Database、用户名和密码是否正确。
  2. 数据库是否允许远程连接,账户是否被锁定或过期。
  3. 安全组、防火墙和数据库白名单是否已放行 Teleport。
  4. 使用 Tunnel 时,Tunnel 状态、路由和目标地址是否正确。
  5. 源端或目标端是否达到连接数上限。

连接恢复后,重新执行两端连接测试和完整预检查。

多张源表意外写入同一目标表

首先在预检查的表映射列表中确认最终映射,然后从最接近表的节点向上检查映射覆盖关系。常见原因是上级或批量规则把目标表名写成固定常量。

将普通同名同步规则改为:

concat('target_database', '.', 'public', '.', SOURCE_OBJECT)

如果作业已经写入数据,应先暂停作业并评估目标端数据,避免直接修改规则后继续写入错误表。

新增表没有自动同步

对于包含增量同步的作业,源端新增表只要落在 includesexcludes 定义的同步范围内,就会自动同步。未同步时依次检查:

  1. 新表所在的 Database 和 Schema 是否在同步范围内。
  2. 表级使用 includes 时,新表名是否命中其中的正则;精确表名不会覆盖其他新表。
  3. 表级使用 excludes 时,新表是否意外命中了排除项。
  4. 同步账户是否具有读取新表的权限。
  5. 新表继承到的同步属性和映射规则是否有效,目标对象是否发生冲突。

对于依赖消息 Schema 分析的 Kafka 协议,还需要确认 Schema 分析结果中已经包含新表。

预检查结果与当前配置不一致

如果预检查之后修改过作业配置,旧结果已经失效。保存当前配置并重新运行预检查,再以最新结果中的对象和映射列表为准。

目标端数据与源端不一致

常见原因包括:

  • 只运行了全量同步,结束后源端又发生了变更。
  • 只运行增量同步,但目标端没有完整的基线数据。
  • 作业仍有同步延迟,变更尚未写入目标端。
  • 目标端存在其他写入方。
  • 对象筛选、DML 属性或字段映射排除了部分数据。
  • 多张源表意外映射到了同一目标表。

先确定差异产生的时间范围和对象,再检查作业配置、实例历史和对应时段的指标。不要在原因未确认时直接重启作业,以免扩大目标端数据影响范围。

作业延迟持续增大

结合 Idle Time 和 Emit Event Time 判断:

  • Idle Time 较大,但 Emit Event Time 较小且不再变化:源端可能没有新数据,通常不表示积压。
  • Idle Time 和 Emit Event Time 都较大且趋势接近:作业可能存在真实延迟。

确认真实延迟后,再检查 Teleport RPS/BPS、源端读取负载、网络带宽、目标端写入负载和作业规格,定位实际瓶颈。具体指标含义请参见作业操作和状态

暂停后源端磁盘占用持续增长

对于 PostgreSQL 源端,优先检查复制槽保留的 WAL。尽快恢复作业,使消费位点继续推进;如果不再需要该作业,应按照平台流程结束作业并确认相关资源已经释放。不要在未确认归属和恢复计划时直接删除复制槽。

修改配置后作业仍按旧规则运行

先确认配置已经保存,再重新运行预检查,检查最新表映射是否已经变化。运行中的配置是否可以直接生效取决于修改项和作业状态;需要重新初始化的修改,应在受控窗口暂停作业后按平台提示操作。不要用“重启”代替配置核对,因为重启会清除已有同步状态。

更多问题请参见Teleport 常见问题。如果问题仍未解决,请保留作业 ID、失败实例、发生时间、预检查结果和错误信息,以便进一步定位。