MySQL主从延迟复制实践及生产故障案例恢复实践

1.1

MySQL主从延迟复制介绍

从MySQL5.6开始支持了主从延迟复制,这个功能主要解决的问题是,当主库有逻辑的数据删除或错误更新后,所有的从库都会进行错误的更新,从而导致所有的数据库数据异常,即使有定时的备份数据可以用于数据恢复,特别是数据库数据量很大时,恢复时间会很长,再恢复期间数据库数据被删或错误数据影响正常的访问体验。

而延迟复制就可以较好的解决这个问题。例如,可以设定某一个从库和主库的更新延迟1小时,这样主库数据出问题以后,1个小时以内发现,可以对这个从库进行无害恢复处理,使之依然是正确的完整的数据,省去了数据恢复占用的时间,用户体验有所增加。

1.2

MySQL主从延迟复制配置实践

MySQL5.6版本的延迟复制配置,是通过在Slave上执行以下命令实现的:

CHANGE MASTER TO MASTER_DELAY = N;   
#读者可在配置延迟从库Change Master时直接加上MASTER_DELAY选项。

该语句设置Slave数据库延时N秒后,再与主数据库进行数据复制,具体操作为登录到Slave数据库服务器(本文是52) ,然后执行如下命令。

mysql> stop slave;

Query OK, 0 rows affected (0.45 sec)

mysql> CHANGE MASTER TO MASTER_DELAY = 20; 

#这是延迟的核心命令。

Query OK, 0 rows affected (0.22 sec)

mysql> start slave;

Query OK, 0 rows affected (0.15 sec)

mysql> show slave status\G

*************************** 1. row ***************************

...省略若干...

Slave_IO_Running: Yes

Slave_SQL_Running: Yes

...省略若干...

SQL_Delay: 20

#这里的数字就是设置的延迟20秒后进行复制。

SQL_Remaining_Delay: NULL

#还剩多少秒执行复制。

Slave_SQL_Running_State: Slavexx to update it

#SQL线程的状态。

...省略若干...

1 row in set (0.09 sec)

复制状态里常用的三个状态参数为SQL_Delay、SQL_Remaining_Delay、Slave_SQL_Running_State,说明上面已分别注释了。

主库插入数据:

mysql> create database lanlan;

Query OK, 1 row affected (0.00 sec)

主库插入完数据1秒以后,从库执行show databases;查看数据是否及时同步了,结果如下:

mysql> show databases;

+--------------------+

| Database           |

+--------------------+

| information_schema |

| alex_python        |

| mysql              |

| performance_schema |

+--------------------+

在从库上并没有看到在主库上创建的数据库lanlan,此时执行间歇性的执行show slave status\G查看延迟的参数状态如下输出。

mysql> show slave status\G

...省略若干...

SQL_Delay: 20

SQL_Remaining_Delay: 13

#剩于13秒执行复制。

Slave_SQL_Running_State: Waiting until MASTER_DELAY seconds after master executed event

...省略若干...

1 row in set (0.00 sec)

mysql> show slave status\G

...省略若干...

SQL_Delay: 20

SQL_Remaining_Delay: 9

#剩于9秒执行复制。

Slave_SQL_Running_State: Waiting until MASTER_DELAY seconds after master executed event

...省略若干...

1 row in set (0.00 sec)

mysql> show slave status\G

...省略若干...

SQL_Delay: 20

SQL_Remaining_Delay: NULL

#复制完成后,没有新数据更新的状态。

Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it

...省略若干...

1 row in set (0.00 sec)

在从库没有更新数据处于延迟复制没到时间期间,查看从库的中继日志。

[[email protected] data]# pwd

/application/mysql/data

[[email protected] data]# mysqlbinlog db02-relay-bin.000002

SET @@session.lc_time_names=0/*!*/;

SET @@session.collation_database=DEFAULT/*!*/;

create database lanlan

#中继日志确已经有了创建的语句,说明IO线程还是实时在工作的。

1.3

MySQL延迟复制原理解析

MySQL的延迟复制实际上影响的只是SQL线程将数据应用到从数据库,而I/O线程早已经把主库更新的数据写入到了从库的中继日志中,因此,在延迟复制期间即使主库宕机了,从库到了延迟复制的时间,依然会把数据更新到和主库宕机时一致。

