Teleport 最佳实践与问题排查
本文按照创建数据同步作业的步骤,介绍每一步的推荐配置、原因和常见风险,并给出高频问题的排查方法。第一次使用 Teleport 时,建议先阅读数据同步快速入门。
创建作业前
明确同步目标
创建作业前,先确认以下信息:
- 同步是一次性迁移,还是需要长期保持增量同步。
- 需要同步哪些 Database、Schema 和 Table,是否需要自动同步以后新增的表。
- 目标端是新建表还是使用已有表,是否允许其他应用同时写入目标表。
- 是否需要重命名对象、合并分库分表、裁剪字段或转换字段类型。
- 业务可接受的同步延迟、迁移窗口和源端日志保留时间。
对于长期同步,通常选择“全量 + 增量”:先同步存量数据,再持续同步新产生的变更。只选择增量同步不会自动补齐启动前已经存在的数据。
先用少量对象验证链路
建议先选择一张数据量较小、结构具有代表性的表创建测试作业,验证以下内容后再扩大同步范围:
- 源端和目标端网络、账户权限正常。
- 目标对象名称和字段映射符合预期。
INSERT、UPDATE、DELETE的结果正确。- 目标表的主键、唯一索引和字段类型满足业务要求。
- 同步吞吐和延迟满足预期。
测试作业和正式作业不要同时同步相同的源表到相同的目标表。
推荐配置步骤
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. 设置同步属性
- 长期增量同步建议保留业务需要的
INSERT、UPDATE、DELETE事件。关闭某类事件前,应确认目标端允许与源端产生相应差异。 - 只开启业务实际需要的 DDL 事件。开启 Schema Evolution 前,应确认源端变更方式和目标端对象依赖满足要求。
- 对 PostgreSQL 增量同步,建议同步表具有主键。无主键表需要结合 Replica Identity 和实际更新、删除需求进行评估。
- 对新增表使用继承配置时,在上级节点统一设置属性,避免新表未继承到逐表配置。
详细说明请参见设置同步属性和数据同步 Schema Evolution 原理解析。
6. 选择同步策略和规格
- 一次性迁移且迁移完成后不再追踪源端变化时,选择全量同步。
- 只需要从当前日志位置开始接收未来变更、并且目标端已有完整基线数据时,才选择增量同步。
- 需要迁移存量数据并长期保持同步时,选择“全量 + 增量”。
- 规格评估应同时考虑数据量、源端读取能力、网络带宽和目标端写入能力。单独扩大 Teleport 规格不能消除源端、目标端或网络瓶颈。
可先按数据同步容量规划选择初始规格,再根据实际 RPS、延迟和上下游负载调整。
7. 运行预检查
启动前必须检查最新一次预检查结果,重点关注:
- 源端和目标端连接及账户权限。
- 源端版本、日志配置和同步所需的前置条件。
- 目标端对象和写入权限。
- 最终表映射和字段映射。
- 可能产生的脏数据或数据冲突风险。
修改连接、对象范围、映射规则或同步属性后,之前的结果不能代表当前配置,应重新运行预检查。对于错误项,建议修复后再启动;对于警告项,应理解影响并完成业务确认后再决定是否继续。
8. 启动并验证
作业启动后不要只检查状态。建议同时完成以下验证:
- 检查作业实例是否进入“运行中”,全量阶段进度是否持续变化。
- 抽查源端和目标端的记录数及关键业务字段。
- 在源端执行一组可识别的
INSERT、UPDATE、DELETE,确认目标端结果。 - 检查目标表结构、主键、唯一索引和字段类型。
- 观察 RPS、BPS、Idle Time 和 Emit Event Time,建立正常运行时的指标基线。
Schema Evolution 最佳实践
Schema Evolution 用于让运行中的增量同步作业跟随源端表结构变化。它不是简单地把源端 DDL 原样发送到目标端,而是经过以下处理:
- 源端 Connector 从增量日志、DDL 捕获事件或 Relation 消息中识别结构变化。
- Teleport 获取变更后的表结构,与当前元数据快照比较,生成表结构差异。
- 映射规则基于新结构重新计算,并把带位点的元数据版本写入状态。
- 对数据库等结构化目标,Teleport 将结构差异转换为目标端 DDL 后执行;对 Kafka 等非结构化目标,只更新元数据和消息映射,不在目标端执行 DDL。
元数据版本与增量位点一同保存,因此作业恢复或从历史位点继续消费时,可以使用对应时刻的表结构解析数据。DDL 和同一事务内的 DML 也会按照源端顺序处理。
不同捕获方式的能力差异
| 源端与捕获方式 | 识别机制 | 推荐用法与能力边界 |
|---|---|---|
| MySQL | 从 binlog 获取 DDL,并解析为结构差异 | 能够支持绝大多数常用 Schema Evolution,包括表的创建、删除、重命名和清空,列的增加、删除、重命名与属性修改,以及常见的主键、索引和约束变更。仍需满足目标端类型兼容性和 DDL 能力。 |
| PostgreSQL Event Trigger | Event 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 而下线表 | 当前不保证自动传播;不要依赖这些变化自动应用到目标数据库 |
ProtonBase 导出到 Kafka 时,目标端没有需要维护的数据库表结构。遇到无法转换为目标端 DDL 的 Schema Evolution,Teleport 会优先刷新元数据和映射并继续输出,不会将表下线。导出到 PostgreSQL 等结构化数据库时,目标端必须真实执行 DDL;如果变化无法安全应用,Teleport 会将受影响的单表下线以保护数据一致性,作业和其他表继续运行。
变更前的建议
- MySQL 或 PostgreSQL 源端需要频繁做 DDL 时,优先使用能够捕获完整 DDL 的方式;PostgreSQL 建议使用 Event Trigger,不要为了减少初始化对象而退回 Relation Message。
- 先在测试表验证源端 DDL、映射规则和目标端类型转换。特别关注缩小字段长度、降低数值精度、修改主键,以及多张源表合并到同一目标表的场景。
- ProtonBase 导出到数据库时,避免在线删除或重命名列。确需变更时,先暂停作业,在源端和目标端完成兼容性变更,再按平台流程恢复或重新初始化受影响的表。
- ProtonBase 导出到 Kafka 时,下游消费者仍需能够处理字段增加、消失和类型变化。Teleport 不下线表不代表消费者一定兼容新消息结构。
- DDL 后检查作业事件和目标表结构。发现单表因不支持的演进而下线后,不要直接重启整个作业;先确认源端变化、目标端能力和映射结果,再处理受影响的表。
更完整的原理说明请参见数据同步 Schema Evolution 原理解析。
运行期间的最佳实践
避免多方写入同一目标数据
持续同步期间,尽量避免应用、人工脚本或另一个同步作业同时写入 Teleport 管理的目标数据。多方写入可能产生数据覆盖、唯一键冲突以及源端和目标端不一致。
区分恢复和重启
- 恢复:保留已有同步状态,从暂停位置继续同步。
- 重启:清除已有作业状态并从头开始同步。
临时停机后通常应选择恢复。只有明确需要重新执行全量同步,并且已经评估目标端存量数据处理方式时才使用重启。
不要长时间暂停增量作业
增量作业暂停后,源端仍可能持续产生变更日志。尤其是 PostgreSQL 源端,复制槽可能使 WAL 持续保留并占用磁盘。暂停期间应监控源端日志空间,并尽快恢复或按计划结束作业。
变更配置后重新验证
调整对象范围、映射规则、同步属性、连接信息或目标表结构后,应重新运行预检查,并再次检查最终表映射。配置变更和数据库 DDL 尽量安排在受控变更窗口内完成。
常见问题排查
连接测试失败
按以下顺序检查:
- 地址、端口、Database、用户名和密码是否正确。
- 数据库是否允许远程连接,账户是否被锁定或过期。
- 安全组、防火墙和数据库白名单是否已放行 Teleport。
- 使用 Tunnel 时,Tunnel 状态、路由和目标地址是否正确。
- 源端或目标端是否达到连接数上限。
连接恢复后,重新执行两端连接测试和完整预检查。
多张源表意外写入同一目标表
首先在预检查的表映射列表中确认最终映射,然后从最接近表的节点向上检查映射覆盖关系。常见原因是上级或批量规则把目标表名写成固定常量。
将普通同名同步规则改为:
concat('target_database', '.', 'public', '.', SOURCE_OBJECT)如果作业已经写入数据,应先暂停作业并评估目标端数据,避免直接修改规则后继续写入错误表。
新增表没有自动同步
对于包含增量同步的作业,源端新增表只要落在 includes 或 excludes 定义的同步范围内,就会自动同步。未同步时依次检查:
- 新表所在的 Database 和 Schema 是否在同步范围内。
- 表级使用
includes时,新表名是否命中其中的正则;精确表名不会覆盖其他新表。 - 表级使用
excludes时,新表是否意外命中了排除项。 - 同步账户是否具有读取新表的权限。
- 新表继承到的同步属性和映射规则是否有效,目标对象是否发生冲突。
对于依赖消息 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、失败实例、发生时间、预检查结果和错误信息,以便进一步定位。