说明
mysql 集群部署在 k8s 上,架构是“一主两从”,机房突然断电,导致 mysql 集群启动之后,发生主从同步异常。
主库上查看binlog信息:
mysql> show master status \G;
*************************** 1. row ***************************
File: mysql-0-bin.000365
Position: 499726305
Binlog_Do_DB:
Binlog_Ignore_DB:
Executed_Gtid_Set:
1 row in set (0.00 sec)
ERROR:
No query specified
从库上重新执行主从同步:
mysql> stop slave;
mysql> reset slave;
mysql> change master to master_host='mysql-0.mysql.middle.svc.cluster.local',master_user='root',master_password='f11K40ziyu8Y',master_log_file='mysql-0-bin.000365',master_log_pos=499726305,master_port=3306;
mysql> start slave;
mysql> show slave status \G;
查看主从同步状态,发现同步异常,遇到的报错如下文。
主从同步异常
MySQL 连接出错 mysqladmin flush-hosts
详细信息如下:
Host is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts'.
同一个ip在短时间内产生太多(超过mysql数据库max_connection_errors的最大值)中断的数据库连接而导致的阻塞,抛出mysqladmin flush-host。
这里提供三种方法,我使用的是第二种方法。
方法一:提高允许的max_connect_errors数量
临时处理方法,治标不治本。
临时修改,可使用命令行形式:
## 登入数据库
mysql -h mysql_ip -P mysql_port -uroot -pmysql_passwd
## 查看max_connection_errors
mysql> show variables like '%max_connect_errors%';
## 修改max_connection_errors的数量为1000
mysql> set global max_connect_errors=1000;
## 修改 max_connections 的数量为1000
mysql> set global max_connections = 1000;
命令行修改,只是临时修改,重启MySQL后会失效;如果需要永久生效,需要在my.cnf配置文件中修改。
## 登入数据库
mysql -h mysql_ip -P mysql_port -uroot -pmysql_passwd
## 查看max_connect_errors
mysql> show variables like '%max_connect_errors%';
mysql-connection-error-mysqladmin-flush-hosts-solutions-00
max_connect_errors 默认是10 或 100,修改方法如下:
vim /etc/my.cnf
## 添加一行
max_connect_errors=1000
## 重启MySQL,修改才会生效!
systemctl restart mysqld
mysql-connection-error-mysqladmin-flush-hosts-solutions-01
方法二:命令清理hosts文件
## 直接命令修改flush-hosts
mysqladmin flush-hosts -h mysql_ip -P mysql_port -uroot -pmysql_passwd
说明:配置有master/slave主从数据库的最好把主库和从库都修改一遍~
上面是直接命令行修改,我们也可以登入进 mysql 中修改:
mysql -h mysql_ip -P mysql_port -uroot -pmysql_passwd
mysql> flush hosts;
方法三:重启 mysql
如果是生产环境,不建议重启 mysql 操作。
systemctl restart mysqld
上面提到的方法都是治标不治本的,造成上述故障原因有很多,具体还是要根据自己的实际业务场景进行排查,我这里简单说两点:
*(1)由于程序中创建了过多的mysql连接,通常情况下,程序开始的运行的时候建立与数据库的连接,运行期间进行数据库的一些增删改查操作,程序关闭的时候,断开与数据库的连接。
*(2)部署主从同步这种架构,当集群因某种原因重启后,主从节点同步失败,从节点也会短时间内产生过多的连接,造成阻塞。
从库上记录删除失败,Error_code: 1032
在备库执行同步命令后,使用show slave status \G;
显示下面错误:
Last_Error: Could not execute Update_rows event on table master.connection_alert_contents; Can't find record in 'connection_alert_contents', Error_code: 1032;handler error HA_ERR_KEY_NOT_FOUND; the event's master log master-bin.000067, end_log_pos 1275813
1032错误----现在生产库中好多数据,在从库误删或从库无这条数据,生产库更新后找不到了,现在主从不同步了,再跳过错误也没用,因为没这条,再更新还会报错。
这里提供四种解决方法(我使用的是方法三),不过有的方法需要进一步验证。特别提醒:数据操作有风险,操作前记得先备份数据。
方法一:忽略1032 ERROR报错
貌似作用不大
mysql> set global sql_slave_skip_counter=1;
mysql> stop slave;
mysql> start slave;
也可以在my.cnf
中配置slave-skip-errors=1032
从而跳过日志中1032 ERROR报错,需要重启mysql服务。
方法二:从节点补丢失的数据
如果是主从同步或读写分离架构,从节点可能没有写权限,需要先设置从节点可写。报错信息如下:
1209 - The MySQL server is running with the–read-only option so it cannot execute this statement
查询从库上read_only参数的值,1为只读,0为读写。
mysql> select @@read_only;
mysql> set global read_only=0;
具体方法可参考mysql主从复制中的1032错误。
方法三:备份主库导入从库
这种方法会造成从库数据有丢失
详见mysqldump导入导出,然后再重新开启主从同步。
方法四:重新建从节点
重新部署新的从节点,再开启主从同步。