从库的I/O线程处于Connection连接中的状态,一般都是连接不上主库导致:
产生Connecting状态大多数情况下,都是复制用户不存在,或者密码不对,导致连不上主库,可以在从库服务器中使用mysql命令登录复制用户,观察是否能到登录成功,如果登录不上,就表示是复制用户的问题,导致I/O线程处于Connecting状态。
从库的I/O线程处于No状态,可能是以下原因导致:
下面模拟主库Binlog日志损坏,从库无法请求指定的Binlog,从而导致I/O线程处于No故障状态以及恢复处理过程。+
1)主库破坏Binlog日志
1.多刷新几次产生新的Binlog
mysql> flush logs;
mysql> flush logs;
mysql> flush logs;
当主库刷新Binlog日志后,从库也会跟着请求到最新的Binlog日志。
2.主库破坏Binlog
mysql> reset master;
2)从库的I/O线程处于No状态
从库的状态I/O线程立马变成No状态,从库要请求00004Binlog日志,但是主库的只有00001Binlog日志,没有从库要找的00004Binlog日志,此时就会处于No状态。
并且会报错说从库要请求mysql-bin.000004
二进制日志,但是主库只有mysql-bin.000001
二进制日志,没有从库要请求的日志,因此I/O会报错。
Got fatal error 1236 from master when reading data from binary log: 'could not find next log; the first event 'mysql-bin.000001' at 452, the last event read from './mysql-bin.000004' at 194, the last byte read from './mysql-bin.000004' at 194.'
3)此时主库又产生了新的操作
此时主库又发生了新的操作,创建了一个db_test库,而从库现在没法复制这些数据。
mysql> create database db_test;
4)处理方法
I/O状态目前处于No的状态,我们已经知道原因了,就是从库要请求主库的Binlog日志不对,我们调整一下请求的Binlog日志,然后指定Binlog标识位号为从库I/O线程故障时的标识位号,保证主从的数据同步。
mysql> stop slave;
mysql> reset slave all;
mysql> CHANGE MASTER TO
MASTER_HOST='192.168.20.11',
MASTER_USER='replicas',
MASTER_PASSWORD='123456',
MASTER_PORT=3306,
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=154,
MASTER_CONNECT_RETRY=10;
mysql> start slave;
主库重新生成了新的Binlog日志,并且也产生了数据,我们不好确定从库故障时,主库的Binlog位置号,因此我们直接从154号开始同步,一定是最全的数据,重新配置主从同步信息,Binlog指对之后,从库的I/O状态正常。
SQL线程主要是读取relay-log.info获取relay-log的位置号,然后执行relay-log中主库推送来的Binlog日志,然后再更新relay-log.info文件。
当SQL线程状态为No,主库发送来的Binlog日志,从库无法执行,从而导致数据不同步。
导致SQL线程处于No状态的原因:
如果真的有人在从库中写入了数据,SQL线程故障了,状态为No,并且写入的数据是无关紧要的,可以通过以下命令,跳过失败的SQL,使SQL线程恢复正常。
stop slave;
set global sql_slave_skip_counter = 1;
也可以修改配置文件,将可能在从库误操作导致SQL无法执行的几种错误号,配置在配置文件中,全部跳过,但是不合理。
vim /etc/my.cnf
slave-skip-errors = 1032,1062,1007
最合理的避免人员在从库误写入数据的方法,就是给从库设置为只读模式,或者配置读写分离,通过中间件,将写的操作写入到主库,读的操作写入到从库。