【Day 35】Linux-主从复制的维护
一、主、从库故障
(一) 从库宕机恢复机制
从库重启后会自动读取复制信息并连接主库继续同步:
- >SELECT * FROM slave_master_info\G; // 查看主库连接信息
- >SELECT * FROM slave_relay_log_info\G; // 查看中继日志信息
(二)主从复制故障处理
1、 IO 线程故障排查
示例 1:Access denied for user 'repl'@'从库IP' → 主库给从库的复制账号密码错误,需重新在主库授权并更新从库配置。
①SELECT user, host, replication_slave_priv FROM mysql.user WHERE user = 'repl';
- CREATE USER 'repl'@'从库IP' IDENTIFIED BY '你的密码';
- GRANT REPLICATION SLAVE ON *.* TO 'repl'@'从库IP';
- FLUSH PRIVILEGES;
②SHOW SLAVE STATUS\G //确认Master_User
是 'repl',Master_Host
是主库 IP,且密码正确。
- STOP SLAVE;
- CHANGE MASTER TO MASTER_HOST='主库IP', MASTER_USER='repl', MASTER_PASSWORD='你的密码', MASTER_LOG_FILE='主库当前日志文件', MASTER_LOG_POS=主库当前日志位置; START SLAVE;
示例 2:Can't connect to MySQL server on '主库IP' (113) → 主从网络不通,检查防火墙、主库绑定地址(bind-address 是否允许从库访问)。
① ping 主库ip
② 防火墙:二选其一
③ traceroute 主库IP //检查网络路由
④ 验证主库 MySQL 服务状态
- systemctl status mysql // 检查服务状态
- netstat -tulpn | grep 3306 //确认MySQL监听地址,确保 MySQL 监听所有地址(0.0.0.0)
⑤ grep bind-address /etc/my.cnf //bind-address = 0.0.0.0,并重启
⑥检查 SELinux 设置
- getenforce //# 查看SELinux状态 ,
- setenforce 0 //临时关闭,如果关闭后可以连接,需要配置 SELinux 允许 MySQL 网络连接
2、 SQL 线程故障排查
示例 1:Duplicate entry '123' for key 'PRIMARY' → 主从数据不一致,从库已有相同主键 / 唯一键的数据,与主库同步过来的记录冲突。可能是从库手动写入了数据,或主从数据初始不一致。需手动同步不一致的数据后重启复制。
- STOP SLAVE SQL_THREAD; //跳过当前错误(仅临时应急,生产慎用)
- SET GLOBAL sql_slave_skip_counter = 1; //跳过1个事务
- START SLAVE SQL_THREAD;
示例 2:Table 'test.t1' doesn't exist → 主库有表 test.t1 但从库没有,需先在从库创建相同表结构。
- SHOW CREATE TABLE 库名.表名; //主库导出表结构
- ALTER TABLE 库名.表名 ...; //从库执行相同的表结构变更语句,与主库保持一致
- START SLAVE SQL_THREAD; //重启 SQL 线程
示例3:
二、主从角色切换
(一)常规
0、准备阶段:锁定原主库(防止数据写入)
- FLUSH TABLES WITH READ LOCK; //在原主库执行 全局只读锁,禁止写入
- SHOW MASTER STATUS; //此时记录的 binlog 位置是旧主库的 “最终数据节点”
1、将原从库提升为新主库
① 确认从库数据与旧主库完全一致
- >SHOW MASTER STATUS;
- >SHOW SLAVE STATUS\G //确认原从库数据完整性,此语句仅用于从库查询自身复制状态
①Seconds_Behind_Master = 0 ;
②Relay_Master_Log_File 和 Read_Master_Log_Pos 与上文原主库执行结果一致。
② 停止复制并清除旧主库关联
- >STOP SLAVE; //停止复制线程
- >RESET SLAVE ALL; // 清除主服务器连接信息
// 逻辑上应先切断与旧主库的关联,再确认自身的 binlog 位置。
③ 获取旧主库的binlog位置,作为新主库的binlog起点
- SHOW MASTER STATUS; //记录新主库 binlog 位置
- // 新主库(原从库)停止复制并清除旧配置后,会以 “主库” 身份开始生成自己的 binlog(之前作为从库时可能未开启或使用不同的 binlog 序列)。此时记录的 binlog 位置是新主库的 “初始数据节点”(从这一刻起,新主库的写入会记录到自己的 binlog 中)。旧主库后续降为从库时,必须通过
CHANGE MASTER TO
指向这个位置,才能从新主库的最新状态开始同步(否则会同步旧数据或报错)。
④修改只读配置,重启mysql
- # sed -i '/read_only/d' /etc/my.cnf //移除只读配置
- # sed -i '/super_read_only/d' /etc/my.cnf
- # sed -i 's/#log_bin/log_bin/' /etc/my.cnf // 确保新主库开启binlog
- # systemctl restart mysqld
⑤ 检查
- >SHOW VARIABLES LIKE 'read_only'; // 应显示OFF
- >SHOW VARIABLES LIKE 'super_read_only'; // 应显示OFF
- >SHOW VARIABLES LIKE 'log_bin'; //确认ON(binlog已开启)
2、切换业务连接到新主
① 修改应用配置指向新主库
- # vim wp-config.php //修改应用配置,修改为新主库
② 在新主库创建应用用户(与旧主库权限一致)
- CREATE USER IF NOT EXISTS 'xxxxx'@'应用服务器IP' IDENTIFIED BY '密码';
- GRANT ALL ON blog.* TO 'xxxxx'@'应用服务器IP';
- FLUSH PRIVILEGES;
- //修改后测试应用是否能正常连接新主库,确保读写正常。
3、原主库修复后作为从库连接新主
① 解锁原主库(若业务已完全切换,可解锁允许临时读取)
- >UNLOCK TABLES;
② 清理原主库的旧复制信息(若该 “原主库” 在当前主从架构调整前,曾经作为过 “从库” )
- >STOP SLAVE; //停止复制线程
- >RESET SLAVE ALL; // 清除旧的主从配置
③ 在新主库创建复制用户(若不存在)
- CREATE USER IF NOT EXISTS 'xxx'@'原主库IP' IDENTIFIED WITH mysql_native_password BY '密码';
- GRANT REPLICATION SLAVE ON *.* TO 'xxx'@'原主库IP';
- FLUSH PRIVILEGES;
④ 原主库配置同步新主库
//注意,posotion是数字,(无需引号)
4、在新从库上验证同步状态
- >SHOW SLAVE STATUS\G
① Slave_IO_Running = Yes
② Slave_SQL_Running = Yes
③ Seconds_Behind_Master = 0(无延迟)
(二)主从切换(基于 GTID 的快速切换)
1、在新主库(原从库)执行:
- STOP SLAVE; //停止原复制线程
- RESET SLAVE ALL; //清除旧主库信息
- SET GLOBAL read_only = OFF; // 解除只读,允许业务写入
- SET GLOBAL super_read_only = OFF;
2、在其他从库(如原主库修复后)执行:
- >CHANGE MASTER TO MASTER_HOST = '新主库IP', MASTER_USER = '复制用户名', MASTER_PASSWORD = '密码', MASTER_AUTO_POSITION = 1;
- >START SLAVE;