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

《MySQL主从延迟复制实践及生产故障案例恢复实践》要点:
本文介绍了MySQL主从延迟复制实践及生产故障案例恢复实践,希望对您有用。如果有疑问,可以联系我们。

1.MySQL主从延迟复制介绍

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

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

[root@db02 data]# pwd

/application/mysql/data

[root@db02 data]# mysqlbinlog db02-relay-bin.000002

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

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

create database lanlan

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

3.MySQL延迟复制原理解析

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

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

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

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

4.MySQL延迟复制恢复案例实践

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

(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)

(2)模拟在主库写入数据

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

[root@db01 ~]# for n in {1..5}

> do

>     mysql -e “create database oldboy$n”

>     sleep 5

> done

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

(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)

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

(4)停止写库恢复数据

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

[root@db01 ~]# iptables -I INPUT -p tcp –dport 3306 ! -s 172.16.1.51 -j DROP 

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

(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日志到从库了.

(6)从库暂停主从复制,并检查数据

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

mysql> stop slave;

mysql> show databases;

+——————–+

| Database           |

+——————–+

| information_schema |

| alex_python        |

| mysql              |

| performance_schema |

+——————–+

4 rows in set (0.00 sec)

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

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

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

[root@db02 data]# pwd           

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

/application/mysql/data

[root@db02 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线程读取中继日志位置信息.

[root@db02 data]# cat relay-log.info  

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

7

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

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

oldboy-bin.000024

309

3600

0

1

(8)解析需要的中继日志

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

[root@db02 data]# mysqlbinlog –start-position=284 db02-relay-bin.000002 >relay.sql 

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

(9)从解析文件中删除问题SQL

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

[root@db02 data]# egrep “drop database oldboy5” relay.sql   

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

drop database oldboy5

[root@db02 data]# sed -i ‘/drop database oldboy5/d’ relay.sql

#删除,注意别删多了.

[root@db02 data]# egrep “^drop database oldboy5” relay.sql   

#检查删除结果.

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

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

[root@db02 data]# mysql<relay.sql   

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

[root@db02 data]# mysql -e “show databases like ‘oldboy%’;”

+——————–+

| Database (oldboy%) |

+——————–+

| oldboy1            |

| oldboy2            |

| oldboy3            |

| oldboy4            |

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

+——————–+

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


起步 处理器架构,参考 x86是指intel的开发的一种32位指令集 intel和amd早期的cpu都支持这种指令集 AMD比Intel率先制造出了商用的兼容x86的CPU,AMD称之为AMD64 Intel选择了设计一种不兼容x86的全新64为指令集,称之为IA-64,后来支持AMD64的指令集,
pscp pscp -P 22 C:\work\test.txt root@192.168.1.5:/home/data pscp -P 22 root@192.168.1.5:/home/data/test.txt C://work// 检索 find / -name default.config
文件处理 ls -a # 显示所有文件 ls -l # 显示详细信息 ls -d # 显示路径 mkdir /目录名称 # 创建目录 cd /目录名称 # 切换目录 pwd # 显示当前路径 rmdir /目录名称 # 删除目录 cp -rp [目录名称] [目标目录] # 复制目录到目标目录 cp
准备一台电脑(我就用联想拯救者r7000演示) 参考博客制作启动盘 插上U盘,启动电脑,一直按F2 进入如下页面后,将U盘设置为第一启动项,点击exit,保存并退出 之后进入如下页面,选择第三项 进入如下页面,选择第四项 进入如下页面,选择第一项,选中后,先不要点Enter 按e键,将inst.st
认识 Linux系统是参考了UNIX系统作为模板开发的,但没有使用UNIX的代码;是UNIX的一种,但不是衍生版 在Linux内核的基础上开发是发行版 分区 逻辑分区永远从5开始 步骤 挂载:可理解为分配盘符,挂载点即是盘符名;不同之处:Linux中是以空目录名称作为盘符 Hda 第一块硬盘 Hda
文件处理命令 以 . 开头的文件是隐藏文件 以 - 开头表示这是一个文件 以 d 开头表示是一个目录 以 l 开头表示是一个软链接 第一个root是所有者,第二个root是所属组 ls -h 以文件默认大小后缀 显示 ls -i 查看i节点(唯一标识) 所有者:只能有一个,可变更 所属组:只能有一个
参考 01 02 03 前提环境 本地安装VirtualBox,并安装CentOS8,配置网络后,window系统上putty能连接到CentOS8服务器 配置步骤 右键服务器复制 启动复制后的服务器,查看ip和hostname发现和原来的服务器一样,需要修改 hostname # 查看主机名 vi
文件搜索命令 星号匹配任意字符,问号匹配任意单个字符 -iname 根据文件名查找且不区分大小写 -ok 命名会有一个询问的步骤 如果没有找到指定文件,可输入命令:updatedb 更新文件资料库;除tmp目录不在文件资料库收录范围之内 locate -i 文件名 # 检索时不区分大小写 which
安装环境 安装最新版的Virtual Box,点击安装 下载centos8镜像 创建虚拟机,可参考 选择下载到本地的镜像 设置启动顺序 点击启动 启动过程中报错:“FATAL:No bootable medium found!” 1.没有选择iso镜像 2.光驱没有排在第一位置 3.镜像只能选择x8
Linux严格区分大小写 所有内容文件形式保存,包括硬件 Linux不靠扩展名区分文件类型 挂载:将设备文件名和挂载点(盘符)连接的过程 Linux各个目录的作用 bin表示二进制 服务器注意事项 远程服务器不允许关机,只能重启 重启时应该关闭服务 不要在服务器访问高峰运行高负载命令 远程配置防火墙
IDE连接Linux,上传下载文件 参考1 参考2 连接Linux 上传下载文件 本地项目打包后上传 查看是否上传成功,右键下载 补充 后端项目开发完成后,需clean掉临时文件target文件夹,且只推送修改过的文件 前端项目开发的过程中,需要在每个子组件中使用scoped,确保每个子组件中的编码
起步 LTS与普通版本的区别 LTS版本的发布周期更长,更加稳定 安装jdk sudo mkdir /usr/lib/jvm # 在Ubuntu中创建目录 pscp D:\安装包\linux源码包\jdk-8u291-linux-x64.tar.gz chnq@192.168.0.102:/tmp
前言 最近在b站上看了兄弟连老师的Linux教程,非常适合入门:https://www.bilibili.com/video/BV1mW411i7Qf 看完后就自己来试着玩下,正好手上有台空闲的电脑就尝试不使用虚拟机的方式安装Linux系统 安装步骤 制作启动盘 下载ISO镜像,我这里下载的是Cen
新建虚拟电脑 设置内存和处理器 设置硬盘大小 完成 设置 查看光驱 设置启动顺序 点击启动 选择第1项 进入图形安装界面 选择安装位置,开始安装 设置root密码 重启 登录 查看本地文件夹 配置网络,点击设置 查看宿主机ip C:\Users\ychen λ ipconfig 无线局域网适配器 W
源码包安装需手动下载后安装 二进制包则在package目录下 rpm命令管理rpm包 若某个rpm包依赖于某个模块,需要到网站www.rpmfind.net查询该模块依赖的包,安装这个包后自动安装模块,之后就能安装rpm包了 安装升级时使用包全名 查询卸载时使用包名 虚拟机中的Linux系统安装rp
首先进入命令模式,再输入以下命令 命令模式用于输入命令 插入模式可对文件编写操作 编辑模式下的命令是在冒号后输入 :12, 15d # 删除指定范围的行,这里是删除12到15行 :n1,n2s/old/new/g ## 表示从n1行到n2行,old表示旧的字符串 vim使用小技巧:自定义快捷键,如快
使用源码包安装,需要自己指定安装位置,通常是 /usr/local/软件名/ linux中要想启动执行文件,应使用绝对路径 /绝对路径/rpm包名 start ## 执行方式一 service rpm包名 start ## 执行方式二 使用源码包安装后,由于自定义安装路径,就不能使用service命
网络命令 在收邮件的用户中,输入 mail 可查看邮件信息,输入序列号查看详细信息 在mail命令下,输入h 查看所有邮件的列表 输入:d 序列号 # 删除邮件 last # 统计所有用户登录或重启时间,用于日志查询 lastlog # 显示包括未登录用户的登录时间 lastlog -u 用户id
若要使用yum管理,必须能连接网络,首先配置网络IP 进入yum源文件中启动容器 使用yum源头安装rpm包不需要进入package路径,同时也不需要使用包全名,会有yum自动管理 安装软件组
简介 client即是本机安装的docker,相当于git Docker_host相当于centos系统 registry则是docker仓库,相当于GitHub 镜像用于创建docker容器,一个镜像可以创建多个docker容器 容器是由镜像创建的运行实例,(镜像相当于类,容器相当于类创建的对象)