如何监控主从状态
$ mysql -S /tmp/mysql3308.sock -e "show slave status \G" Slave_IO_Running: Yes # IO线程工作状态:YES、NO、Connecting Slave_SQL_Running: Yes # SQL线程工作状态:YES、NO Last_IO_Errno: 0 # IO故障代码:2003,1045,1040,1593,1236 Last_IO_Error: # IO线程报错详细信息 Last_SQL_Errno: 0 # SQL故障代码:1008,1007 Last_SQL_Error: # IO线程报错详细信息
IO线程故障
连接主库失败 user,password,IP,Port,plugin 主库无法连接:网络、宕机、防护墙、最大连接数上限
故障模拟:
(1)主库宕机 systemctl stop mysqld3307 show slave status\G 还原: systemctl start mysqld3307 mysql -S /tmp/mysql3308.sock -e "start slave;" (2) 模拟用户密码错误 mysql -S /tmp/mysql3307.sock -e "alter user repl@'10.0.0.%' identified by '11212'" mysql -S /tmp/mysql3308.sock -e "start slave; show slave status\G " 还原: mysql -S /tmp/mysql3307.sock -e "alter user repl@'10.0.0.%' identified by '123'" mysql -S /tmp/mysql3308.sock -e "start slave; show slave status\G " (3) 连接数上限 mysql -S /tmp/mysql3307.sock -e " set global max_connections=2;" mysql -S /tmp/mysql3307.sock mysql -S /tmp/mysql3307.sock mysql -S /tmp/mysql3308.sock -e "stop slave; start slave; show slave status\G " 还原: mysql -S /tmp/mysql3307.sock -e " set global max_connections=200;" mysql -S /tmp/mysql3308.sock -e "stop slave; start slave; show slave status\G "
排查方法:
$ mysql -urepl -p123 -h 10.0.0.51 -P 3300 mysql: [Warning] Using a password on the command line interface can be insecure. ERROR 2003 (HY000): Can't connect to MySQL server on '10.0.0.51' (111) $ mysql -urepl -p123 -h 10.0.0.52 -P 3307 mysql: [Warning] Using a password on the command line interface can be insecure. ERROR 2003 (HY000): Can't connect to MySQL server on '10.0.0.52' (113) $ mysql -urepla -p123 -h 10.0.0.51 -P 3307 mysql: [Warning] Using a password on the command line interface can be insecure. ERROR 1045 (28000): Access denied for user 'repla'@'db01' (using password: YES) $ mysql -urepl -p1123 -h 10.0.0.51 -P 3307 mysql: [Warning] Using a password on the command line interface can be insecure. ERROR 1045 (28000): Access denied for user 'repl'@'db01' (using password: YES)
请求日志
主库日志损坏、缺失。 主从的server_id、Server_uuid相同。
server_id 故障重现:
$ mysql -S /tmp/mysql3307.sock mysql> set global server_id=8; $ mysql -S /tmp/mysql3307.sock mysql> select @@server_id; $ mysql -S /tmp/mysql3308.sock mysql> stop slave;start slave;show slave status;
回退:
$ mysql -S /tmp/mysql3307.sock mysql> set global server_id=7; $ mysql -S /tmp/mysql3307.sock mysql> select @@server_id; $ mysql -S /tmp/mysql3308.sock mysql> start slave;show slave status;
主库日志损坏故障重现:
$ mysql -S /tmp/mysql3307.sock mysql> reset master; $ mysql -S /tmp/mysql3308.sock mysql> start slave;show slave status; 测试环境处理方法(主从的数据当前是一致的): $ mysql -S /tmp/mysql3308.sock # 将所有线程停止。 mysql> stop slave; # 将从库复制信息清空(master.info,relay-log.info清空,show slave status看不到信息了) mysql> reset slave all; mysql> CHANGE MASTER TO MASTER_HOST='10.0.0.51', MASTER_USER='repl', MASTER_PASSWORD='123', MASTER_PORT=3307, MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=154, MASTER_CONNECT_RETRY=10; mysql> start slave;
生产中需要额外考虑什么情景?
需要重构主从: 1. 备份恢复. 2. change master to ; start slave
SQL线程故障
SQL线程主要工作:回放relaylog中的日志事件,可以理解为后台执行SQL语句
1. realy-log 损坏。 处理方法: 重构。 方法1: 备份主库+change master to + start slave; 方法2: 找到问题点+ change master + start slave; 思路: 如何找到问题位置点。 1. 找到SQL已经回放到什么位置了。 SQL回放的realylog位置点,对应的主库binlog的位置点(relay-log.info) Relay_Log_File: db01-relay-bin.000006 Relay_Log_Pos: 320 ----》 2. 找到主库相应位置点: Relay_Master_Log_File: mysql-bin.000001 Exec_Master_Log_Pos: 600 3. change master to mysql-bin.000001 600 2. 执行SQL出问题? (1)主从节点配置不一样: 平台、版本、参数、SQL_MODE 调整成一致。 (2)修改的对象不存在(库、表、用户) 从库被写入了。 双主架构。异步方式主从,导致数据不一致。 (3)创建的对象已存在(库、表、用户、约束冲突) 从库被写入了。 双主架构。 方法一:部分场景可以使用,只要保证数据以主库为准即可使用。 stop slave; set global sql_slave_skip_counter = 1; #将同步指针向下移动一个,如果多次不同步,可以重复操作。 start slave; 方法二:不推荐 /etc/my.cnf slave-skip-errors = 1032,1062,1007
常见错误代码:
1007:对象已存在
1032:无法执行DML
1062:主键冲突,或约束冲突
总结:SQL线程故障规避方法
1. 从库只读 ,读写分离中间件。 2. 不使用双主结构。PXC、MGR替代。 3. 半同步、增强半同步复制等,或者PXC、MGR替代。