特别提示:其实MySQL的延迟复制的功能早在几年前,老男孩老师就已经用思想实现了这个功能, 并应用于企业生产备份和恢复中了,方法如下:

1)15.2节已经介绍过的,执行mysql> stop slave sql_thread;把SQL线程停掉,然后进行备份,备份期间主库宕机,但是主库的Binlog依然会及时发到从库,最终从库依然可以恢复到和主库宕机前的状态。

2)写一个脚本,利用定时任务控制sql_thread的停止和运行,进而库就可以控制实现简单的从库延迟复制功能了,这就是思想的重要性。当然了5.6版本就用软件提供的功能吧,5.6以前的数据库要想实现延迟复制,可以思考下老男孩曾经用过的延迟备份以及延迟复制的思路。

1.4  MySQL延迟复制恢复案例实践

在企业中,我们要根据业务需求给延迟复制指定一个时间段,例如1个小时后进行该从库复制,那么在这一个小时内,如果主库误更新了数据,那么其他的从库也都傻傻地误更新了数据,如何将这个延迟的从库恢复正常没有误更新数据前的完整状态呢?且看下文的实践。

1.4.1  将从库延迟调整为1小时

模拟环境,将从库延迟调整为3600秒;

mysql> stop slave;

Query OK, 0 rows affected (0.00 sec)

mysql> CHANGE MASTER TO MASTER_DELAY = 3600;

Query OK, 0 rows affected (0.03 sec)

mysql> start slave;

Query OK, 0 rows affected (0.08 sec)

mysql> show slave status\G

...省略若干...

SQL_Delay: 3600

SQL_Remaining_Delay: 2414

Slave_SQL_Running_State: Waiting until MASTER_DELAY seconds after master executed event

...省略若干...

1 row in set (0.00 sec)

1.4.2   模拟在主库写入数据

每隔5秒写入1个库,就当模拟用户写入数据了。

[[email protected] ~]# for n in {1..5}

> do

>     mysql -e "create database oldboy$n"

>     sleep 5

> done

提示:Shell脚本知识可参考《跟老男孩学习Linux运维:Shell编程实战》一书。

1.4.3   模拟人为破坏数据

模拟人为破坏数据也可以是不带where的update语句。

mysql> drop database oldboy5;   

#删除oldboy5数据库,后面就是把这个数据恢复回来,别的数据还得有。

Query OK, 0 rows affected (0.00 sec)

mysql> show databases like ‘oldboy%‘;

+--------------------+

| Database (oldboy%) |

+--------------------+

| oldboy1            |

| oldboy2            |

| oldboy3            |

| oldboy4            |

+--------------------+

4 rows in set (0.00 sec)

#此时,所有的从库都已经是坏数据了,只有延迟从库是好的,但是是一小时前的数据。

1.4.4 停止写库恢复数据

当数据库出现误删数据情况时,要想完整恢复数据(特别是update不加条件破坏数据),最好选择对外停止访问措施,需要牺牲用户体验,除非业务可以忍受数据不一致,并且不被二次破坏。从库可以适当继续开放给用户读访问,但是也可能会导致用户读到的数据是坏的数据,需要读者去衡量数据一致性和用户体验的问题。本例使用iptables封堵用户对主库的所有访问。

[[email protected] ~]# iptables -I INPUT -p tcp --dport 3306 ! -s 172.16.1.51 -j DROP 

#非172.16.1.51禁止访问数据库3306端口,51是主库IP。

1.4.5 检查Binlog发送和接收是否完成

登录主库执行show processlist;对Binlog是否全部发送到该延迟从库进行确认,当然了,也可以登录延迟从库执行show processlist;对从库IO线程是否接收完全部Binlog进行状态查询确认。

mysql> show processlist;

+----+---------------------------------------+---------------+

| 12 | rep  | 172.16.1.52:39043 | NULL | Binlog Dump |  709 | Master has sent all binlog to slave; waiting for binlog to be updated | NULL             |

+----+------------------------------------+------------------+

2 rows in set (0.00 sec)

#上述提示表示主库已经发送完所有Binlog日志到从库了。

1.4.6  从库暂停主从复制,并检查数据

从库上执行stop slave;暂停主从复制,并查看数据库是否同步过来。

mysql> stop slave;

mysql> show databases;

+--------------------+

| Database           |

+--------------------+

