快速,持续,稳定,傻瓜式
支持Mysql,Sqlserver数据同步

MySQL同步复制报错处理总结

请联系QQ:1793040 索取软件

A 。删除母版上的记录时发生故障。删除主机上的记录后,由于找不到记录,因此在从机上报告错误。

无法在表\上执行Delete_rows事件lt; database.table_name \ gt ;; “无法在\ lt; table_name \ gt中找到记录,错误代码:1032;处理程序错误HA_ERR_KEY_NOT_FOUND;事件”的主日志mysql-bin.000002,end_log_pos 84718

发生这种情况,因为它已在主机上被删除。为了解决这个问题,您可以使用直接从从站跳过的方法。命令如下:

分为两种:GTID和binlog

A1。跳过GTID副本:

1.停止从属进程

停止从动;

2.设置交易号,该交易号从Retrieved_Gtid_Set
获得

SET @@ SESSION.GTID_NEXT =” 1ffbb886-e3a6-11e2-89fd-18a905565190:7″

3.设置一个空交易

?开始;承诺;

4.恢复交易号

SET SESSION GTID_NEXT = AUTOMATIC;

5.启动从属进程

开始从动;

A2。跳过binlog复制的内容:

停止从属;

设置全局sql_salve_skip_count = 1;启动奴隶;

针对这种情况,我编写了一个skip_deleterows_replication.sh来处理这种情况。脚本如下(我曾经将其直接放在cron中以通过定时任务对其进行检测):

#!/bin/bash

############################################## ###################

##

##该脚本是根据maakit脚本编写的,默认情况下会跳过10次

##

##仅无法在表\上执行Delete_rows事件lt; database.table_name \ gt ;;无法在\ lt; table_name \ gt中找到记录,错误代码:1032;处理程序错误HA_ERR_KEY_NOT_FOUND;该事件的主日志mysql-bin.000002,end_log_pos 84718

##这种情况将被跳过。其他情况需要自己处理,同时丢失数据

##

##作者zxb

############################################## ##################

export LANG = zh_CN

v_dir =/usr/bin/

v_user =根

v_passwd = binbin

v_log =/tmp/日志

v_times = 10

##创建并初始化各种日志目录

如果[-d” $ {v_log}”];然后

?回声” $ {v_log}已经存在。”

其他

? mkdir $ {v_log}

fi

回声”” \> $ {v_log}/slave_status.log

回声”” $ {v_log}/slave_status_error.log

计数= 1

而真实

? Seconds_Behind_Master = $($ {v_dir} mysql-u $ {v_user}-p $ {v_passwd}-e”显示从属状态\\\\ G;” | grep Seconds_Behind_Master | awk-F:” {print $ 2}”)

如果[$ {Seconds_Behind_Master}! =” NULL”];然后

?回声”奴隶没事!”

? $ {v_dir} mysql-u $ {v_user}-p $ {v_passwd}-e”显示从属状态\\\\ G;” \ gt; \ gt; $ {v_log}/slave_status.log

?打破

其他

?回声”” \ gt; $ {v_log}/slave_status_error.log

?日期 \ gt; $ {v_log}/slave_status_error.log

? $ {v_dir} mysql-u $ {v_user}-p $ {v_passwd}-e”显示从属状态\\\\ G;” \ gt; \ gt; $ {v_log}/slave_status_error.log

? $ {v_dir} mysql-u $ {v_user}-p $ {v_passwd}-e”显示从属状态\\\\ G;” | egrep” Delete_rows” \ gt;/dev/null 2 gt; \ 1

?如果[$? = 0];然后

” $ {v_dir} mysql-u $ {v_user}-p $ {v_passwd}-e”停止从服务器;设置全局sql_salve_skip_count = 1;启动从服务器;”

?其他

$ {v_dir} mysql-u $ {v_user}-p $ {v_passwd}-e”启动从站;”

” Last_SQL_Error = $ {v_dir} mysql-u $ {v_user}-p $ {v_passwd}-e”显示从属状态\\\\ G;” | grep-v” Last_SQL_Error_Timestamp” | awk-F:”/Last_SQL_Error/{print $ 2}”

如果[$ {Last_SQL_Error}! =” NULL”];然后

回声”复制是错误,必须手动处理;” ||邮件-s”复制警报” zhangxianbin@onething.net-f zhangxianbin330.pingan.com.cn

其他

回声”可以复制”

打破

? fi

? fi

?让我们数一数++

?如果[$ count-gt $ {v_times}];然后

