• Mysql slave 同步错误解决


     涉及知识点

    mysql 主从同步 ,参考: MySQL数据库设置主从同步

    mysqlbin log查看, 参考:MySQL的binlog日志

    解决slave报错, 参考:

     Backup stopped working !! Slave_SQL_Running: No

     mysql数据库binlog日志截断报错,导致mysql主从同步失败故障排查

    slave库失败原因分析、解决,及根据binlog 修改position 手动同步

    问题

    客户反映报表缺少近期的数据。

    分析解决

    master 数据库提供服务,slave数据库作报表服务器,通过mysqlbin log做主从同步。

    从报表数据来看,缺少了从10/28到现在(11/18)之前的数据,比对master、slave数据库主要表数据,发现:

    10/28之后的slave库数据缺失,一致未同步。

    1. 查看slave mysql同步状态:

    关注图中黄色字段:

    Slave_IO_Running: Yes
    Slave_SQL_Running: No --- 表示sql进程未工作,问题就处在这。

    图中粉色背景,Last_Error: ....

    'Duplicate entry '1169595' for key 'PRIMARY'' on query. Default database: ''. Query: 'insert into  user。。。

    这个错误很简单,违反主键唯一约束。

    2. mysql 错误日志 通过my.conf 确定出错误日志文件,vi 查看,根据日志151028搜索到以下:

    从日志中,看到10/28 1:28:55 mysql 非正常关闭; 1:29 重启后,开始recovery。 1:29:16s 后I/O errror; 1:30:19s SQL error, slave SQL thread aborted(停止工作)。

    mysql也给出了解决办法:

    Fix the problem, and restart the slave SQL thread with "SLAVE START". We stopped at log 'mysql-bin.000274' position 504869752

    重启,并告诉sql 执行的binlog 文件设置position, 重启slave. 错误仍存在,如下

    mysql> CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000274',MASTER_LOG_POS=504873114;
    ERROR 1198 (HY000): This operation cannot be performed with a running slave; run STOP SLAVE first
    mysql> stop slave;
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000274',MASTER_LOG_POS=504873114;
    Query OK, 0 rows affected (1.98 sec)
    
    mysql> start slave;
    Query OK, 0 rows affected (0.00 sec)
    mysql> show slave statusG
    *************************** 1. row ***************************
                   Slave_IO_State: Waiting for master to send event
                      Master_Host: 172.17.128.15
                      Master_User: cns
                      Master_Port: 3306
                    Connect_Retry: 60
                  Master_Log_File: mysql-bin.000281
              Read_Master_Log_Pos: 361947072
                   Relay_Log_File: app3-relay-bin.000002
                    Relay_Log_Pos: 253
            Relay_Master_Log_File: mysql-bin.000274
                 Slave_IO_Running: Yes
                Slave_SQL_Running: No
    View Code

    错误原因仍是

    Last_SQL_Error: Error 'Duplicate entry '1169595' for key 'PRIMARY'' on query. Default database: ''. Query: 'insert into user (type,lang,ipAddr,activityStatus,extUserId,endpoint,createTime, email, userName, mobile, storageSize, tuner
    )values ('normal','zh-xx','xxxx','active','913151000777430','xxx',now(),null,null,null,0,0)'

    至此看来,虽然找到问题原因必须解决以上这个问题。 进一步了解mysql 同步机制及bin log, 原理:slave 获取master的binlog, 并执行,执行报错说明数据库已有这条记录,可能原因是日志中的position不准确,只能从binlog入手分析,

    binlog查看参考: MySQL的binlog日志

    这里通过第二种方式查看:

     mysql> show binlog events [IN 'log_name'] [FROM pos] [LIMIT [offset,] row_count];
    
                 选项解析:
                   IN 'log_name'   指定要查询的binlog文件名(不指定就是第一个binlog文件)
                   FROM pos        指定从哪个pos起始点开始查起(不指定就是从整个文件首个pos点开始算)
                   LIMIT [offset,] 偏移量(不指定就是0)
                   row_count       查询总条数(不指定就是所有行)

    log_name, pos 错误日志已知道,查询如下:

    binlog 包括所有数据库操作的sql,每条记录包含1个数据库操作。

    在bin log 中,很容易找到出错的语句,现在问题是:找到slave SQL线程执行到哪个position. 这里只能采用最笨的办法,根据sql 语句,查看slave库中的数据,如:

    Query | 1 | 504873619 | replace into content_preference(userId,contentId,playRecordId,status,createTime)
    values (587658,15308,1544691,0,now())

    此sql语句为向content_preference 插入一条记录,那么在salve库中content_preference 表中确定是否有id=587658,contentId=15308的记录,如果有,表示此语句已执行。

    一直向下查找,最终找到没有执行的sql 的记录, 找到position。

    至此,可以判断出slave库中执行binlog 的position, 重新设定slave库的binlog position ,启动slave, 查看执行状态,running, 见下:

    mysql> stop slave;
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000274',MASTER_LOG_POS=504873114;
    Query OK, 0 rows affected (1.98 sec)
    
    mysql> start slave;
    Query OK, 0 rows affected (0.00 sec)
    
    
    mysql> show slave statusG
    *************************** 1. row ***************************
                   Slave_IO_State: Queueing master event to the relay log
                      Master_Host: 172.17.128.15
                      Master_User: xxx
                      Master_Port: 3306
                    Connect_Retry: 60
                  Master_Log_File: mysql-bin.000274
              Read_Master_Log_Pos: 693913486
                   Relay_Log_File: app3-relay-bin.000002
                    Relay_Log_Pos: 1819098
            Relay_Master_Log_File: mysql-bin.000274
                 Slave_IO_Running: Yes
                Slave_SQL_Running: Yes

    在备份执行完毕后,报表导出数据正常,问题解决。

    反思

     mysql在11/28日重启,原因是当天线上服务出现异常,无法解决,重启了机器,当时没考虑到报表数据库也在此机器上,重启后也未检查数据库备份情况,直到用户使用才发现问题。

    mysql意外重启,虽然在下次重启启动后,记录了异常信息,和备份的binlog 日志文件及位置。如果是正在执行binlog SQL,但此时mysql意外关闭,记录的position 较旧,导致下次启动时,

    会有部分binlog 日志重复执行导致。 此问题,不能说是mysql bug,这种机制,可以保证slave数据不至于丢失,但需要人工找到posion,即可。

    后续:

    1. 对于机器重启情况, 可手动执行stop slave.  在正常关闭mysql, 重启后,手动start slave, 应该就可以正常同步。

    2. 线上系统,重启一定要小心, 重启后监控相关模块是否启动,可以增加mysql slave工作监控。

  • 相关阅读:
    Effective C++第三遍
    SQL基础教程
    hibernate 数据关联多对多
    hibernate 数据关联一对一
    hibernate 数据关联一对多
    hibernate Criteria查询
    hibernate HQL查询
    hibernate 持久化对象的生命周期
    hibernate的配置
    微博登录
  • 原文地址:https://www.cnblogs.com/qdpurple/p/4975595.html
Copyright © 2020-2023  润新知