| information_schema |

| alex_python        |

| mysql              |

| performance_schema |

+--------------------+

4 rows in set (0.00 sec)

#提示:因为延迟时间还未到,因此数据不会同步到该延迟从库。

1.4.7

定位恢复数据对应中继日志

根据relay-log.info记录的SQL线程读取relay-log的的位置解析未应用到从库的relay-bin日志。

[[email protected] data]# pwd           

#进入到中继日志所在的目录。

/application/mysql/data

[[email protected] data]# ls -l *relay* 

#查看中继日志相关信息。

-rw-rw----. 1 mysql mysql 172 9月  13 17:32 db02-relay-bin.000001

-rw-rw----. 1 mysql mysql 993 9月  13 17:37 db02-relay-bin.000002

-rw-rw----. 1 mysql mysql  48 9月  13 17:32 db02-relay-bin.index

-rw-rw----. 1 mysql mysql  61 9月  13 17:32 relay-log.info

#SQL线程读取中继日志位置信息。

[[email protected] data]# cat relay-log.info  

#查看中继日志应用的位置信息。

7

./db02-relay-bin.000002  #SQL线程读取中继日志的文件名信息。

284                      #SQL线程读取中继日志位置点信息。

oldboy-bin.000024

309

3600

0

1

1.4.8

解析需要的中继日志

解析SQL线程未解析的全部剩余relay-bin中继日志数据,由于模拟数据量不够大,因此本例里只有db02-relay-bin.000002一个中继日志,实际工作中可能有多个,一并解析到一个指定文件或者分不同的文件存放也可。

[[email protected] data]# mysqlbinlog --start-position=284 db02-relay-bin.000002 >relay.sql 

#根据上述的relay-log.info的中级日志文件和位置信息进行解析中继日志,此命令的用法前面章节已经讲解过了,此不累述。

1.4.9

从解析文件中删除问题SQL

将破坏数据库数据的SQL语句找到并从已解析的SQL语句中删除,这里就是“drop database oldboy5”。

[[email protected] data]# egrep "drop database oldboy5" relay.sql   

#检查是否存在误删的SQL语句。

drop database oldboy5

[[email protected] data]# sed -i ‘/drop database oldboy5/d‘ relay.sql 

#删除,注意别删多了。

[[email protected] data]# egrep "^drop database oldboy5" relay.sql   

#检查删除结果。

1.4.10

将处理好的SQL文件恢复到数据库

将解析后并处理好的relay.sql数据文件恢复到延迟从库。

[[email protected] data]# mysql<relay.sql   

#这步就是从停止slave复制开始,根据relay-log.info位置手工将剩下的所有日志数据恢复到数据库中,需要注意就是提前要清理破坏数据库的语句,在恢复。

[[email protected] data]# mysql -e "show databases like ‘oldboy%‘;"

+--------------------+

| Database (oldboy%) |

+--------------------+

| oldboy1            |

| oldboy2            |

| oldboy3            |

| oldboy4            |

| oldboy5            |   #被删除的oldboy5数据库已经找回。

+--------------------+

到此,利用延迟数据库恢复数据完毕,将此库提升为主库(见手工实现主从角色切换章节内容),将VIP指向该“延迟从库”,即新主库提供用户访问,然后,在对其他的破坏的主从数据库进行修复。

时间: 2024-10-10 11:53:52

MySQL主从延迟复制实践及生产故障案例恢复实践的相关文章

专职DBA-MySQL主从延迟复制

专职DBA-MySQL主从延迟复制 本次实验环境延用MySQL主从异步复制的搭建环境 mysql集群企业级架构方案 1.根据对数据库的访问请求实现读写分离(读从写主) 2.根据不同的业务拆分多个从库以提供访问 一主五从 3从提供外部用户读请求访问(读写分离.LVS负载均衡) 1从用于内部用户读访问(业务后台.数据分析.搜索业务.财务统计.定时任务.开发查询等) 1从用于数据库定时全备份,以及增量备份(开启binlog) 3.实现对主库的高可用 (1).heartbeat+dbrd+mysql方案

MySQL 主从延迟复制方法总结

mysql 5.6开始已经支持主从延迟复制,可设置从库延迟的时间.延迟复制的意义在于:主库误删除对象时,在从库可以查询对象没改变前状态. 方法介绍 1.percona公司pt-slave-delay工具 主库: [[email protected] ~]$ login Logging to file '/tmp/master.log' Warning: Using a password on the command line interface can be insecure. Welcome