打破

?其他

$ {v_dir} mysql-u $ {v_user}-p $ {v_passwd}-e”显示从属状态\\\\ G;” \ gt; \ gt; $ {v_log}/slave_status_error.log

睡觉2

继续

? fi

fi

B.主键冲突

当主数据和从数据不一致时,该记录已存在于从数据上,但是我们在主数据库中插入了同一条记录,此时将报告错误。错误信息如下:

无法在表zxb.test上执行Write_rows事件;关键字” PRIMARY”的条目” 29889″重复,错误代码:1062;处理程序错误HA_ERR_FOUND_DUPP_KEY;事件”主日志mysql-bin.000008,end_log_pos 617275634

解决方案:首先检查从站desc bbs.zxb的表结构;详细信息如下:

MySQL \> desc zxb.test;

+——-+———+——+——+———+——-+

|领域类型?? |空|键? |默认值|额外|

+——-+———+——+——+———+——-+

| ID?? | int(11)|没有? | PRI? |空值?? | |

|名称? |字符(5)|是? | |空值?? | |

+——-+———+——+——+———+——-+

检查表的字段信息以获取主键的字段名称。然后删除重复的主键,然后启动slave;没关系

C.记录在主服务器上已更新,但在从属服务器上未找到

解决方案:在主服务器上,使用mysqlbinlog分析错误的binlog日志正在做什么。如果主数据库要更新一条数据,但找不到该数据,则这种情况可能是关闭binlog的派生操作或其他操作。通常我们的方法是:

C1。在主库中找到相应的记录

C2。跳过此操作。设置全局sql_salve_skip_count = 1;

C3。重新启动slave;启动奴隶;

当从站意外关闭时,中继日志可能会损坏。当您再次启动同步复制时,错误消息如下:

Last_SQL_Error:初始化中继日志位置时出错:I/O从二进制日志中读取标头时出错

Last_SQL_Error:初始化中继日志位置时出错:Binlog的魔术号错误;?

它不是可以使用的二进制日志文件吗?此版本的MySQL。

处理方法(两种方法均适用):

1.在my.cnf中添加relay_log_recovery = 1吗?

2.重新配置主从同步:

停止从属;

将master更改为binlog模式的master_log_file =”” master_log_pos =””;-

将MASTER更改为MASTER_HOST =” xxx”,MASTER_USER =” xxx”,Master_Port = xxx,MASTER_PASSWORD =” xxx”,MASTER_AUTO_POSITION = 1;?–gtid模式

启动奴隶;

错误报告如下:

Last_SQL_Error:无法在表ggcond.der_report_num上执行Write_rows事件;关键字” PRIMARY”的条目” 119728″重复,错误代码:1062;处理程序错误HA_ERR_FOUND_DUPP_KEY;事件”主日志mysql-bin.008062,end_log_pos 42041

解决方案:修改相应的表(将myisam表转换为innodb),并直接忽略相应的表操作(临时处理方法)

?复制忽略表= ggcond.der_report_num

设置全局innodb_flush_log_at_trx_commit = 0;

设置全局sync_binlog = 0;

a,innodb_flush_log_at_trx_commit:对于InnoDB引擎是唯一的,ib_logfile的刷新方法(ib_logfile:记录重做日志和撤消日志的信息)

值:0/1/2

innodb_flush_log_at_trx_commit = 0,表示每秒将日志缓冲区刷新到文件系统(os缓冲区),并且调用文件系统的” flush”操作将缓存刷新到磁盘。也就是说,之前的日志一秒钟保存在日志缓冲区(即内存)中,如果计算机出现故障,则可能丢失一秒钟的事务数据。

innodb_flush_log_at_trx_commit = 1表示每次提交事务时,都会将日志缓冲区刷新到文件系统(os缓冲区),并调用文件系统的” flush”操作将缓存刷新到磁盘。在这种情况下,数据库的IO要求非常高。如果底层硬件提供较差的IOPS,则由于硬件IO问题,MySQL数据库的并发性将很快无法改善。

innodb_flush_log_at_trx_commit = 2,这意味着每次提交事务时,日志缓冲区将刷新到文件系统,但不会立即刷新到磁盘。如果仅MySQL数据库挂起,则相应的事务数据不会丢失,因为文件系统没有问题。仅在数据库所在的主机操作系统损坏或突然断电的情况下,数据库的事务数据才可能丢失事务数据,例如1秒。这种好处减少了事务数据丢失的可能性,并且对底层硬件的IO要求不是很高(日志缓冲区被写入文件系统,通常仅从文件系统的内存缓冲区从日志缓冲区内存IO转移到无压力)。

