• [MySQL复制] SQL_ERROR 1032解决办法(non-gtid env)


    一、缘由:

      在主主同步的测试环境,由于业务侧没有遵循同一时间只写一个点的原则,造成A库上删除了一条数据,B库上在同时更新这条数据。

    由于异步和网络延时,B的更新event先到达A端执行,造成A端找不到这条记录,故SQL_THREAD报错1032,主从同步停止。

    二、错误说明:

      MySQL主从同步的1032错误,一般是指要更改的数据不存在,SQL_THREAD提取的日志无法应用故报错,造成同步失败

    (Update、Delete、Insert一条已经delete的数据)。

      1032的错误本身对数据一致性没什么影响,影响最大的是造成了同步失败、同步停止。

      如果主主(主从)有同步失败,要第一时间查看并着手解决。因为不同步,会造成读取数据的不一致。应在第一时间恢复同步,

    尽量减少对业务的影响。然后再具体分析不同步的原因,手动或者自动修复数据,并做pt-table-checksum数据一致性检查。

      目前业务一般是做主主同步,主主同步由于是异步更新,存在更新冲突的问题,且很容易引起SQL ERROR 1032错误。这个应该在业务侧解决,

    保证同一时间只更新数据库的一个点,类似单点写入。我们的解决办法是:写一个底层数据库调用库,可能涉及到更新冲突的操作,都调用这个库。

    在配置文件里,配2个点的数据库A、B,保证一直都更新A库,如果A库不可用,就去更新B库。

      另外,如果是对数据一致性要求较高的场景,比如涉及到钱,建议用PXC(强一致性、真正同步复制)。

    三、解决办法:

      MySQL5.6.30版本,binlog模式为ROW。

      show slave statusG,可以看到如下报错:

    Slave_SQL_Running: NO
    Last_SQL_Errno: 1032 Last_SQL_Error: Worker 3 failed executing transaction '' at master log mysql-bin.000003, end_log_pos 440267874;          Could not execute Delete_rows event on table db_test.tbuservcbgolog; Can't find record in 'tbuservcbgolog', Error_code: 1032;          handler error HA_ERR_KEY_NOT_FOUND; the event's master log mysql-bin.000003, end_log_pos 440267874

      从上可以看出,是SQL_THREAD线程出错,错误号码1032。是在应用delete db_test.tbuservcbgolog 表中一行数据的事件时,由于这条数据

    不存在而出错。此事件在主服务器Master binlog中的位置是 mysql-bin.000003, end_log_pos 440267874。(当然可以在从服务器Slave的Relay

    log中查找,具体方法见最后) 

    方法1:跳过错误Event

    先跳过这一条错误(event),让主从同步恢复正常。(或者N条event,一条一条跳过)

      stop slave;

      set global sql_slave_skip_counter=1;

      start slave;

    方法2:跳过所有1032错误

    更改my.cnf文件,在Replication settings下添加:

      slave-skip-errors = 1032

    并重启数据库,然后start salve。

    注意:因为要重启数据库,不推荐,除非错误事件太多。

    方法3:还原被删除的数据

    根据错误提示信息,用mysqlbinlog找到该条数据event SQL并逆向手动执行。如delete 改成insert。

    本例中,此事件在主服务器Master binlog中的位置是 mysql-bin.000003, end_log_pos 440267874。

    1)利用mysqlbinlog工具找出440267874的事件

    /usr/local/mysql-5.6.30/bin/mysqlbinlog --base64-output=decode-rows -vv mysql-bin.000003 |grep -A 20 '440267874'

    或者/usr/local/mysql-5.6.30/bin/mysqlbinlog --base64-output=decode-rows -vv mysql-bin.000003 --stop-position=440267874 | tail -20

    或者usr/local/mysql-5.6.30/bin/mysqlbinlog --base64-output=decode-rows -vv mysql-bin.000003 > decode.log 

    ( 或者加上参数-d, --database=name 来进一步过滤)

     
    #160923 20:01:27 server id 1223307  end_log_pos 440267874 CRC32 0x134b2cbc      Delete_rows: table id 319 flags: STMT_END_F
    ### DELETE FROM `db_99ducj`.`tbuservcbgolog`
    ### WHERE
    ###   @1=10561502 /* INT meta=0 nullable=0 is_null=0 */
    ###   @2=1683955 /* INT meta=0 nullable=0 is_null=0 */
    ###   @3=90003 /* INT meta=0 nullable=0 is_null=0 */
    ###   @4=0 /* INT meta=0 nullable=0 is_null=0 */
    ###   @5='2016-09-23 17:02:24' /* DATETIME(0) meta=0 nullable=1 is_null=0 */
    ###   @6=NULL /* DATETIME(0) meta=0 nullable=1 is_null=1 */
    # at 440267874
     

    以上为检索出来的结果,事务语句为:delete from db_99ducj.tbuservcbgolog where @1=10561502 and @2=1683955 ...

    其中@1 @2 @3...分别对应表tbuservcbgolog的列名,填补上即可。

    我们可以逆向此SQL 将deleter 变成Insert,手动在从库上执行此Insert SQL,之后restart slave就好了。

  • 相关阅读:
    springboot + websocket + qpid问题记录
    学习开源项目guns遇到的问题记录
    CSS选择器和jQuery选择器学习总结
    (深入.Net平台的软件系统分层开发).第一章.上机练习.20170424
    (深入.Net平台和C#编程)第九章.上机练习.20170417
    (深入.Net平台和C#编程)第八章.上机练习(网络电视精灵).20170415
    (深入.Net平台和C#编程)第十章.课程总复习.20170413
    (深入.Net平台和C#编程)第七章.上机练习.20170412
    (深入.Net平台和C#编程)第六章.简答题5.20170410
    (深入.Net平台和C#编程)第六章.简答题3.20170410
  • 原文地址:https://www.cnblogs.com/DataArt/p/10227786.html
Copyright © 2020-2023  润新知