canal上游数据库迁移方案

canal [kə’næl] 主要用途是基于 MySQL 数据库增量日志解析,提供增量数据订阅和消费。
生产环境中的数据库总会因为各种原因需要迁移,如果这个数据库又是 canal 的上游库,canal 也需要同步修改数据库的相关配置。
如果直接迁移数据库,然后修改 canal 中的数据库配置,会因为与之前数据库的 binlog File、Position 不匹配,导致 canal 报错 can't find start position for example

方案概述

注:本次方案不涉及数据库本身的迁移,只包含与 canal 变更相关的内容。

由于 canal 会记录上游数据库同步的情况,把 binlog File、Position 记录下来,在 Instance 启动时会读取这些记录恢复到上次同步的状态。
所以在迁移上游数据库之前需要修改这些 binlog 信息,具体的迁移步骤如下。

  1. 由于迁移数据库需要修改 binlog position 信息,可能会导致部分消息重复发送,需要确保 canal 的下流消费者有幂等性。
  2. 保证新库已部署完成,并与保持与原库同步。
  3. 查看新库 binlog File、Position。
  4. 停止 canal 对应的实例。
  5. 修改 canal 记录的 binlog position 信息。
  6. 修改 canal 的上游库的配置信息。
  7. 启动 canal 对应的实例。
  8. 验证变更。

迁移方案

查看新库 Binlog position

连接到新的 MySQL 数据库中,执行如下命令查看 binlog 信息。

1
show master status;

会显示如下信息,记录下其中的 File、Position。

1
2
3
4
5
6
7
mysql> show master status;
+------------------+-----------+--------------+------------------+-----------------------------------------------------------------------------------------+
| File             | Position  | Binlog_Do_DB | Binlog_Ignore_DB |Executed_Gtid_Set                                                                       |
+------------------+-----------+--------------+------------------+-----------------------------------------------------------------------------------------+
| mysql-bin.000255 | 226215458 |              |                  | b2d6b3e0-3dd0-11ef-bf73-528c00fbc35b:1-57534559, b2e19ab6-3dd0-11ef-98f0-528c009b3b34:1 |
+------------------+-----------+--------------+------------------+-----------------------------------------------------------------------------------------+
1 row in set (0.03 sec)

停止 canal 实例

这里使用的是 canal admin 进行相关操作,进入到 canal admin 的 Instance 管理界面,找到对应的 instance 并选择操作按钮,然后点击停止
待操作后,可以点击刷新列表按钮查看操作后的状态。

停止 canal 实例

修改 canal position 信息

canal 可以分为 单机部署、集群部署,这两种方式的 position 信息保存的位置是不同的,单机版是保存在本地文件中,集群版是保存在 zookeeper 中,具体路径如下。

单机版:cconf/instance/meta.dat

集群版:/otter/canal/${destinations}/instance/1001/cursor

本次以集群版为例,说明如何修改 zookeeper 中的 position 信息。

  1. 先启动一个 zookeeper 的 docker 容器,并进入容器内,利用 zkCli.sh 来连接并操作 zookeeper 相关数据。
1
docker run --rm --name zk --entrypoint sh -ti zookeeper:latest

注:也可以下载 zookeeper 相关文件在本地操作,zookeeper 官网

  1. 执行如下合集连接并查询当前 canal Instance 的 position 信息。
1
2
./bin/zkCli.sh -server 100.127.9.2:2181
get /otter/canal/destinations/testdb_beijing/1001/cursor

会返回如下信息,其中包含了上游数据库地址、端口、binlog file、binlog position 等信息。

1
{"@type":"com.alibaba.otter.canal.protocol.position.LogPosition","identity":{"slaveId":-1,"sourceAddress":{"address":"100.127.9.2","port":3306}},"postion":{"gtid":"","included":false,"journalName":"mysql-bin.003277","position":100389087,"serverId":1686047208,"timestamp":1722382660000}}
  1. 把新库的 binlog file、binlog position 信息修改后,使用 set 命令修改 zookeeper 中的内容。
1
set /otter/canal/destinations/testdb_beijing/1001/cursor {"@type":"com.alibaba.otter.canal.protocol.position.LogPosition","identity":{"slaveId":-1,"sourceAddress":{"address":"100.127.9.233","port":3306}},"postion":{"gtid":"","included":false,"journalName":"mysql-bin.000255","position":226215458,"serverId":1686047208,"timestamp":1722382660000}}

修改 canal 上游数据库配置

在 canal admin 的 Instance 管理页面中,修改对应 Instance 实例的数据库地址、用户名、密码。

1
2
3
canal.instance.master.address=10.127.9.233:3306
canal.instance.dbUsername=root
canal.instance.dbPassword=root_password

启动 canal 实例

在 canal admin 的 Instance 管理页面中,重新启动对应的实例。

验证变更

  1. 查看 canal Instance 日志是否正常,正常情况下会显示 find start position successfully 并包含新库的 binlog File、Position 等信息。
  2. 查看 canal 下游 MQ、消费者 是否有新的消息送达。

总结

  1. 确认 canal 的部署方式,单机与集群修改 Position 的方式不同。
  2. 因为迁移之后会有部分重复的 binlog 消息,所以需要确保 canal 下游消费者的幂等性,避免影响业务。
  3. 先记录新库 Position ,停止 canal instance,再改 canal Position,避免丢失数据。
  4. 生产环境一定要有严谨的验证和回退方案,需根据实际情况定制。