mysql 5.7→8.0主从复制会静默失败,因5.7 binlog缺失caching_sha2_password握手信息且mysql.user表缺plugin字段,导致seconds_behind_master恒为null;必须配置default_authentication_plugin=mysql_native_password、收紧sql_mode并禁用gtid,或改用debezium+kafka方案。

主从复制直接升级会静默失败,不是延迟高而是根本不同步
START SLAVE 后 Seconds_Behind_Master 一直为 NULL,不是网络或权限问题,而是 5.7 主库 binlog 不携带 caching_sha2_password 握手信息,而 8.0 从库默认要求该插件;同时 5.7 的 mysql.user 表结构缺失 plugin 字段,导致权限变更事件被跳过或解析失败。官方文档写“支持”,但生产实测中基本不可用。
必须改的三项配置才能让主从勉强跑起来
若坚持走原生复制路径,以下配置缺一不可,且顺序不能错:
- 在 5.7 主库
my.cnf的[mysqld]段加:default_authentication_plugin=mysql_native_password,然后重启服务——否则新建用户仍用caching_sha2_password,后续无法同步 - 在 8.0 从库
my.cnf中显式收紧sql_mode:sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION,务必删掉ONLY_FULL_GROUP_BY和已移除的NO_AUTO_CREATE_USER - 5.7 导出初始快照时,必须禁用 GTID:
mysqldump --all-databases --routines --triggers --single-transaction --set-gtid-purged=OFF > init.sql;8.0 导入后立即执行RESET MASTER,否则 GTID 冲突会卡死复制
启动后必须盯住的两个真实状态,不是 SHOW SLAVE STATUS\G 里那两行
SHOW SLAVE STATUS\G 显示 Slave_IO_Running: Yes 且 Slave_SQL_Running: Yes 是假象。真正要确认的是:
-
Seconds_Behind_Master必须是整数(如0),若为NULL,99% 是认证插件不匹配,IO 线程压根没连上 - 翻 8.0 从库错误日志,搜索
Could not execute Write_rows_v1 event on table mysql.user——出现即表明 5.7 的用户表结构被拒绝,此时必须手动删掉从库mysql库下所有非 InnoDB 表(如plugin、servers),再STOP SLAVE; START SLAVE;
比原生复制更稳的方案:Debezium + Kafka 中转
生产环境别硬扛原生复制的兼容性雷区。推荐链路:MySQL 5.7 → Debezium Connector → Kafka → MySQL 8.0 Sink Connector。好处是:
- Debezium 能自动适配 5.7→8.0 的字段类型映射(如
password→authentication_string) - 通过 Kafka 缓冲,可随时暂停/重放/过滤 DDL,避免
ALTER TABLE类语句直接冲击 8.0 - Sink 端可配置
transforms统一转换字符集(强制utf8mb4)、替换废弃函数(如把PASSWORD()替换为SHA2())
最常被忽略的一点是:即使用了 Debezium,也必须在 5.7 主库提前运行 util.checkForServerUpgrade() 扫描保留字冲突(如列名 rank)、utf8mb3 字符集等隐患——这些不会阻断复制,但会在 8.0 写入时报错或丢数据。











