Linux 上通过binlog文件 恢复mysql 数据库详细步骤
一、binlog 介绍
服务器的二进制日志记录着该数据库的所有增删改的操作日志(前提是要在自己的服务器上开启binlog),还包括了这些操作的执行时间。为了显示这些二进制内容,我们可以使用mysqlbinlog命令来查看。
用途1:主从同步
用途2:恢复数据库(也是线上出现一次数据库文件丢失后,才对这个有所了解并学习的)
mysqlbinlog命令用法:shell> mysqlbinlog [options] log_file ...
1) mysqlbinlog 选项示例
常见的选项有以下几个:
--start-datetime
从二进制日志中读取指定等于时间戳或者晚于本地计算机的时间。取值如:="1470733768" 或者="2016-08-09 5:09:28"
示例:
[root@hcloud ~]# mysqlbinlog --start-datetime="2016-08-09 5:05:27" /var/lib/mysql/mysql-bin.
--stop-datetime
从二进制日志中读取指定小于时间戳或者等于本地计算机的时间 取值和上述一样
--start-position
从二进制日志中读取指定position 事件位置作为开始。取值:="2698"
示例:
[root@hcloud ~]# mysqlbinlog --start-position="" /var/lib/mysql/mysql-bin.
--stop-position
从二进制日志中读取指定position 事件位置作为事件截至。取值:="2698"
二、环境准备以及备份恢复
1) 安装好mysql后,检查开启binlog
mysql> SHOW BINARY LOGS; ERROR (HY000): You are not using binary logging
:上面提示说明没有服务器开启binlog
修改/etc/my.cnf
在mysqld选项中添加 一行内容如下:
log-bin=mysql-bin
默认如果不给值的话,log-bin 的会以mysqld-bin 为索引,创建mysqld-bin.00001等
重启mysqld即可。
2) 检查下binlog
mysql> show binary logs;
+------------------+-----------+
| Log_name | File_size |
+------------------+-----------+
| mysql-bin. | |
+------------------+-----------+
row in set (0.00 sec)
3) 先创建一些原始数据。
mysql> create database Test_DB;
Query OK, row affected (0.00 sec) mysql> use Test_DB;
Database changed mysql> CREATE TABLE OneTb(id INT() NOT NULL,name varchar(),age INT());
Query OK, rows affected (0.00 sec) mysql> insert into OneTb values (,'user1',);
mysql> insert into OneTb values (,'user2',);
insert into OneTb values (,'user3',);
检查下数据:
mysql> select * from OneTb;
+----+-------+------+
| id | name | age |
+----+-------+------+
| | user1 | |
| | user2 | |
| | user3 | |
+----+-------+------+
rows in set (0.00 sec)
4) 备份还原 (完整备份以及还原)
这里我们模拟一下做下每天的完整备份数据库任务。
[root@hcloud ~]# mysqldump -uroot -p Test_DB > /data/mysqlbackup/Test_DB_0809-:.sql
Enter password:
模拟下操作失误,将数据修改错误了。
mysql> update OneTb set age = ;
Query OK, rows affected (0.00 sec)
Rows matched: Changed: Warnings: mysql> select * from OneTb;
+----+-------+------+
| id | name | age |
+----+-------+------+
| | user1 | |
| | user2 | |
| | user3 | |
+----+-------+------+
rows in set (0.00 sec)
现在我们使用传统的方式来进行恢复还原。
[root@hcloud ~]# mysql -uroot -p Test_DB < /data/mysqlbackup/Test_DB_0809-\:.sql
再次查询一下:
mysql> select * from Test_DB.OneTb;
+----+-------+------+
| id | name | age |
+----+-------+------+
| | user1 | |
| | user2 | |
| | user3 | |
+----+-------+------+
rows in set (0.00 sec)
可以看到数据都已经还原回来。
5) 利用binlog模拟还原
在原表的基础上在创建几条数据。
mysql> insert into Test_DB.OneTb values(,'user4',),(,'user5',),(,'user6',);
Query OK, rows affected (0.00 sec)
Records: Duplicates: Warnings: mysql> select * from Test_DB.OneTb;
+----+-------+------+
| id | name | age |
+----+-------+------+
| | user1 | |
| | user2 | |
| | user3 | |
| | user4 | |
| | user5 | |
| | user6 | |
+----+-------+------+
rows in set (0.00 sec)
如果这个时候我们把数据不小心修改了或者把库删除掉了,导致数据全部丢失,这个时候如果再用之前最新的备份文件 Test_DB_0809-16:50.sql,去恢复数据的话,那么将会丢掉备份之后新插入的数据。
注意:如果真的使用最近的一次备份文件去做的话,一定是在万不得已的情况(比如binlog 被删除,整个硬盘挂掉、、、 想想都可怕。。。)。
模拟误操作,批量更改下用户的名字。
mysql> update Test_DB.OneTb set name='user10';
Query OK, rows affected (0.00 sec)
Rows matched: Changed: Warnings:
不行,上一步不够狠,这里再狠一点,把表都给删除
mysql> drop table Test_DB.OneTb;
ERROR (HY000): MySQL server has gone away
No connection. Trying to reconnect...
Connection id:
Current database: *** NONE *** Query OK, rows affected (0.00 sec)
由于之前我们一开始开启了binlog 日志选项,用binlog恢复数据库。下面从binlog入手,先检查一下binlog 文件,目前我的mysql 服务自开启binlog 后重启了两次,所以有2个binlog文件;
(关于binlog文件的生成:每重启一次,便会重新生成一个binlog文件;还有一种情况就是运行了FLUSH LOGS命令也会重建一个;还有一种情况就是当这个binlog文件的大小到了设定的值后,就会重新生成一个新的)
mysql-bin.index 文件中记录的是:自log-bin选项开启后,记录的所有的二进制日志清单列表。
注意:在实际生产环境中,如果遇到需要恢复数据库的情况,不要让用户能访问到数据库,以避免新的数据插入进来,以及在主从的环境下,关闭主从。
使用mysqlbinlog 命令可以查看binlog文件.我们看下最新的文件mysql-bin.00002
从最后可以看出有删除的操作。但是我们不能完全的恢复,因为最后还有删除的操作。
现在我的思路就是,先将第一个binlog 和第二个binlog 文件导出来à利用指定的position位置的方式(过滤掉删除表操作和update Test_DB.OneTb set name='user10';这条语句 ),导出2个sql 语句,最后我们将2个sql 合成一个sql,导入到数据库中即可。
我们先用mysqlbinlog命令找到update 那条语句的位置,然后指定position 将mysql-bin.00001 导出来。
[root@hcloud ~]# mysqlbinlog /var/lib/mysql/mysql-bin. …. # :: server id end_log_pos Query thread_id= exec_time= error_code= SET TIMESTAMP=/*!*/; SET @@session.foreign_key_checks=, @@session.unique_checks=/*!*/; SET @@session.sql_mode=/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=,@@session.collation_connection=,@@session.collation_server=/*!*/; insert into Test_DB.OneTb values(,'user4',),(,'user5',),(,'user6',) /*!*/; # at # :: server id end_log_pos Query thread_id= exec_time= error_code= SET TIMESTAMP=/*!*/; update Test_DB.OneTb set name='user10' /*!*/; # at # :: server id end_log_pos Stop DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
从上面可以看到我们在做插入正常数据后的position 是2698,那么使用下面的命令导出sql
[root@hcloud ~]# mysqlbinlog --stop-position="" /var/lib/mysql/mysql-bin. > Backup_1.sql
然后导出mysql-bin.00002的sql 语句(注:由于演示操作,该binlog文件只有一个drop 表操作,所以不做处理,但是在实际环境中,由于中途可能会有重启数据库操作,那时就需要检测最新的binlog有没有业务需要的语句。)
sql 语句已经导出来了。我们可以利用该语句直接恢复所有正常的数据。
注:本次恢复没有利用到之前的完整备份,因为我是开启binlog后,然后才做的所有建库建表操作,第一个binlog文件里已经记录了所有的数据库操作,所以不需要使用之前的完整备份(另外:实际的生产环境,还是需要利用到完整备份的,因为线上环境可能会有N多个binlog文件,所以需要利用到完整备份和最新的binlog文件来结合恢复)
开始恢复前,我们将原有的Test_DB数据库也给干掉吧。毕竟我们的binlog中有创建操作
mysql> DROP DATABASE Test_DB;
Query OK, rows affected (0.03 sec)
恢复数据库时还可以利用在登陆mysql 后,用source 命令导入sql语句,这里暂不介绍
[root@hcloud ~]# mysql -uroot -p < Backup_1.sql
Enter password:
恢复完成后,我们检查下表的数据是否完整
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| Test_DB |
| mysql |
+--------------------+
rows in set (0.00 sec) mysql> select * from Test_DB.OneTb;
+----+-------+------+
| id | name | age |
+----+-------+------+
| | user1 | |
| | user2 | |
| | user3 | |
| | user4 | |
| | user5 | |
| | user6 | |
+----+-------+------+
rows in set (0.00 sec)
Ok完整的都恢复过来了。
三、总结
1) 恢复方式
a) 利用最新一次的完整备份加binlog 指定事件起始时间和终止时间或者position恢复数据库
b) 利用所有binlog指定事件起始位置和终止时间来合并sql文件恢复数据库(此方法要确保binlog文件的完整)
c) 利用mysqldump 使用完整恢复。(在确保最新一次的完整备份后的数据不重要,允许丢掉的情况下,直接恢复。该方法最简单、效率最高)
2) 附:官方建议的备份原则(为了能睡个好觉….嗯,是的)
a) 在mysql安装好并运行时,就始终开启 log-bin选项,该日志文件位于datadir目录下,也要确保该目录所在存储介质是安全的。
b) 定期做完整的mysql 备份。
c) 定期使用 FlUSH LOGS 或者 mysqladmin flush-logs ,该操作会关闭当前的二进制日志文件,并新建一个binlog日志文件。(和重启mysql后新建的binlog操作一样)。以备份binlog日志,利用binlog日志也可以做增量备份。
参考文章:
mysql官方文档:http://dev.mysql.com/doc/refman/5.6/en/point-in-time-recovery.html
本文属于原创,如有转载请务必注明出处。飞走不可:http://www.cnblogs.com/hanyifeng/p/5756462.html
Linux 上通过binlog文件 恢复mysql 数据库详细步骤的更多相关文章
- 利用日志文件恢复MYSQL数据库
利用日志文件恢复MYSQL数据库 650) this.width=650;" onclick='window.open("http://blog.51cto.com/viewpic ...
- java连接mysql数据库详细步骤解析
java连接mysql数据库详细步骤解析 第一步:下载一个JDBC驱动包,例如我用的是:mysql-connector-java-5.1.17-bin.jar 第二步:导入下载的J ...
- 利用data文件恢复MySQL数据库
背景:测试服务器 MySQL 数据库不知何种原因宕机,且无法启动,而原先的数据库并没有备份,重新搭建一个新服务器把原data 复制出来 进行恢复 1 尽量把原data复制出来(一个都不要少以防意外 其 ...
- 用(*.frm *.MYD *.MYI)文件恢复MySql数据库
保存下来以防以后遇到 今天还原mysql数据库时,看到那个data文件夹下好几个文件,还没有.sql文件,没有见过,总结下.Data文件夹里面包括:数据库名文件夹,文件夹里包括,*.frm,*.MYI ...
- ASP.NET 连接MySQL数据库 详细步骤
ASP.NET默认的数据库是MS SQL Server,微软的数据库产品.事实上,如果不计成本因素的话,Windows Server + IIS + MS SQL Server + ASP.NET是网 ...
- C#连接操作MySQL数据库详细步骤 帮助类等(二次改进版)
最近准备写一个仓库管理的项目 客户要求使用C#编写MySQL存储数据 为了方便,整理了数据库操作的工具类 首先在项目App.config 文件下添加节点 <connectionStrings&g ...
- 烂泥:通过binlog恢复mysql数据库
本文由秀依林枫提供友情赞助,首发于烂泥行天下. 在上一篇文章,我们讲解了有关mysql的binlog日志的基础知识.这篇文章,我们来讲解如何通过mysql的binlog日志来恢复数据库. 在使用bin ...
- Linux VPS自动定时备份网站文件和MYSQL数据库到FTP空间(LNMP)
如果我们网站更新不是很频繁,我们可以定期手动进行备份网站文件和MYSQL数据库导出.如果我们网站数据更新频繁,且数据尤为重要,建议要采用定期自动 备份,至少需要多备份数据,无论我们选择何种优秀的VPS ...
- 如何在删除ibdata1和ib_logfile的情况下恢复MySQL数据库
昨天,有个朋友对公司内部使用的一个MySQL实例开启binlog,但是在启动的过程中失败了(他也没提,为何会失败),在启动失败后,他删除了ibdata1和ib_logfile,后来,能正常启动了,但所 ...
随机推荐
- [Scala]Scala学习笔记六 文件
1. 读取行 读取文件,可以使用scala.io.Source对象的fromFile方法.如果读取所有行可以使用getLines方法: val source = Source.fromFile(&qu ...
- 如何定位BAD_ACCESS
1.访问了野指针,比如对一个已经释放的对象执行了release.访问已经释放对象的成员变量或者发消息. 死循环 如何调试BAD_ACCESS错误 1.重写object的respondsToSelect ...
- 02-C与OC语言的一些小知识
1. #import 跟#include.@class有什么区别?#import<> 跟 #import”"又什么区别? 1> #import和#inclu ...
- weight decay (权值衰减)
http://blog.sina.com.cn/s/blog_890c6aa30100z7su.html 在机器学习或者模式识别中,会出现overfitting,而当网络逐渐overfitting时网 ...
- 去除inline-block元素间间距的N种方法(转)
一.现象描述 真正意义上的inline-block水平呈现的元素间,换行显示或空格分隔的情况下会有间距,很简单的个例子: <input /> <input type="su ...
- SLIP 协议
SLIP 协议 SLIP 英文原义:Serial Line Internet Protocol 中文释义:串行线路网际协议 注解:该协议是Windows远程访问的一种旧工业标准,主要在Unix远程访问 ...
- 基于NodeJS的全栈式开发(基于NodeJS的前后端分离)
也谈基于NodeJS的全栈式开发(基于NodeJS的前后端分离) 前言 为了解决传统Web开发模式带来的各种问题,我们进行了许多尝试,但由于前/后端的物理鸿沟,尝试的方案都大同小异.痛定思痛,今天我们 ...
- 获得消息的x,y的窗口内坐标(包括边框和titlebar高度
rectWindow = D2D.GetWindowRect(self.hwnd)#窗口大小 rectClient = D2D.GetWindowRect(self.hwnd,True)#客户区大小 ...
- c++ hook 钩子的使用介绍
转自:http://www.cnblogs.com/lidabo/archive/2012/11/29/2795269.html 例子:http://www.codeproject.com/Artic ...
- Nchan 实时消息 安全配置
备注: 即时消息的安全对于我们来说是比较重要的,作者在设计Nchan 的时候已经考虑了 a. nchan_authorize_request (Hooks and Callbacks)可以集成 ...