背景

2018年4月24日上午9点左右,小编在即将托管的服务器上建立数据库,并通过openvpn建立加密隧道,从而实现阿里云RDS和本地自建数据库之间同步。在托管服务器上配置openvpn后,重启openvpn客户端时,一直获取不到ip,后面重启了一下openvpn服务端,本地托管服务器获取到了IP,之后小编很开心的配置着MySQL主从同步。但是到11:00左右,有同事反应线上自建数据库无法访问,小编通过查看,发现在阿里云虚拟机上的自建MySQL同步中断,从而导致本地同步也中断,并且已经同步停止了2个小时。为了保证业务的正常运行,小编做了如下操作。

当前数据库同步架构图

记一次阿里云RDS与自建数据库同步中断的补救过程_数据库同步

补救策略
  1. 在RDS上获取gtid点,在从库上从新设置同步点,使从库正常运行起来,保证业务的流畅
  2. 通过解析RDS binlog,把binlog转换成SQL语句,然后把SQL语句插入到从库中
  3. 重新做RDS到自建库的数据同步
  4. 数据库同步架构改进,解决单点问题。
补救过程

1. 先让同步正常运行,保证业务不中断

1. 在RDS上获取gtid节点 

  • 命令 :
 show master status\G
  • 结果 : 
*************************** 1. row ***************************
             File: mysql-bin.000886
         Position: 324398134
     Binlog_Do_DB: 
 Binlog_Ignore_DB: Executed_Gtid_Set: 005304be-d260-11e7-b402-6c92bf475505:1-219538493,759ccfb9-70d0-11e7-b7d5-6c92bf47591d:1-2572999,936b4aea-70d0-11e7-b7d6-6c92bf4757fb:1-132842752,df8f8121-d25f-11e7-b401-6c92bf4757d1:1-44768267共返回 1 行记录,花费 5 ms.

2. 配置从节点过滤主键不存在的错误 编辑 从库配置文件(小编的配置文件为/etc/my.cnf)

slave-skip-errors = 1062,1053,1032

3. 重启数据库 

service mysqld restart

4. 在从节点重新设置同步点 

  • 停止同步
stop slave
  • reset 同步
reset slave all;reset master;
  • 重新设置同步点
set global gtid_purged='005304be-d260-11e7-b402-6c92bf475505:1-219538493,759ccfb9-70d0-11e7-b7d5-6c92bf47591d:1-2572999,936b4aea-70d0-11e7-b7d6-6c92bf4757fb:1-132842752,df8f8121-d25f-11e7-b401-6c92bf4757d1:1-44768267';CHANGE MASTER TO
  MASTER_HOST='xxxxxxxx',
  MASTER_USER='xxxxx',
  MASTER_PASSWORD='xxxxxxxx',
  MASTER_PORT=3306,
  MASTER_AUTO_POSITION=1,
  MASTER_CONNECT_RETRY=10;

5. 启动同步 

start slave

6. 查看同步是否正常 

show slave status\G

2. 弥补数据

由于从库无法通过运行RDS的binlog来修复数据,所以需要解析RDS的binlog,让其转换成SQL语句,然后再在各个从库上执行解析出来的SQL语句,具体流程如下:

1. 下载binlog在阿里云控制台,选择RDS的日志备份,并获取下载地址,在服务器上通过如下命令下载

wget  -c '日志地址' -O xxx.tar.gz

2. 获取某一时间段的binlog并转换成可识别语句

 mysqlbinlog --no-defaults --base64-output=decode-rows -v -v --start-datetime='2018-04-27 08:58:38' --stop-datetime='2018-04-27 11:58:37' mysql-bin.000797 > 797_10_11.txt

3. 使用下列脚本把上面转换后的binlog解析成SQL语句 

  • 脚本binlog_parse_to_sql.py

小编千辛万苦终于找到了一可以把binlog转换成SQL语句的脚本,github地址为:https://github.com/yy1117/binlog_parse_to_sql。但是该脚本直接使用不适合小编的需求,所以小编对代码进行了更改,满足了自己的需求。

#!/usr/bin/python# -*- coding:utf8 -*-#version_1.2#######Comment:######################################################################  Author:GuiJiaoQi&XuYou  MAIL:yinyi1117@126.com;QQ:85531861       ########  set global group_concat_max_len =1024000;避免group_concat  默认长度不够   ########  如果binlog文件的表在后面发生表结果变化,这个解析会报错           ########  如果columns是二进制的解析会报错,如果有二进制的还请换工具,抱歉               #####################################################################################import os,sysimport reimport MySQLdbimport optparsedef main():
        p = optparse.OptionParser()
    p.add_option('-u','--user',type='string',dest='user',default='root',
            help='User for login ')
    p.add_option('-p','--password',type='string',dest='password',
                        help='Password to use when connecting')
        p.add_option('-s','--socket',type='string',dest='socket',
                      help='The socket file to use for connection.')
        p.add_option('-f','--file',type="string",dest='filename',