MySQL binlog之数据恢复
一、恢复方案
1、数据量不是特别大,可以将mysqldump命令备份的数据使用mysql客户端命令或者source命令完成数据的恢复;
2、使用Xtrabackup完成数据库的物理备份恢复,期间需要重启数据库服务;
3、使用LVM快照卷完成数据库物理备份恢复,期间需要重启数据库服务;
二、使用mysqlbinlog进行时间点恢复
1、介绍
mysqlbinlog是一个从二进制日志中读取语句的工具,在mysql安装完成之后自带的。
2、二进制日志恢复原理
当使用mysqldump对数据库进行备份时,生成的备份文件中包含了数据库DML操作时的时间点以及备份时的二进制日志位置信息,如果单库,可以从某个时间点开始,进行时间点恢复;如果是主从架构,可以根据备份时的--master-data=2和--single-transaction,完成根据时间点或者位置点的恢复。
3、二进制日志恢复示例
(1)单库恢复示例
创建数据库,并插入测试数据
mysql> SHOW CREATE DATABASE test_db;
mysql> CREATE TABLE `student` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) NOT NULL,
`age` tinyint(4) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
mysql> INSERT INTO student (name,age) VALUES('Jack',23),('Tomcat',24),('XiaoHong',22),('ZhangFei',29);
使用mysqldump进行全量备份,备份时滚动日志,同时记住二进制日志文件名称和日志的位置点
[root@WB-BLOG ~]# mysqldump -uroot -proot -h127.0.0. -P3306 --databases test_db --single-transaction --triggers --routines --flush-logs --events > /tmp/test_db.sql
[root@WB-BLOG ~]# mysql -e "show binary logs" > bin_pos_`date +%F`.out
此时查看二进制日志文件名称和日志点位置如下
mysql> SHOW BINARY LOGS;
+------------------+-----------+
| Log_name | File_size |
+------------------+-----------+
| mysql-bin.000001 | 1497 |
| mysql-bin.000002 | 397 |
+------------------+-----------+
2 rows in set (0.00 sec)
使用了一段时间,不小心误操作,执行了如下的语句,将数据库中的数据全部修改了
mysql> UPDATE STUDENT SET name = 'admin';
过了一段时间,可能是几分钟,也可能是几个小时,有人反映网站登录有问题了,查看发现好多数据被误修改,而这段时间内,还一直有写入操作,如又新增了如下的记录
mysql> INSERT INTO student(name,age) VALUES('Hbase',23),('BlackHole',30);
此时需要恢复数据,首先为了防止数据继续写入,可以先锁表,暂停写入业务,通知用户系统维护,然后执行如下操作:
#登录数据库,锁表,此时表只能读,不能写
mysql> USE test_db;
mysql> LOCK TABLE student READ;
#然后重新(注意是重新打开)打开一个session窗口,否则会话处出之后,锁就会释放。然后压缩备份现有数据和二进制日志文件
[root@WB-BLOG mysql_logs]# tar -zcvf mysql_data.tar.gz /mysql_data/*
[root@WB-BLOG mysql_logs]# tar -zcvf mysql_bin.tar.gz /mysql_logs/*
#导入最近备份的一次全备数据
[root@WB-BLOG ~]# mysql -uroot -proot -h127.0.0. -P3306 < /tmp/test_db.sql #查看全备时的二进制日志文件和日志点
[root@WB-BLOG ~]# cat bin_pos_2018--.out
Log_name File_size
mysql-bin.
mysql-bin.
#将861这个点之后的二进制日志文件转换为一个sql文件
[root@WB-BLOG bin]# ./mysqlbinlog /mysql_logs/mysql-bin. --start-position= > /tmp/tmp.sql
#使用vim编辑器编辑这个sql文件,找到其中的未加条件的UPDATE语句,然后将其删掉,然后将删掉UPDATE语句之后的sql脚本内容导入到数据库中
[root@WB-BLOG bin]# vim /tmp/tmp.sql
use `test_db`/*!*/;
SET TIMESTAMP=/*!*/;
update student set name = 'admin' #删掉这一句
[root@WB-BLOG bin]# mysql -uroot -proot -h127.0.0. -P3306 < /tmp/tmp.sql
#登录数据库查询数据是否恢复,可以查看被误修改的数据是否还原,然后对表执行解锁,再次全备数据
mysql> UNLOCK TABLES;
(2)主从架构数据恢复示例
环境
主库:192.168.199.10(node01)
从库:192.168.199.11(node02)
首先停止从库的SQL线程,然后在从库上全备数据,并输入"SHOW SLAVE STATUS"信息到备份文件中,"SHOW SLAVE STATUS"的输出信息中记录了当前应用到了主库的哪个位置点的信息
#登录从库,然后关闭SQL线程
mysql> STOP SLAVE SQL_THREAD;
#然后记录从库中当前应用的主库的二进制日志文件信息
[root@node02 mysql_data]# mysql -e "SHOW SLAVE STATUS \G" > slave_`date +%F`.info
[root@node02 mysql_data]# mysqldump -uroot -proot -h127.0.0. -P3306 --databases test_db --routines --triggers --single-transaction > /tmp/mysql_test_db_`date +%F`.sql
在从库上备份完成之后,重新启动从库的SQL线程
mysql> START SLAVE SQL_THREAD;
启动SQL线程之后,备份这段时间内在主库上的DML操作会重新同步到从库上。假如在主库上发生了一个误操作,没加条件更新了student表中的所有数据,导致了表中所有数据被修改,此时由于同步操作,从库也被修改了
#登录主库,修改数据库的对外用户,使其暂不提供服务,然后滚动日志
mysql> UPDATE mysql.user SET Host = '127.0.0.1' WHERE User='tomcat';
Query OK, 1 rows affected (0.00 sec)
#刷新权限表
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)
#滚动日志
mysql> FLUSH LOGS;
Query OK, 0 rows affected (0.01 sec)
#将从库备份的数据及备份时刻的从库slave信息传到主库上
[root@node02 mysql_data]# scp /tmp/mysql_test_db_2018--.sql 192.168.199.10:/root/
[root@node02 mysql_data]# scp slave_2018--.info node01:/root/
备份主库的数据目录和二进制日志文件目录
[root@node01 mysql_logs]# tar -zcvf mysql_master_data.tar.gz /mysql_data/*
[root@node01 mysql_logs]# tar -zcvf mysql_logs.tar.gz /mysql_logs/*
导入从库最近一次备份的数据
[root@node01 mysql_logs]# mysql -uroot -proot -h127.0.0. -P3306 < /root/mysql_test_db_2018--.sql
#注意:上述的操作不能锁主库的表,否则全备数据无法导入。
查看备份时刻的从库中应用到的主库二进制日志文件名称及位置点
[root@node01 mysql_logs]# cat /root/slave_2018--.info
Master_Log_File: master-bin. #备份时所应用的主库二进制日志文件名称
Read_Master_Log_Pos: #备份时所应用的主库二进制日志文件的位置
从该日志文件及日志点开始,将395日志点之后的日志文件转换为sql脚本,如果有多个二进制日志文件可以同时转换为sql脚本,如下所示
[root@node01 mysql_logs]# mysqlbinlog /mysql_logs/master-bin. --start-position= > /tmp/tmp.sql
#将master-bin.,master-bin.,master-bin.000005合并到/tmp.sql文件中
[root@node01 mysql_logs]# mysqlbinlog /mysql_logs/master-bin.{3,4,5} --start-position= > /tmp/tmp.sql
找到误操作的update语句,然后删除该语句,并将增量的sql脚本导入数据库
[root@node01 mysql_logs]# vim /tmp/tmp.sql
use `test_db`/*!*/;
update student set name = 'admin' #删掉这一句
[root@node01 mysql_logs]# mysql -uroot -proot -h127.0.0. -P3306 < /tmp/tmp.sql
登录数据库,查看数据是否正常,被误修改的数据是否已经恢复,如果恢复,则在主库上全备数据,然后传到从库,完成从库恢复
[root@node01 mysql_data]# mysqldump -uroot -proot -h127.0.0. -P3306 --databases test_db --routines --triggers --single-transaction --master-date= > /tmp/master_test_db_`date +%F`.sql
[root@node01 mysql_data]# scp /tmp/master_test_db_2018--.sql node01:/root/
#如果从库设置了只读,需要先去掉只读限制
mysql> SET GLOBAL read_only = OFF;
#将数据导入从库
[root@node02 mysql_logs]# mysql -uroot -proot -h127.0.0. -P3306 < /root/master_test_db_2018--.sql
#开启从库的只读
mysql> SET GLOBAL read_only = ON;
由于在主库上备份时添加了--master-date=1参数,所以从库导入之后,不需要重新执行change master操作。
登录从库,查看SHOW SLAVE STATUS信息是否正常,如果正常,登录主库,重新修改授权表,然后对外提供服务
mysql> UPDATE mysql.user set Host = '192.168.0.%' WHERE User = 'tomcat';
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)
执行完成之后,主从数据恢复完毕。
至此,数据恢复介绍完毕,上述介绍了使用全备加二进制日志实现单实例数据库和主从数据库的数据恢复过程
Reference link:
https://segmentfault.com/a/1190000015371440
https://blog.csdn.net/qq_40809549/article/details/79896760
https://www.cnblogs.com/-mrl/p/9959365.html
全量备份参考: mysqldump -u root -p -B -F -R -x --master-data=2 test_db|gzip >/opt/backup/test_db_$(date +%F).sql.gz
参数说明:
-B:指定数据库
-F:刷新日志
-R:备份存储过程等
-x:锁表
--master-data=2表示在dump过程中记录主库的binlog和pos点,并在dump文件中注释掉这一行;
--master-data=1表示在dump过程中记录主库的binlog和pos点,并在dump文件中不注释掉这一行,即恢复时会执行;
--dump-slave=2表示在dump过程中,在从库dump,mysqldump进程也要在从库执行,记录当时主库的binlog和pos点,并在dump文件中注释掉这一行;
--dump-slave=1表示在dump过程中,在从库dump,mysqldump进程也要在从库执行,记录当时主库的binlog和pos点,并在dump文件中不注释掉这一行;
注意:在从库上执行备份时,即--dump-slave=2,这时整个dump过程都是stop io_thread的状态。
mysqldump导出数据时,当这个参数(master-data)的值为1的时候,mysqldump出来的文件就会包括CHANGE MASTER TO这个语句,CHANGE MASTER TO后面紧接着就是file和position的记录,在slave上导入数据时就会执行这个语句,salve就会根据指定这个文件位置从master端复制binlog。默认情况下这个值是1
当这个值是2的时候,chang master to也是会写到dump文件里面去的,但是这个语句是被注释的状态。
--single-transaction:从5.1.13开始mysqldump指定--single-transaction备份时使用START TRANSACTION /*!40100 WITH CONSISTENT SNAPSHOT */ 来代替begin 开启一个事物,这样就能在备份的时候产生一个一致的快照
--flush-logs:同 -F
--events:包含事件
--routines:包含常规
--triggers:包含触发器
mysqlbinlog参数说明:
常用参数选项解释:
--no-defaults ?
--start-position=875 起始pos点
--stop-position=954 结束pos点
--start-datetime="2016-9-25 22:01:08" 起始时间点
--stop-datetime="2019-9-25 22:09:46" 结束时间点
--database=zyyshop 指定只恢复zyyshop数据库(一台主机上往往有多个数据库,只限本地log日志)
--------------------------------------------------------
不常用选项:
-u --user=name 连接到远程主机的用户名
-p --password[=name] 连接到远程主机的密码
-h --host=name 从远程主机上获取binlog日志
--read-from-remote-server 从某个MySQL服务器上读取binlog日志
MySQL binlog之数据恢复的更多相关文章
- mysql利用binlog进行数据恢复
目录 mysql利用binlog进行数据恢复 binlog基本配置和格式 binlog基本配置 查看binlog状态 binlog的三种格式 转换成sql mysql自带的mysqlbinlog 利用 ...
- Windows Mysql binlog 数据恢复
show variables like 'log_bin%'; 可以看到Mysql binlog为关闭状态,那我们去更改为开启状态
- MySQL bin-log 日志清理方式
MySQL bin-log 作用 1.数据恢复:如果你的数据库出问题了,而你之前有过备份,那么可以看日志文件,找出是哪个命令导致你的数据库出问题了,想办法挽回损失. 2.主从服务器之间同步数据:主 ...
- MySQL 数据库增量数据恢复案例
MySQL 数据库增量数据恢复案例 一.场景概述 MySQL数据库每日零点自动全备 某天上午10点,小明莫名其妙地drop了一个数据库 我们需要通过全备的数据文件,以及增量的binlog文件进行数据恢 ...
- Mysql binlog日志解析
1. 摘要: Mysql日志抽取与解析正如名字所将的那样,分抽取和解析两个部分.这里Mysql日志主要是指binlog日志.二进制日志由配置文件的log-bin选项负责启用,Mysql服务器将在数据根 ...
- MySQL Binlog的介绍
binlog基本定义:二进制日志,也成为二进制日志,记录对数据发生或潜在发生更改的SQL语句,并以二进制的形式保存在磁盘中: 作用:MySQL的作用类似于Oracle的归档日志,可以用来查看数据库的变 ...
- 腾讯工程师带你深入解析 MySQL binlog
欢迎大家前往云+社区,获取更多腾讯海量技术实践干货哦~ 本文由 腾讯云数据库内核团队 发布在云+社区 1.概述 binlog是Mysql sever层维护的一种二进制日志,与innodb引擎中的red ...
- 教你MySQL Binlog实用攻略
本文由云+社区发表 1.概述 binlog是Mysql sever层维护的一种二进制日志,与innodb引擎中的redo/undo log是完全不同的日志:其主要是用来记录对mysql数据更新或潜在发 ...
- MySQL Binlog 介绍
Binlog 简介 MySQL中一般有以下几种日志: 日志类型 写入日志的信息 错误日志 记录在启动,运行或停止mysqld时遇到的问题 通用查询日志 记录建立的客户端连接和执行的语句 二进制日志 记 ...
随机推荐
- const定义的并非是常量,而是常量索引
我第一次看const的时候,记忆中对const的定义是,定义常量. 后经过研究,定义的并非常量,而是常量索引. 有时候会遇到使用const定义数组的情况 const arr = [] arr.push ...
- java 通过反射获取数组
1.创建数组.设置数组元素.访问数组 一维数组: 多维数组: public Class<?> getComponentType() 返回表示数组组件类型的 Class.如果此类不表示数组类 ...
- 写api接口神器--带你5分钟了解swagger
随着互联网技术的发展,现在的网站架构基本都由原来的后端渲染,变成了:前端渲染.先后端分离的形态,而且前端技术和后端技术在各自的道路上越走越远. 前端和后端的唯一联系,变成了API接口:API文档变成了 ...
- 解决扫码枪输入input时受中文输入法的影响
<html><head> <meta content="text/html; charset=UTF-8" http-equiv="Cont ...
- vscode 编写Markdown文件
vscode使用Markdown文档编写 首先安装vscode工具,具体的使用可以参考之前的博文:<Visual Studio Code教程:基础使用和自定义设置> VScode已经默 ...
- [ByteCTF 2019]EZCMS
题目复现链接:https://buuoj.cn/challenges 参考链接:ByteCTF_2019&XNUCA_2019部分web题复现 一.知识点 1.源码泄露 访问www.zip获取 ...
- Vue-搭建环境
项目开发完react-native,因为又对vue开始感兴趣了,又开始自学起了vue,关于vue是一个很简便的前端框架,要学习它,当然是要先学会搭建vue的环境, 不会搭建环境的程序员不是一个好的程序 ...
- margin-top百分比问题
(1)其实margin-top和margin-bottom的百分比,一般是按容器元素的宽度而不是高度来计算的,padding同理.
- js 获取滚动位置,滚动到指定位置,平滑滚动
1.获取当前滚动条位置信息 var top = dom.scrollTop; // 获取y轴上的滚动位置 var left = dom.scrollLeft; // 获取x轴上的滚动位置 2.滚动到指 ...
- compile and link C/CPP programs on Mac
ref: https://stackoverflow.com/questions/29987716/cannot-use-gsl-library-on-macos-ld-symbols-not-fou ...