日常的数据备份及恢复测试,是DBA工作重中之重的事情,所以要做好备份及测试,日常的备份常见有mysqldump+binlog备份、xtrabackup+binlog备份,无论那一种,几乎都少不了对binlog的备份,说明了binlog在数据恢复中的重要性,下面做个小测试,是工作中不少运维或者新人DBA容易犯的错。

创建一个测试表tb1:

<test>(root@localhost) [xuanzhi]> show create table tb1\G
*************************** . row ***************************
Table: tb1
Create Table: CREATE TABLE `tb1` (
`id` int() NOT NULL AUTO_INCREMENT,
`name` char() CHARACTER SET latin1 DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
row in set (0.00 sec) <test>(root@localhost) [xuanzhi]>

往表里插入两条数据:

<test>(root@localhost) [xuanzhi]> insert into tb1 (name)  value ('aa'),('bb');
Query OK, 2 rows affected (0.01 sec)
Records: 2 Duplicates: 0 Warnings: 0 <test>(root@localhost) [xuanzhi]> show master logs;
+----------------------+-----------+
| Log_name | File_size |
+----------------------+-----------+
| localhost-bin.000001 | 329 |
+----------------------+-----------+
1 row in set (0.00 sec) <test>(root@localhost) [xuanzhi]>

这个时候对数据备份,如果是xtrabackup备份的话,会在有xtrabackup_binlog_info文件中记录此时备份是到那个binlog文件和pos点的,如果是mysqldump备份,则需要带上--master-data=2这个参数,下面我们的数据量少,用mysqldump备份:

[root@localhost ~]# mysqldump -uroot -p123456  -R --events --triggers=true --master-data= --single-transaction xuanzhi > xuanzhi.sql
Warning: Using a password on the command line interface can be insecure.
[root@localhost ~]# grep -i "CHANGE MASTER" xuanzhi.sql
-- CHANGE MASTER TO MASTER_LOG_FILE='localhost-bin.000001', MASTER_LOG_POS=;
[root@localhost ~]#

备份完后,继续模拟数据库有写入,而还是写在localhost-bin.000001

<test>(root@localhost) [xuanzhi]> insert into tb1 (name)  value ('cc'),('dd');
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0 <test>(root@localhost) [xuanzhi]> show master logs;
+----------------------+-----------+
| Log_name | File_size |
+----------------------+-----------+
| localhost-bin.000001 | 538 |
+----------------------+-----------+
1 row in set (0.00 sec) <test>(root@localhost) [xuanzhi]> flush logs;
Query OK, 0 rows affected (0.01 sec) <test>(root@localhost) [xuanzhi]> insert into tb1 (name) value ('ee');
Query OK, 1 row affected (0.00 sec) <test>(root@localhost) [xuanzhi]> show master logs;
+----------------------+-----------+
| Log_name | File_size |
+----------------------+-----------+
| localhost-bin.000001 | 589 |
| localhost-bin.000002 | 321 |
+----------------------+-----------+
2 rows in set (0.00 sec) <test>(root@localhost) [xuanzhi]>

上面我们进行flush logs是为了模拟现在已经有多个binlog文件了,恢复时进行多个binlog一起恢复。

进行误操,把xunazhi库drop了:

<test>(root@localhost) [xuanzhi]> drop database xuanzhi;
Query OK, 1 row affected (0.02 sec) <test>(root@localhost) [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| test |
+--------------------+
4 rows in set (0.00 sec) <test>(root@localhost) [(none)]>

创建数据xuanzhi,把备份导入:

<test>(root@localhost) [(none)]> create database xuanzhi;
Query OK, 1 row affected (0.00 sec)
[root@localhost ~]# mysql -uroot -p123456 xuanzhi <./xuanzhi.sql
Warning: Using a password on the command line interface can be insecure.
[root@localhost ~]#

查看数据:

<test>(root@localhost) [(none)]> use xuanzhi
Database changed
<test>(root@localhost) [xuanzhi]> select * from tb1;
+----+------+
| id | name |
+----+------+
| 1 | aa |
| 2 | bb |
+----+------+
2 rows in set (0.00 sec) <test>(root@localhost) [xuanzhi]>

可以看到备份前的数据恢复了,我们现在要结合Binlog来恢复,但前提要找出误操作前的pos点,也就是drop database xuanzhi前的pos点:

[root@localhost ~]# mysqlbinlog -v --base64-output=DECODE-ROWS localhost-bin. |grep -C   -i "drop database"
### INSERT INTO `xuanzhi`.`tb1`
### SET
### @=
### @='ee'
# at
# :: server id end_log_pos CRC32 0x825a2f99 Xid =
COMMIT/*!*/;
# at
# :: server id end_log_pos CRC32 0x8c139cac Query thread_id= exec_time= error_code=
SET TIMESTAMP=/*!*/;
drop database xuanzhi
/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
[root@localhost ~]# mysql -uroot -p123456 xuanzhi <./xuanzhi.sql
Warning: Using a password on the command line interface can be insecure.
[root@localhost ~]#

从上面可以看到,误操作前的pos点是321,那我们现在通过binlog来进行数据恢复:

[root@localhost mysql-5.6]# mysqlbinlog --start-position= --stop-position= localhost-bin. localhost-bin. |mysql -uroot -p123456 xuanzhi
Warning: Using a password on the command line interface can be insecure.
[root@localhost mysql-5.6]#

--start-position是备份后记录下的pos点, --stop-position是误操前的pos点,如果批多个binlog文件,那么start-position是第一个binlog文件的pos点,stop-position是最后一个binlog的pos点,下面我们看下数据是否恢复回来了:

<test>(root@localhost) [xuanzhi]> select * from tb1;
+----+------+
| id | name |
+----+------+
| 1 | aa |
| 2 | bb |
| 3 | cc |
| 4 | dd |
| 5 | ee |
+----+------+
5 rows in set (0.00 sec) <test>(root@localhost) [xuanzhi]>

这里要提的是进行恢复前,要把需要恢复的binlog备份好,或者移动拷贝一份到另一个目录,因为进行数据导入时也会继续写binlog。假如你没有误操作的情况下,就是想测试一下数据的恢复,很多人的操作是导入备份,再从备份里记录的binlog文件名和pos点进行binlog恢复,发现步骤都很完美,也没报错,恢复后就是只有备份时的数据,没有备份后的数据,下面测试一下给大家看:

<test>(root@localhost) [xuanzhi]> insert into tb1 (name)  value ('aa'),('bb');
Query OK, 2 rows affected (0.01 sec)
Records: 2 Duplicates: 0 Warnings: 0 <test>(root@localhost) [xuanzhi]> select * from tb1;
+----+------+
| id | name |
+----+------+
| 1 | aa |
| 2 | bb |
+----+------+
2 rows in set (0.00 sec)
<test>(root@localhost) [xuanzhi]> show master logs;
+----------------------+-----------+
| Log_name | File_size |
+----------------------+-----------+
| localhost-bin.000001 | 329 |
+----------------------+-----------+
1 row in set (0.00 sec) <test>(root@localhost) [xuanzhi]>

进行备份操作:

[root@localhost ~]# mysqldump -uroot -p123456 -R --events --triggers=true --master-data= --single-transaction xuanzhi > xuanzhi.sql
Warning: Using a password on the command line interface can be insecure.
[root@localhost ~]# grep -i "change master" xuanzhi.sql
-- CHANGE MASTER TO MASTER_LOG_FILE='localhost-bin.000001', MASTER_LOG_POS=;
[root@localhost ~]#

继续写localhost-bin.000001后进行flush logs生成新的binlog再继续写数据,这里只是想模拟localhost-bin.000001写满了切localhost-bin.000002,结合多个binlog一起恢复

<test>(root@localhost) [xuanzhi]> insert into tb1 (name)  value ('cc'),('dd');
Query OK, rows affected (0.00 sec)
Records: Duplicates: Warnings: <test>(root@localhost) [xuanzhi]> flush logs;
Query OK, rows affected (0.00 sec) <test>(root@localhost) [xuanzhi]> insert into tb1 (name) value ('dd');
Query OK, row affected (0.01 sec) <test>(root@localhost) [xuanzhi]> show master logs;
+----------------------+-----------+
| Log_name | File_size |
+----------------------+-----------+
| localhost-bin. | |
| localhost-bin. | |
+----------------------+-----------+
rows in set (0.00 sec) <test>(root@localhost) [xuanzhi]>

下面进行恢复测试,正常来说先把备份导入:

[root@localhost ~]# mysql -uroot -p123456 xuanzhi <./xuanzhi.sql
Warning: Using a password on the command line interface can be insecure.
[root@localhost ~]#

查看数据,只有备份的那两条记录:

<test>(root@localhost) [xuanzhi]> select * from tb1;
+----+------+
| id | name |
+----+------+
| | aa |
| | bb |
+----+------+
rows in set (0.00 sec) <test>(root@localhost) [xuanzhi]>

那现在通过localhost-bin.000001,localhost-bin.000002来恢复后面那3条数据,那么起始pos是那个呢,就是上面备份完后备份文件里的那个pos,我们进到binlog的存放路径:

可以看到备份后的数据是没有恢复回来的。为什么呢?因为导入备份的时候,又开始写binlog了,而你恢复时用的binlog也就是现在导入备份时正在写的binlog。大体过程是这样的:

1、导入备份后,备份的所有操作都写进最后一个binlog了,也就是上面的localhost-bin.000002

2、进行binlog恢复,从备份文件里的pos点开始,按理来说是可以恢复到最新数据的,但是上面导入了备份,导入时的所有操作都会记录到localhost-bin.000002

3、备份导入时会有DROP TABLE和CREATE TABLE的动作写进binlog里,所以最终得到的数据,还是备份时的数据。

总结:

        一、在恢复全备数据之前必须将该binlog文件移出,否则恢复过程中,会继续写入语句到binlog,最终导致增量恢复数据部分变得比较混乱

        二、做好数据文件及binlog的备份至关重要,但不是备份完就算了,要定期进行数据恢复测试或演练

        三、恢复时建议对外停止更新,即禁止更新数据库

作者:陆炫志

出处:xuanzhi的博客 http://www.cnblogs.com/xuanzhi201111

您的支持是对博主最大的鼓励,感谢您的认真阅读。本文版权归作者所有,欢迎转载,但请保留该声明。

一个简单的binlog恢复测试的更多相关文章

  1. 参考MySQL Internals手册,使用Golang写一个简单解析binlog的程序

    GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. MySQL作为最流行的开源关系型数据库,有大量的拥趸.其生态已经相当完善,各项特性在圈内都有大量研究.每次新特性发布,都会 ...

  2. 如何利用JUnit开展一个简单的单元测试(测试控制台输出是否正确)

    待测类(CreateString)如下: public class CreateString { public void createString() { //Output the following ...

  3. 安全小测试:介绍一个简单web安全知识测试的网站

    https://websecurity.firebaseapp.com/ 一次测试一共7道题,最后有答案,可以反复做,每次随机抽题

  4. (原创)如何使用boost.asio写一个简单的通信程序(一)

    boost.asio相信很多人听说过,作为一个跨平台的通信库,它的性能是很出色的,然而它却谈不上好用,里面有很多地方稍不注意就会出错,要正确的用好asio还是需要花一番精力去学习和实践的,本文将通过介 ...

  5. 分享一个.NET实现的简单高效WEB压力测试工具

    在Linux下对Web进行压力测试的小工具有很多,比较出名的有AB.虽然AB可以运行在windows下,但对于想简单界面操作的朋友有点不太习惯.其实vs.net也提供压力测试功能但显然显得太重了,在测 ...

  6. 用Apache 里面的ab做一个简单的压力测试

    我用的是xampp环境包. D:\xampp\apache\bin 进入这路径, 找到ab.exe  尝试双击打开ab.exe 但不能如愿, 这两个都是一个压力的测试软件, 是apache自带的; 好 ...

  7. AWVS漏洞测试-02节-添加一个简单的新闻系统

    实现一个简单的新闻发布系统 有登录 注册 添加新闻 浏览新闻 评论新闻 新闻列表 这些基本功能 使用asp.net webform 首先是登录页 protected void Button1_Clic ...

  8. 一个简单的Spring测试的例子

    在做测试的时候我们用到Junit Case,当我们的项目中使用了Sring的时候,我们应该怎么使用spring容器去管理我的测试用例呢?现在我们用一个简单的例子来展示这个过程. 1 首先我们新建一个普 ...

  9. Web开发之tomcat配置及使用(环境变量设置及测试,一个简单的web应用实例)

    Tomcat的配置及测试: 第一步:下载tomcat,然后解压到任意盘符 第二步:配置系统环境变量 tomcat解压到的D盘 (路径为: D:\tomcat), 配置环境变量: 启动tomcat需要两 ...

随机推荐

  1. mysql 与linux ~ 内存分析与调优

    一 简介:linux内存和mysql二 分类   1 用户空间和内核空间      用户空间内存,从低到高分别是五种不同的内存段      1 只读段 包含代码和常量等      2 数据段 包含全局 ...

  2. TensorFlow学习笔记:保存和读取模型

    TensorFlow 更新频率实在太快,从 1.0 版本正式发布后,很多 API 接口就发生了改变.今天用 TF 训练了一个 CNN 模型,结果在保存模型的时候居然遇到各种问题.Google 搜出来的 ...

  3. aiohttp的笔记之TCPConnector

    TCPConnector维持链接池,限制并行连接的总量,当池满了,有请求退出再加入新请求.默认是100,limit=0的时候是无限制 1.use_dns_cache: 使用内部DNS映射缓存用以查询D ...

  4. pymongo加索引以及查看索引例子

    # -*- coding: utf-8 -*- # @Time : 2018/12/28 10:01 AM # @Author : cxa import pymongo db_configs = { ...

  5. bug笔记(pc)

    1.如果a标签中的href没有设置,那么点击的这个按钮的时候,这个页面会自动刷新!!! Bug:   <a href=”” class=”btn”></a>类似这种情况,点击a ...

  6. 迁移学习(Transfer Learning)

    原文地址:http://blog.csdn.net/miscclp/article/details/6339456 在传统的机器学习的框架下,学习的任务就是在给定充分训练数据的基础上来学习一个分类模型 ...

  7. ubuntu html5开发工具brackets

    Brackets 是一款使用 HTML,CSS,JavaScript 创建的开源的针对 Web 开发的编辑器.实时预览,快速编辑,跨平台,可扩展,开源,让 Brackets 成为一款非常优秀的编辑器. ...

  8. 前端 -----jQuery的事件绑定和解绑

    11-jQuery的事件绑定和解绑   1.绑定事件 语法: bind(type,data,fn) 描述:为每一个匹配元素的特定事件(像click)绑定一个事件处理器函数. 参数解释: type (S ...

  9. mysql针对单个库进行备份

    #!/bin/bashBakDir=/backup/mysql_backupLogFile=/backup/mysql_backup.logDate=`date +%Y%m%d`Begin=`date ...

  10. 分布式全文检索引擎之ElasticSearch

    一 什么是 ElasticSearch Elasticsearch 是一个分布式可扩展的实时搜索和分析引擎,一个建立在全文搜索引擎 Apache Lucene(TM) 基础上的搜索引擎.当然 Elas ...