位置: 编程技术 - 正文
推荐整理分享线上MYSQL同步报错故障处理方法总结(必看篇),希望有所帮助,仅作参考,欢迎阅读内容。
文章相关热门搜索词:,内容如对您有帮助,希望把文章链接给更多的朋友!
前言
在发生故障切换后,经常遇到的问题就是同步报错,数据库很小的时候,dump完再导入很简单就处理好了,但线上的数据库都G-G,如果用单纯的这种方法,成本太高,故经过一段时间的摸索,总结了几种处理方法。
生产环境架构图
目前现网的架构,保存着两份数据,通过异步复制做的高可用集群,两台机器提供对外服务。在发生故障时,切换到slave上,并将其变成master,坏掉的机器反向同步新的master,在处理故障时,遇到最多的就是主从报错。下面是我收录下来的报错信息。
常见错误
最常见的3种情况
这3种情况是在HA切换时,由于是异步复制,且sync_binlog=0,会造成一小部分binlog没接收完导致同步报错。
第一种:在master上删除一条记录,而slave上找不到。
Last_SQL_Error: Could not execute Delete_rows event on table hcy.t1; Can't find record in 't1', Error_code: ; handler error HA_ERR_KEY_NOT_FOUND; the event's master log mysql-bin., end_log_pos
第二种:主键重复。在slave已经有该记录,又在master上插入了同一条记录。
Last_SQL_Error: Could not execute Write_rows event on table hcy.t1; Duplicate entry '2' for key 'PRIMARY', Error_code: ; handler error HA_ERR_FOUND_DUPP_KEY; the event's master log mysql-bin., end_log_pos
第三种:在master上更新一条记录,而slave上找不到,丢失了数据。
Last_SQL_Error: Could not execute Update_rows event on table hcy.t1;Can't find record in 't1', Error_code: ; handler error HA_ERR_KEY_NOT_FOUND; the event's master log mysql-bin., end_log_pos
异步半同步区别
异步复制简单的说就是master把binlog发送过去,不管slave是否接收完,也不管是否执行完,这一动作就结束了.
半同步复制简单的说就是master把binlog发送过去,slave确认接收完,但不管它是否执行完,给master一个信号我这边收到了,这一动作就结束了。(谷歌写的代码,5.5上正式应用。)
异步的劣势当master上写操作繁忙时,当前POS点例如是,而slave上IO_THREAD线程接收过来的是3,此时master宕机,会造成相差7个点未传送到slave上而数据丢失。
特殊的情况
slave的中继日志relay-bin损坏。Last_SQL_Error: Error initializing relay log position: I/O error reading the header from the binary logLast_SQL_Error: Error initializing relay log position: Binlog has bad magic number; It's not a binary log file that can be used by this version of MySQL
这种情况SLAVE在宕机,或者非法关机,例如电源故障、主板烧了等,造成中继日志损坏,同步停掉。
人为失误需谨慎:多台slave存在重复server-id这种情况同步会一直延时,永远也同步不完,error错误日志里一直出现上面两行信息。解决方法就是把server-id改成不一致即可。
Slave: received end packet from server, apparent master shutdown:Slave I/O thread: Failed reading log event, reconnecting to retry, log 'mysql-bin.' at postion
问题处理
删除失败
在master上删除一条记录,而slave上找不到。
Last_SQL_Error: Could not execute Delete_rows event on table hcy.t1; Can't find record in 't1',Error_code: ; handler error HA_ERR_KEY_NOT_FOUND; the event's master log mysql-bin., end_log_pos
解决方法:
由于master要删除一条记录,而slave上找不到故报错,这种情况主上都将其删除了,那么从机可以直接跳过。可用命令:
stop slave;set global sql_slave_skip_counter=1;start slave;
如果这种情况很多,可用我写的一个脚本skip_error_replcation.sh,默认跳过个错误(只针对这种情况才跳,其他情况输出错误结果,等待处理),这个脚本是参考maakit工具包的mk-slave-restart原理用shell写的,功能上定义了一些自己的东西,不是无论什么错误都一律跳过。)
主键重复
在slave已经有该记录,又在master上插入了同一条记录。
解决方法:
在slave上用desc hcy.t1; 先看下表结构:
删除重复的主键
在master上和slave上再分别确认一下。
更新丢失
在master上更新一条记录,而slave上找不到,丢失了数据。
解决方法:
在master上,用mysqlbinlog 分析下出错的binlog日志在干什么。
在slave上,查找下更新后的那条记录,应该是不存在的。
mysql> select * from t1 where id=2;Empty set (0. sec)
然后再到master查看
把丢失的数据在slave上填补,然后跳过报错即可。
中继日志损坏
slave的中继日志relay-bin损坏。
手工修复
解决方法:找到同步的binlog和POS点,然后重新做同步,这样就可以有新的中继日值了。
例子:
Slave_IO_Running :接收master的binlog信息
Master_Log_File Read_Master_Log_Pos
Slave_SQL_Running:执行写操作
Relay_Master_Log_File Exec_Master_Log_Pos
以执行写的binlog和POS点为准。
各种大招都用上了,无奈slave数据丢失过多,ibbackup(需要银子)该你登场了。
Ibbackup热备份工具,是付费的。xtrabackup是免费的,功能上一样。
Ibbackup备份期间不锁表,备份时开启一个事务(相当于做一个快照),然后会记录一个点,之后数据的更改保存在ibbackup_logfile文件里,恢复时把ibbackup_logfile 变化的数据再写入到ibdata里。
Ibbackup 只备份数据( ibdata、.ibd ),表结构.frm不备份。
下面一个演示例子:
备份:ibbackup /bak/etc/my_local.cnf /bak/etc/my_bak.cnf
恢复:ibbackup --apply-log /bak/etc/my_bak.cnf
把ibdata1 ib_logfile0 ib_logfile1拷贝到从,把.frm也拷贝过去,启动MySQL后,做同步,那个点就是上面输出的:
ibbackup: Last MySQL binlog file position 0 , file name ./mysql-bin.CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.',MASTER_LOG_POS=;
Maatkit工具包 yum install perl-DBI。
如果表数据不一致,CHECKSUM的值是不相等的。
解释下输出的意思:
DATABASE:数据库名TABLE:表名CHUNK:checksum时的近似数值HOST:MYSQL的地址ENGINE:表引擎COUNT:表的行数CHECKSUM:校验值TIME:所用时间WAIT:等待时间STAT:MASTER_POS_WAIT()返回值LAG:slave的延时时间
如果你想过滤出不相等的都有哪些表,可以用mk-checksum-filter这个工具,只要在后面加个管道符就行了。
知道有哪些表不一致,可以用mk-table-sync这个工具来处理。
注:在执行mk-table-checksum时会锁表,表的大小取决于执行的快慢。
MASTER上的t2表数据:
SLAVE上的t2表数据:
它的工作原理是:先一行一行检查主从库的表是否一样,如果哪里不一样,就执行删除,更新,插入等操作,使其达到一致。表的大小决定着执行的快慢。
MySQL复制监控
MySQL常见错误类型
:创建表失败:创建数据库失败:数据库已存在,创建数据库失败:数据库不存在,删除数据库失败:不能删除数据库文件导致删除数据库失败:不能删除数据目录导致删除数据库失败:删除数据库文件失败:不能读取系统表中的记录:记录已被其他用户修改:硬盘剩余空间不足,请加大硬盘可用空间:关键字重复,更改记录失败:关闭时发生错误:读文件错误:更改名字时发生错误:写文件错误:记录不存在:数据表是只读的,不能对它进行修改:系统内存不足,请重启数据库或重启服务器:用于排序的内存不足,请增大排序缓冲区:已到达数据库的最大连接数,请加大数据库可用连接数:系统内存不足:无效的主机名:无效连接:当前用户没有访问数据库的权限:不能连接数据库,用户名或密码错误:字段不能为空:数据库不存在:数据表已存在:数据表不存在:字段不存在:无效的SQL语句,SQL语句为空:不能建立Socket连接:数据表已满,不能容纳任何记录:打开的数据表太多:数据库出现异常,请重启数据库:连接数据库失败,没有连接数据库的权限:数据库用户不存在:当前用户无权访问数据库:当前用户无权访问数据表:当前用户无权访问数据表中的字段:数据表不存在:未定义用户对数据表的访问权限:SQL语句语法错误:网络错误,出现读错误,请检查网络连接状况:网络错误,读超时,请检查网络连接状况:网络错误,出现写错误,请检查网络连接状况:网络错误,写超时,请检查网络连接状况:字段值重复,入库失败:字段值重复,更新记录失败:打开数据表失败:提交事务失败:回滚事务失败:当前用户和数据库建立的连接已到达数据库的最大连接数,请增大可用的数据库连接数或重启数据库:加锁超时:当前用户没有创建用户的权限:外键约束检查失败,更新子表记录失败:外键约束检查失败,删除或修改主表记录失败:当前用户使用的资源已超过所允许的资源,请重启数据库或重启服务器:权限不足,您无权进行此操作:MySQL版本过低,不具有本功能
复制监控脚本
参考原文修改。
原脚本
修改后脚本
只做了简单的整理,修正了Behind为NULL的判断,但均未测试;
应可考虑增加:
对修复执行结果的判断;多条错误的循环修复、检测、再修复?
取消SlaveStatusFile临时文件。
Errno、Behind两种告警分别发邮件,告警正文增加show slave结果原文。
增加PATH,以便加到crontab中。
考虑crontab中周期执行(加锁避免执行冲突、执行周期选择)
增加执行日志?
以上这篇线上MYSQL同步报错故障处理方法总结(必看篇)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持积木网。
浅谈innodb_autoinc_lock_mode的表现形式和选值参考方法 前提条件,percona5.6版本,事务隔离级别为RRmysqlshowcreatetabletest_autoinc_lockG***************************1.row***************************Table:test_autoinc_lockCreateTable:CREATETABL
MySQL几点重要的性能指标计算和优化方法总结 1QPS计算(每秒查询数)针对MyISAM引擎为主的DBMySQLshowGLOBALstatuslike'questions';+---------------+------------+|Variable_name|Value|+---------------+------------+|Questions||+---
解决mac使用homebrew安装MySQL无法登陆问题 如果你电脑是Mac的,使用homebrew安装MySQL是一个非常便捷的方式,但是还是会出现一些问题;首先保证你已经安装了mysql,如果是通过homebrew安装的,输入my
友情链接: 武汉网站建设