本文介绍一个完整的、生产可操作的方案,让你精准获取 MySQL 当前所有 binlog 文件及其“最早可用位点信息”。


🧩 一、查看当前 MySQL 所有未过期的 binlog 文件

登录 MySQL(主库或从库均可):

SHOW BINARY LOGS;

输出示例:

+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000123 |   2456789 |
| mysql-bin.000124 |   3678123 |
| mysql-bin.000125 |   1023987 |
+------------------+-----------+

这意味着:

  • MySQL 当前还保留了从 mysql-bin.000123 开始的所有 binlog;
  • 最早能读到的 binlog 文件是:mysql-bin.000123
  • 如果 Canal 要从最早同步,就应以此文件为起点。

🧱 二、查看最早 binlog 文件的起始位点(position)

每个 binlog 文件的第一个有效事件始终在 position = 4
所以最早位点是:

项目


file

mysql-bin.000123

position

4

👉 Canal 就可以配置为从这里开始。


⚙️ 三、验证这个文件是否还可被读取(防止已部分清理)

可以在 MySQL 客户端中执行:

SHOW BINLOG EVENTS IN 'mysql-bin.000123' LIMIT 5;

如果能返回类似结果:

+---------------+-----+----------------+-----------+-------------+---------------------------------------------+
| Log_name      | Pos | Event_type     | Server_id | End_log_pos | Info                                        |
+---------------+-----+----------------+-----------+-------------+---------------------------------------------+
| mysql-bin.000123 |   4 | Format_desc    |         1 |         123 | Server ver: 8.0.32, Binlog ver: 4          |
| mysql-bin.000123 | 123 | Previous_gtids |         1 |         234 |                                             |
+---------------+-----+----------------+-----------+-------------+---------------------------------------------+

✅ 那就说明该文件仍然可用;
Canal、Flink、DTS等都可以从 position=4 开始正常消费。

如果提示错误:

ERROR 1236 (HY000): Could not find first log file name in binary log index file

说明这个 binlog 已被清理(可能超出 expire_logs_daysbinlog_expire_logs_seconds)。


🧩 四、可直接从命令行检查 binlog 头部(无需登录)

有时我们只想验证文件是否还在,可以直接查看:

ls -lh /var/lib/mysql/mysql-bin.*

或者:

mysqlbinlog --no-defaults --start-position=4 --stop-position=500 /var/lib/mysql/mysql-bin.000123 | head -n 10

输出头几行确认文件有效。


🧠 五、脚本化方案(自动输出最早可同步位点)

如果你要在生产中自动记录 Canal 的安全起点,可以用这段脚本:

#!/bin/bash
# 获取 MySQL 最早未过期 binlog 文件及起始位点

MYSQL_USER="canal"
MYSQL_PWD="your_password"
MYSQL_HOST="127.0.0.1"
MYSQL_PORT=3306

# 获取最早文件
EARLIEST_FILE=$(mysql -u$MYSQL_USER -p$MYSQL_PWD -h$MYSQL_HOST -P$MYSQL_PORT -e "SHOW BINARY LOGS;" | awk 'NR==2 {print $1}')

if [ -z "$EARLIEST_FILE" ]; then
  echo "❌ 未找到任何 binlog 文件,请检查 binlog 是否启用"
  exit 1
fi

# 默认 position=4
POSITION=4

echo "✅ 当前 MySQL 最早可用 binlog 位点:"
echo "  File: $EARLIEST_FILE"
echo "  Position: $POSITION"

执行结果示例:

✅ 当前 MySQL 最早可用 binlog 位点:
  File: mysql-bin.000123
  Position: 4

你可以定期执行这个脚本(比如 Canal 启动前),确保你的 canal.instance.master.journal.name 配置在安全范围内。


🧩 六、拓展:若使用 GTID 模式

如果 MySQL 启用了 GTID(gtid_mode=ON),
那么更推荐从 GTID 集合的最早起点 开始,而不是文件/position。

执行:

SHOW MASTER STATUS;

输出示例:

+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000125 |   456789 |              |                  | 3e1a-xxxx:1-12589 |
+------------------+----------+--------------+------------------+-------------------+

再查看:

SHOW MASTER LOGS;

你就能看到 GTID 对应的最早 binlog 文件。

Canal 配置即可改为:

canal.instance.gtidon = true
canal.instance.master.gtid = 3e1a-xxxx:1

这样即使早期 binlog 文件被清理,只要 GTID 集合连续,Canal 也能继续追踪。


✅ 七、总结

目的

命令

结果

查看所有未过期 binlog 文件

SHOW BINARY LOGS;

确定最早 binlog 文件名

查看最早 binlog 文件起点

默认 position = 4

Canal 从此读取

验证文件可读性

SHOW BINLOG EVENTS IN 'xxx';

能返回说明未清理

自动输出脚本

见上方 bash 脚本

用于 Canal 初始化配置

GTID 模式

SHOW MASTER STATUS;

Canal 可用 GTID 启动


📌 实战建议:

Canal 起点必须 ≥ 当前 MySQL 最早未过期的 binlog 文件位置,否则 Canal 会报错:

ERROR 1236 (HY000): Could not find first log file name in binary log index file

所以 Canal 启动前最好总是先执行 SHOW BINARY LOGS 检查。