✅ 一、目标
我们要修改 Canal 的实例配置文件conf/example/instance.properties
(或你自定义的 conf/<instance_name>/instance.properties
)
确保它正确对应:
- MySQL 当前最早的 binlog 文件名
- 该文件的第一个事件的实际 position(非 4)
🧩 二、确认 MySQL 当前最早 binlog 文件及起始 position
执行以下 SQL:
SHOW BINARY LOGS;
假设返回:
+------------------+-----------+
| Log_name | File_size |
+------------------+-----------+
| mysql-bin.000123 | 1073741824 |
| mysql-bin.000124 | 987654321 |
| mysql-bin.000125 | 123456789 |
+------------------+-----------+
最早的 binlog 文件是:
mysql-bin.000123
接着查看它的起始 position:
SHOW BINLOG EVENTS IN 'mysql-bin.000123' LIMIT 5;
可能输出:
+------------------+-----+-------------------+-----------+-------------+--------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------------+-----+-------------------+-----------+-------------+--------------------------+
| mysql-bin.000123 | 154 | Format_desc | 1 | 278 | Server ver: 8.0.32 ... |
| mysql-bin.000123 | 278 | Previous_gtids | 1 | 389 | |
+------------------+-----+-------------------+-----------+-------------+--------------------------+
🔹说明:
该文件的起始事件 position = 154
(不是默认的 4)
⚙️ 三、修改 Canal 配置
找到你的 Canal 实例配置文件,例如:
conf/example/instance.properties
修改以下部分👇:
# MySQL 连接配置
canal.instance.master.address = 127.0.0.1:3306
canal.instance.dbUsername = canal
canal.instance.dbPassword = canal_password
canal.instance.connectionCharset = UTF-8
canal.instance.enableDruid = true
# ==========================
# binlog 启动位置配置
# ==========================
# 当前最早的 binlog 文件名
canal.instance.master.journal.name = mysql-bin.000123
# 对应 SHOW BINLOG EVENTS 查到的第一个事件 position
canal.instance.master.position = 154
# 可选,指定时间戳(毫秒),通常可留空或0
canal.instance.master.timestamp = 0
# 开启 GTID 模式可忽略 position 配置(如果启用了 MySQL GTID)
# canal.instance.gtidon = true
# canal.instance.master.gtid = <your-gtid>
🧱 四、Canal 启动后行为验证
启动 Canal:
sh bin/startup.sh
查看日志:
tail -f logs/example/example.log
应看到:
INFO c.a.o.canal.parse.inbound.mysql.MysqlEventParser - start to dump from position:
mysql-bin.000123:154
然后继续:
INFO c.a.o.canal.parse.inbound.mysql.MysqlEventParser - rotate to new binlog file mysql-bin.000124
✅ 表示 Canal 已成功从 000123:154 启动并自动追踪后续文件。
🧩 五、自动同步 Doris(全量 + 增量)
在保证 Canal 启动正确后,你通常会结合以下组件做同步:
阶段 | 工具 | 说明 |
全量 |
| 一次性导入历史数据 |
增量 |
| 持续实时同步 |
在增量同步阶段,Canal 的精确位点控制非常关键,
否则容易造成:
- 漏数据(起点太晚)
- 重复数据(起点过早)
- 同步中断(文件不存在)
💡 六、附:自动获取最早 binlog 文件和 position(脚本方式)
你也可以写一个简单的 SQL + Shell 脚本,让 Canal 自动配置:
#!/bin/bash
mysql_host="127.0.0.1"
mysql_user="root"
mysql_pass="password"
# 获取最早的 binlog 文件名
file=$(mysql -h$mysql_host -u$mysql_user -p$mysql_pass -e "SHOW BINARY LOGS;" | awk 'NR==2{print $1}')
# 获取该文件的第一个事件 position
pos=$(mysql -h$mysql_host -u$mysql_user -p$mysql_pass -e "SHOW BINLOG EVENTS IN '$file' LIMIT 1;" | awk 'NR==2{print $2}')
# 修改 Canal 配置文件
sed -i "s#^canal.instance.master.journal.name=.*#canal.instance.master.journal.name=$file#g" conf/example/instance.properties
sed -i "s#^canal.instance.master.position=.*#canal.instance.master.position=$pos#g" conf/example/instance.properties
echo "✅ 已更新 Canal 启动位点为 $file:$pos"
运行后,Canal 就能始终从当前最早有效 binlog 启动,避免“文件已清理”的错误。
🧾 总结
项目 | 正确做法 |
确认 MySQL 最早 binlog 文件名 |
|
获取其起始 position |
|
修改 Canal 启动位点 |
|
Canal 自动衔接后续 binlog | ✅ 会自动根据 RotateEvent 继续同步 |
不要固定写 4 | ❌ 除非是 binlog.000001 |
可用脚本自动更新 | 👍 推荐生产化使用 |