b,sync_binlog

sync_binlog:是MySQL的二进制日志(二进制日志)同步到磁盘的频率。

值:0-N

sync_binlog = 0,提交事务时,MySQL不执行诸如fsync之类的磁盘同步指令,以将binlog_cache中的信息刷新到磁盘,并让Filesystem决定何时进行同步,或在缓存已满后同步至磁盘。这是最好的表现。

sync_binlog = 1,在每次事务提交后,MySQL将执行磁盘同步命令,例如fsync,以将binlog_cache中的数据强制写入磁盘。

sync_binlog = n,每提交n个事务后,MySQL将执行磁盘同步指令,例如fsync,以将binlog_cache中的数据强制写入磁盘。

CHECK TABLE table_name;

设置会话myisam_sort_buffer_size = 256 * 1024 * 1024;

SET SESSION read_buffer_size = 64 * 1024 * 1024;

设置全局myisam_max_sort_file_size = 10 * 1024 * 1024 * 1024;

设置全局repair_cache.key_buffer_size = 128 * 1024 * 1024;

缓存索引tbl_name IN repair_cache;

将索引加载到缓存中tbl_name;

维修台tbl_name;

设置全局repair_cache.key_buffer_size = 0;

这种情况经常出现在之前,它是一个非常大的表(大约100G),因为业务需要删除数据或需要删除此表,然后开发人员实际使用了删除方法,然后进行主从悲剧

此问题有两种情况。如果删除整个表的数据,请使用truncate。

遇到这种问题,让开发人员采用批量提交的方式,平均每2000个数据删除一次,具体代码实现如下:

分隔符$$

使用bigtable $$

删除过程(如果存在)big_table_delete_2k $$

创建过程big_table_delete_5k(在v_id int中)

开始

del_2k:循环:

从bigtable中删除,其中id = v_id限制为2000;

选择row_count()到@count;

如果@ count = 0,则

?选择concat(” bigtable id =”,v_id,” is”,@ count,” rows。”)作为bigtable_delete_finish;

?离开del_2k;

?万一;

?选择睡眠(1);

?结束循环del_2k;

?结束$$

?定界符

如果以后出现上述问题,请使用相关的存储过程,谢谢

sql_exec_mode的常规值很严格,但是slave_exec_mode =” IDEMPOTENT”,以前联系过的同事应该知道。

让我们先谈谈此参数使用的场景,在第一个场景中可以强制跳过该场景。以下情况不适用:

1.使用冥想模式时,手表必须具有主键

2.您无法在DDL上操作DDL,并且没有等待由不同字段长度引起的错误(例如,主机的一个字段为char(20),而备用计算机的为char(10))

设置冥想模式等后,必须重新启动从属,具体代码实现如下:

##########################################

##

## skip_slave_error.sh

##

##作者zxb

##

########################################

#!/bin/bash

v_user =根

v_passwd = binbin

端口= 3306

v_dir =/usr/bin/

v_log =/tmp/日志

##创建并初始化各种日志目录

如果[-d” $ {v_log}”];然后

?回声” $ {v_log}已经存在。”

其他

? mkdir $ {v_log}

fi

用于” cat slaveip.txt”中的hostip

?结果= $($ {v_dir} mysql-u $ {v_user}-p $ {v_passwd}-h $ {hostip}-P $ {port}-e”显示从站状态\\\\ G;” | awk-F:”/slave_SQL_Running/{print $ 2}”)

?如果[” $结果”! =”是”];然后

$ {v_dir} mysql-u $ {v_user}-p $ {v_passwd}-h $ {hostip}-P $ {port}-e”设置全局slave_exec_mode = IDEMPOTENT;”

$ {v_dir} mysql-u $ {v_user}-p $ {v_passwd}-h $ {hostip}-P $ {port}-e”停止从属;启动从属;”

回声”复制错误并跳过” \ gt; $ {v_log}/skip.log |邮件-s”复制警报” zhangxianbin330@pingan.com.cn

? fi

完成

之前遇到过此问题,场景是在库中执行mysql-e”像db.test1一样创建表db.test”的同事,但是还没有从库中写入bin_log。 ,解决方案是将相应的参数替换为plicate-ignore-db = db

分析具体参数,自己检查。

相关推荐

 
QQ在线咨询
售前咨询热线
QQ1793040