xtrabackup是mysql 8.0从节点扩容最快最稳方式,前提是主库已开启gtid且binlog_format=row;mysqldump因逻辑备份慢、gtid连续性难保证、易触发error 1872等问题不适用于大库扩容。

直接用 xtrabackup 全量备份主库再恢复到新节点,是 MySQL 8.0 从节点扩容最快、最稳的方式——前提是主库已开启 GTID 且 binlog_format=ROW,否则复制会卡在 START GROUP_REPLICATION 或 START SLAVE 阶段。
为什么不能用 mysqldump 扩容大库从节点
mysqldump 是逻辑备份,导出的是 SQL 文本。对几百 GB 以上的库,导出耗时长、导入更慢(单线程执行 INSERT),期间主库 mysqldump --single-transaction 仍会持有全局读锁(对非事务表)、占用大量内存和网络带宽;更重要的是,它无法保证 GTID 集的连续性,SET GLOBAL gtid_purged 手动设置极易出错,稍有偏差就会触发 ERROR 1872 (HY000): Slave failed to initialize relay log info structure from the repository。
- 备份文件体积通常是物理备份的 2–3 倍,传输时间不可控
- 恢复后必须手动解析
backup.sql头部的-- CHANGE MASTER TO ...注释,而该注释在 GTID 模式下已被弃用 - 不支持
innodb_redo_log_capacity等 MySQL 8.0 新参数的自动继承,容易启动失败
全量备份主库并流式传到新节点
核心是避免在主库本地落盘大文件,用流式压缩 + SSH 直传,全程不写磁盘、不中断业务。
- 主库执行:
xtrabackup --backup --user=bkpuser --password='xxx' --socket=/var/run/mysqld/mysqld.sock --stream=xbstream --compress --extra-lsndir=/tmp/lsn_info | ssh mysql@new-slave "xbstream -x -C /tmp/full" - 必须加
--extra-lsndir:生成xtrabackup_binlog_info和xtrabackup_galera_info(即使不用 Galera),里面含准确的GTID_EXECUTED值 - 目标节点提前清空
/tmp/full并确保mysql用户对该目录有读写权限;不要用 root 直接恢复,避免权限错乱
新节点恢复前必须做的三件事
很多人跳过这步,结果 mysqld 启动报错 InnoDB: The log file size is different 或复制卡在 Retrieved_Gtid_Set 为空。
- 确认新节点
my.cnf中innodb_log_file_size和主库完全一致(查看主库SHOW VARIABLES LIKE 'innodb_log_file_size');xtrabackup不备份日志文件,必须手动保留或重建 - 解压后执行
xtrabackup --prepare --apply-log-only --target-dir=/tmp/full:MySQL 8.0 要求必须先 prepare 再 copy-back,否则ibdata1校验失败 -
chown -R mysql:mysql /tmp/full后再xtrabackup --copy-back --target-dir=/tmp/full;复制完立刻检查/var/lib/mysql下undo_001、mysql.ibd等文件属主是否为mysql
启动后配置 GTID 复制的关键命令
MySQL 8.0 默认强制 GTID,CHANGE MASTER TO 已被弃用,必须用 SET GLOBAL gtid_purged + START REPLICA(注意不是 START SLAVE)。
- 先
SET SQL_LOG_BIN = 0,再RESET MASTER:清空新节点自己的 binlog,避免与主库 GTID 冲突 - 从
/tmp/full/xtrabackup_binlog_info中提取 GTID,例如内容为mysql-bin.000005 123456 9e8a3b4c-1234-5678-90ab-cdef12345678:1-100,则执行SET GLOBAL gtid_purged = '9e8a3b4c-1234-5678-90ab-cdef12345678:1-100' - 最后
START REPLICA(MySQL 8.0.22+ 语法),不是START SLAVE;检查SHOW REPLICA STATUS\G中Replica_IO_Running和Replica_SQL_Running是否为Yes
最容易被忽略的是:新节点 server_id 必须和集群中所有其他节点不同,且不能为 0 或 1(MySQL 8.0 对 server_id 的校验更严格);一旦重复,IO 线程会拒绝连接主库,错误日志里只显示 Access denied for user 'repl'@'xxx' (using password: YES),实际是 server_id 冲突导致认证被拒。











