本文目录导读:

在没有备份的情况下重建 MySQL 从库(Slave),核心思路是:利用主库(Master)当前的二进制日志(binlog)和数据文件,创建一个与主库某个时间点完全一致的副本,由于没有现成的备份文件,你需要直接从正在运行的主库获取数据。
这通常有两种主要方法,取决于你的环境、表大小和允许的停机时间。
核心前提与风险警告
- 主库必须开启 binlog:这是最基本的,如果没有开启,此方法无效。
- 主库必须处于可读状态:你需要在主库上执行 FLUSH TABLES WITH READ LOCK(或使用其他无锁方式)来获取一致性的数据快照。
- 锁表影响:使用
FLUSH TABLES WITH READ LOCK会短暂阻塞主库的写入操作(通常几秒到几十秒),对于大表或高并发系统,这可能导致主库短暂不可写。 - 风险等级:比从备份恢复更高,如果操作失误,可能导致主库数据损坏或从库数据不一致。
使用 mysqldump(最常用、最通用,适合中小型数据量)
mysqldump 可以创建主库的逻辑备份,并在备份文件中记录当前的 binlog 位置(文件名和偏移量)。
步骤:
-
在主库上执行备份并记录 binlog 位置:
mysqldump -u root -p \ --single-transaction \ # 对于 InnoDB,使用事务快照,避免长时间锁表(-single-transaction 会自动设置 RR 隔离级别,不需要加 -lock-tables) --master-data=2 \ # 关键参数!在备份文件中以注释形式记录 CHANGE MASTER TO... --all-databases \ # 备份所有库;如果只重建特定从库,也可以指定 --databases db1 db2 --routines \ # 备份存储过程和函数 --events \ # 备份事件调度器 --triggers \ # 备份触发器 > /tmp/slave_backup.sql
- 为什么用
--master-data=2而不是=1? 因为=2会以注释形式记录 binlog 信息,不会直接执行CHANGE MASTER语句,让你可以手动复制,如果是=1,它会输出一个未注释的CHANGE MASTER语句,如果直接导入到新实例可能会意外执行。
- 为什么用
-
查看备份文件中的 binlog 位置:
grep -i "CHANGE MASTER" /tmp/slave_backup.sql
你会看到类似:
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000123', MASTER_LOG_POS=456789;
记下这两个值。
-
将备份文件传输到从库服务器:
scp /tmp/slave_backup.sql slave_server:/tmp/
-
在从库上执行恢复:
-- 登录从库 MySQL mysql -u root -p < /tmp/slave_backup.sql -- 或者进入 MySQL 后 source mysql> source /tmp/slave_backup.sql;
-
配置并启动从库复制:
-- 1. 设置主库信息(使用上面记下的位置) mysql> CHANGE MASTER TO MASTER_HOST='master_ip_or_hostname', MASTER_USER='replication_user', MASTER_PASSWORD='replication_password', MASTER_LOG_FILE='mysql-bin.000123', -- 从 step 2 获取 MASTER_LOG_POS=456789; -- 从 step 2 获取 -- 2. 启动从库 mysql> START SLAVE; -- 3. 检查状态 mysql> SHOW SLAVE STATUS\G; -- 检查 Slave_IO_Running: Yes 和 Slave_SQL_Running: Yes -- Seconds_Behind_Master: 0 (或接近 0)
使用 xtrabackup(适合大数据库,几乎无锁)
Percona XtraBackup 是物理备份工具,备份速度快,无需长时间锁表(非 InnoDB 表仍需短暂锁),它也能自动记录 binlog 位置。
步骤:
-
在主库上使用
xtrabackup执行备份:xtrabackup --backup \ --user=root \ --password=your_password \ --target-dir=/tmp/full_backup/
-
准备备份(让备份数据保持一致):
xtrabackup --prepare \ --target-dir=/tmp/full_backup/
-
查看备份中的 binlog 位置:
cat /tmp/full_backup/xtrabackup_binlog_info
你会看到:
mysql-bin.000123 456789 -
将备份目录传输到从库服务器。(注意:复制后可能需要检查目录权限)
-
在从库上执行恢复:
# 停止 MySQL 服务(从库) systemctl stop mysql # 确认从库上的 datadir 目录是空的(或备份原有数据) # 将备份数据恢复到 datadir xtrabackup --copy-back \ --target-dir=/tmp/full_backup/ \ --datadir=/var/lib/mysql # 设置正确的目录权限 chown -R mysql:mysql /var/lib/mysql # 启动 MySQL 服务 systemctl start mysql
-
配置并启动从库复制(步骤和方法一完全一致,但使用此方法记录的 binlog 位置)
关键检查与问题排查
-
权限问题:
- 主库上的复制用户必须存在且拥有
REPLICATION SLAVE权限。 - 从库连接主库时,防火墙必须放行 3306 端口(或自定义端口)。
- 主库上的复制用户必须存在且拥有
-
GTID 模式:
- 如果你使用了 GTID(Global Transaction Identifiers),上述方法同样适用,但
CHANGE MASTER需要改为:CHANGE MASTER TO MASTER_AUTO_POSITION=1;
并且不需要指定
MASTER_LOG_FILE和MASTER_LOG_POS,备份时也需要确认 GTID 的一致性(mysqldump的--set-gtid-purged或xtrabackup会自动处理)。
- 如果你使用了 GTID(Global Transaction Identifiers),上述方法同样适用,但
-
主从版本一致性:建议主从版本完全一致(特别是大版本,如 MySQL 5.7 和 8.0),版本不匹配可能导致复制中断或数据不一致。
-
数据库过滤:
- 如果从库只复制部分数据库(通过
replicate-do-db或replicate-ignore-db配置),mysqldump时请只导出相关库,避免无用数据和潜在的冲突。
- 如果从库只复制部分数据库(通过
-
数据一致性校验:启动复制后,使用
checksum table或pt-table-checksum(Percona Toolkit)验证主从数据是否完全一致。
没有备份时的最佳实践
| 方法 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
mysqldump |
数据库 < 50GB,单表 < 10GB,允许短暂锁表(InnoDB 可使用 --single-transaction 避免) |
通用性强,无需安装额外工具,备份文件可读 | 速度慢,对大数据库恢复时间长 |
xtrabackup |
数据库 > 50GB,或不允许长时间阻塞主库写入 | 极快,几乎无锁,支持在线热备 | 需要安装 Percona XtraBackup 工具,恢复步骤稍多 |
强烈建议: 在没有备份的情况下重建从库,最佳实践是 先为主库创建一个备份,从库重建完成后,立即将这个“重建过程”作为你正式备份策略的一部分,定期(如每天)执行全量备份和增量备份,否则一旦主库出现硬件故障,你将面临数据丢失风险。