实时刷新缓存-处理mysql主从延迟的一些设计方案

概要: 在项目开发当中,经常有这样一种场景,对数据库进行添加.修改.删除操作的应用直接连接master库,只对数据库进行查询的应用,会先建立一个中央缓 存,例如redis或者memcache,如果缓存没有命中,那么直接访问slave库.下文会介绍一下在刷新中央缓存时,如果发生主从延迟,应该如何处 理.也即是,当应用System-A 把数据库写入master库的时候,System-B应用在读取slave库的时候,master库的数据还没同步到slave库,如果这个时候刷新缓存 的话,会直接把旧的数

MySQL主从延时复制

MySQL的主从复制是实现MySQL大规模集群的基础,其在日常生产环境中被广泛的被应用,而在MySQL5.6开始对MySQL的底层代码不断的重构完善后在MySQL的主从复制取得极大的进步,且在5.7版本引入主从多线程复制(http://blog.51cto.com/jim123/1961241),而在5.6版本开始MySQL的主从复制就支持slave上延时复制master而不需要借助第三方工具实现,主从复制延时可以在master误删除数据后在slave中延时一定时间后快速找回误删除数据,至于设置

MySQL 主从延迟几万秒 Queueing master event to the relay log(转)

数据库版本Server version:    5.6.24-log Source distribution 问题描述 数据采集平台业务数据库由于批量灌数据导致主从延迟上万秒. 复制线程长期处于Queueing master event to the relay log状态. 监控数据显示1.Seconds_Behind_Master 维持在6w秒左右,且有上升趋势.2.主库有大量的binlog积压无法同步到从库,但主从库的网卡流量都很低远未达到瓶颈.3.从库的qps与tps很低,维持在几百左右

MySQL主从延迟现象及原理分析详解

一.现象 凌晨对线上一张表添加索引,表数据量太大(1亿+数据,数据量50G以上),造成主从延迟几个小时,各个依赖从库的系统无法查询数据,最终影响业务. 现在就梳理下主从延迟的原理. 二.原理 根据 MySQL 官方文档 MySQL Replication Implementation Details 中的描述,MySQL 主从复制依赖于三个线程:一个线程(),两个线程(和).主从复制流程如下图: master 服务器和 slave 服务器连接时,创建以发送数据: 一个对应一个 slave 服务器

mysql主从数据库复制

Mysql内建的复制功能是构建大型,高性能应用程序的基础.将Mysql的数据分布到多个系统上去,这种分布的机制,是通过将Mysql的某一台主机的数据复制到其它主机(slaves)上,并重新执行一遍来实现的.复制过程中一个服务器充当主服务器,而一个或多个其它服务器充当从服务器.主服务器将更新写入二进制日志文件,并维护文件的一个索引以跟踪日志循环.这些日志可以记录发送到从服务器的更新.当一个从服务器连接主服务器时,它通知主服务器从服务器在日志中读取的最后一次成功更新的位置.从服务器接收从那时起发生的

mysql 主从的复制的原理及操作步骤

数据库读法约定: 主库: master 从库: slave mysql 主从同步的原理: #主从是异步模式,且是由从库找主库进行同步: 1.主库开启IO线程:    开启binlog: #binlog记录用户的增删改 从库开启IO线程:    开启SQL线程: 2.主库授权从库同步的帐号密码: 3.备份主库数据且导入从库: 4.在从库change master to 导入用于同步主库的ip.port.user.等信息. CHANGE MASTER TO          MASTER_HOST=

mysql主从服务器复制原理

在实际企业应用环境当中,单台mysql数据库是不足以满足日后业务需求的.譬如服务器发生故障,没有备份服务器来提供服务的话,业务就得停止.介于这种情况,我们来学习一下mysql主从复制. 将Mysql的数据分布到多个系统上去,这种分布的机制,是通过将Mysql的某一台主机的数据复制到其它主机(slaves)上,并重新执行一遍来实现的.复制过程中一个服务器充当主服务器,而一个或多个其它服务器充当从服务器.主服务器将更新写入二进制日志文件,并维护文件的一个索引以跟踪日志循环.这些日志可以记录发送到从服