关注微信公众号【程序员白泽】,进入白泽的知识分享星球

前言

作为《手撕MySQL》系列的第二篇文章,今天介绍一下MySQL的二进制日志(bin log),注意不要和MySQL的InnoDB存储引擎特有的重写日志(redo log)混淆,bin log是记录所有数据库表数据及表结构变更的二进制日志(不会记录查询操作),借助这个日志可以实现:数据恢复主从复制(不难理解,因为所有涉及变更的操作都记录了下来,可以追溯)。

这篇文章侧重于讲解使用bin log进行数据恢复,下一篇文章讲解主从复制

预备知识

SSH工具推荐

接下来会频繁在控制台终端中输入命令,因此推荐一款开源免费的ssh客户端electermhttps://github.com/electerm/electerm,这是地址,可以直接下载安装,非常好用!

bin log 状态管理

在开始讲解bin log可以提供的两个功能之前,先要学会管理自己MySQL服务的bin log状态,并且通过修改参数对其进行控制。先来查看一下自己MySQL服务是否已经开启了bin log,可以看到我的二进制日志已经开启。如果你的没有,这里建议通过修改MySQL配置文件的方式将bin log声明为开启,然后重新启动MySQL服务即可。

以Linux系统为例,MySQL数据库是按照 /etc/my.cnf —— /etc/mysql/my.cnf —— /usr/local/mysql/etc/my.cnf —— ~/.my.cnf 的顺序读取配置文件的,且如果出现参数重复设置则后一个配置文件中参数会覆盖前者。如果你的MySQL服务没有配置文件,那就直接自己创建一个,放在上面某个位置之一,然后在创建的配置文件中输入你从网上搜到的设置bin log开启的配置代码,重启MySQL服务即可。

现在假设你已经开启了MySQL的二进制日志,如下:

mysql> show variables like '%log_bin%';

bin log 数据文件

观察上面的查询结果,可以看到两个路径变量:log_bin_basenamelog_bin_index,分别表示bin log开启后,数据文件的生成位置(/usr/local/mysql/data/)和文件名规则(binlog.xxxxx1、binlog.xxxxx2以此类推),以及索引文件binlog.index,其中存放着bin log数据文件列表。

# 查看MySQL数据文件列表(大部分MySQL数据文件都在这个路径下,下面展示部分,主要是bin log相关的数据文件和索引文件)
lilithgamesdeMacBook-Pro-42:~ lilithgames$ sudo ls -al /usr/local/mysql/data

# 查看bin log索引文件内容(完全对应上面列出的三个数据文件)
lilithgamesdeMacBook-Pro-42:~ lilithgames$ sudo cat /usr/local/mysql/data/binlog.index

既然上面说到,bin log记录所有对数据库的更改操作,那么它是将SQL语句记录在数据文件中还是将改动之后的行结果记录下来呢?这里有三种记录模式:

  • ROW:数据文件中会记录每一行数据被修改的情况,这样就能保证在恢复数据或者主从复制时不会因为一些函数(如now()函数执行两次获取的时间是不一致的)导致数据不完全一致的情况,缺点是对于整张表的修改会导致大量数据插入到数据文件中。
  • SRATEMENT:记录修改数据的SQL语句,和ROW相反,在数据同步时,某些情况下会出现不完全一致的情况。
  • MIXED:混合使用上面两种记录模式,在一般情况下使用SRATEMENT,在特殊情况使用ROW。

但是,新版本MySQL的ROW模式已经进行了优化,对于表结构的修改会以STATEMENT模式记录,而对于记录的修改则会在数据文件中记录所有的行的变更。因此,ROW模式是bin log默认的工作模式。

mysql> show variables like 'binlog_format';

数据恢复

准备数据

Talk is cheap,show me the code!我知道你已经迫不及待想体验bin log的数据恢复了,那就让我们开始吧~

为了方便展示,我们在MySQL登录态下执行flush logs命令,可以生成一个新的日志文件(为了将后面操作数据库的命令单独放在一个新的数据文件中方便查看)

# 生成新的二进制数据文件(序号增加)
mysql> flush logs;
# 查看当前所有二进制数据文件
mysql> show binary logs;

因为我执行了两次flush log命令,因此以此生成了两个新的二进制数据文件,而且明显可以看到这两个数据文件很小,因为还没有新的修改表的操作被记录下来。

接下来我们建立一个测试数据库:test_database,然后创建一张用户表,并且为其插入几条测试数据。

# 创建user表
CREATE TABLE `user` (`id` int(11) NOT NULL AUTO_INCREMENT,
`username` VARCHAR(255) NOT NULL,
PRIMARY KEY (`id`)) ENGINE = INNODB DEFAULT CHARSET=utf8;
# 插入测试用户数据
INSERT INTO user (id, username) VALUES (null, 'AAA');
INSERT INTO user (id, username) VALUES (null, 'BBB');
INSERT INTO user (id, username) VALUES (null, 'CCC');
# 查询测试
SELECT * FROM user

接下来我们通过mysqlbinlog命令来查看bin log的数据文件(猜测表的变更被记录在binlog.000010二进制文件中),这里展示一部分。

sudo mysqlbinlog /usr/local/mysql/data/binlog.000010

下面是binlog.000010文件的部分内容,我们找到了建user表的语句(上面说了,新版MySQL的ROW数据记录模式对于表结构的更改是STATEMENT形式的),下面是数据文件中一些重要的字段解释:

  • 第一个at表示一个事件的起始位置pos,中间的是此次事件的二进制数据,而末尾的at表示下一个事件开始位置pos(也就是当前时间的结束位置pos)
  • 220303 17:59:37 server id 1 表示server 1执行该事件的时间
  • exec_time 表示执行时间(具体时间在主从复制时master和slave有所不同,下篇文章讲解)

# 这个mysqlbinlog命令还可以添加参数,如指定查询开始pos到结束pos之间的数据,Google一下~
sudo mysqlbinlog /usr/local/mysql/data/binlog.000010
# 当然,不借助mysqlbinlog命令,在mysql登录状态下也是可以直接查询bin log数据文件内容的,测试如下:
mysql> show binlog events in 'binlog.000010' from 447 limit 10;

模拟失误

# 失误删除id为1的用户
DELETE FROM user where id=1
# 又插入两个用户
INSERT INTO user (id, username) VALUES (null, 'DDD');
INSERT INTO user (id, username) VALUES (null, 'EEE');

数据恢复

要明确的是:借助bin log二进制日志文件进行数据恢复的本质,是重新执行两个pos区间内的SQL(所以上面才花了较大篇幅讲解查看二进制文件,为的是学会定位pos点,也就是at后面那个数字)

首先通过mysql命令查看binlog.000010数据文件

mysql> show binlog events in 'binlog.000010';

这里要找到两个pos点,一个是user表建立的pos:447,另一个是执行delete操作之前的pos,这里要求结束的pos不能直接选择delete_rows操作的pos:1864,而是要选择它前一个commit事件的下一个pos:1636(否则会出现警告️)

使用mysqlbinlog命令生成pos为447—1636之间的SQL文件(上面说了数据恢复的本质是重新执行两个pos区间内的SQL语句),通过下面的命令,生成了一个return.sql文件。

sudo mysqlbinlog --start-position=447 --stop-position=1636 /usr/local/mysql/data/binlog.000010 > return.sql

执行return.sql文件(相当于又执行了一遍这个区间的SQL语句),进行数据恢复!大功告成!删除的AAA回来了!!不用被开除了!!

mysql> source ~/return.sql

结束语

本篇文章简单讲述了利用bin log进行数据恢复的案例,并且花费了较大篇幅讲解一些bin log的基础知识,为的是为后续讲解利用bin log进行主从复制打下基础,希望阅读本文之后,您感到对二进制日志的理解在八股文的基础之上,更进一步了。

我是白泽,一名后端程序员/学生党,建了一个春秋招备战/内推/闲聊群,欢迎大家加入。

下面是我的微信以及公众号,关注公众号【程序员白泽】,回复简历可以获取我正在使用的简历模板。

MySQL通过bin log日志恢复数据|手撕MySQL|对线面试官的更多相关文章

  1. 浅谈MySQL日志文件|手撕MySQL|对线面试官

    关注微信公众号[程序员白泽],进入白泽的知识分享星球 前言 上周五面试了字节的第三面,深感数据库知识的重要,我也意识到在平时的学习中,自己对于数据库的学习较为薄弱.甚至在有过一定实习经验之后,依旧因为 ...

  2. 解说mysql之binlog日志以及利用binlog日志恢复数据

    众所周知,binlog日志对于mysql数据库来说是十分重要的.在数据丢失的紧急情况下,我们往往会想到用binlog日志功能进行数据恢复(定时全备份+binlog日志恢复增量数据部分),化险为夷! 废 ...

  3. Mysql之binlog日志说明及利用binlog日志恢复数据操作记录

    众所周知,binlog日志对于mysql数据库来说是十分重要的.在数据丢失的紧急情况下,我们往往会想到用binlog日志功能进行数据恢复(定时全备份+binlog日志恢复增量数据部分),化险为夷! 一 ...

  4. 练手mysqlbinlog日志恢复数据(centos6.5 64,mysql5.1)

    练手mysql bin log日志相关 系统是centos 6.5 64 阿里云的服务器 mysql版本5.1 1 如何开启bin-log日志? vi /etc/my.cnf [mysqld] log ...

  5. 【转】Mysql之binlog日志说明及利用binlog日志恢复数据操作记录

    众所周知,binlog日志对于mysql数据库来说是十分重要的.在数据丢失的紧急情况下,我们往往会想到用binlog日志功能进行数据恢复(定时全备份+binlog日志恢复增量数据部分),化险为夷! 废 ...

  6. MySQL二进制binlog日志说明以及利用binlog日志恢复数据

    MySQL的binlog日志对于mysql数据库来说是十分重要的.在数据丢失的紧急情况下,我们往往会想到用binlog日志功能进行数据恢复(定时全量备份+binlog日志恢复增量数据部分). 一.关于 ...

  7. Mysql利用binlog日志恢复数据操作(转)

    a.开启binlog日志:1)编辑打开mysql配置文件/etc/mys.cnf[root@vm-002 ~]# vim /etc/my.cnf在[mysqld] 区块添加 log-bin=mysql ...

  8. MySQL通过binlog日志恢复数据

    一.查看下自己的MySQL是否开启了binlog日志 # 是否启用binlog日志 OFF:关闭 ON:开启 show variables like 'log_bin'; 二.开启binlog日志 在 ...

  9. 转-->>mysql的bin log

    binlog 基本认识 MySQL的二进制日志可以说是MySQL最重要的日志了,它记录了所有的DDL和DML(除了数据查询语句)语句,以事件形式记录,还包含语句所执行的消耗的时间,MySQL的二进制日 ...

随机推荐

  1. 搭建服务器之FTP

    FTP服务器,使用软件vsftpd,服务守护进程也是vsftpd.客户端访问的话可以用浏览器或ftp命令行. 1.yum install vsftpd.安装简单主要是配置,这个比httpd复杂点的地方 ...

  2. 定位new

    常规的new是分配内存,然后调用相应的构造函数,而定位new是在已经分配内存的上面调用构造函数: // ConsoleApplication7.cpp : 定义控制台应用程序的入口点. #includ ...

  3. javaObject类—hashCode方法

    1 package face_object; 2 /* 3 * Object:所有类的根类. 4 * Object是不断抽取而来的,具备所有对象都具备的共性内容. 5 * 常用的共性功能: 6 * 7 ...

  4. 学习Java第9天

    今天所作的工作: 反射,枚举类型与泛型 明天工作: 1.线程 2.网络通信 所遇到的问题及解决方法: 反射基本思想,泛型类似于类模板. 理解反射太难了,转悠了好半天,关键是理解反射的思想,才容易学.

  5. 面向计算机视觉的深度学习 | iBooker·ApacheCN

    原文:Deep Learning for Computer Vision 协议:CC BY-NC-SA 4.0 自豪地采用谷歌翻译 不要担心自己的形象,只关心如何实现目标.--<原则>,生 ...

  6. 「CTSC 2011」排列

    「CTSC 2011」排列 要求不存在公差为 A 或者公比为 B 的子列,那么实际上可以把该问题转化为求一个图的最优拓朴序. 任意差为 A 或者比为 B 的两个数连一条边. 求一个合法序列的答案可以用 ...

  7. Git提示“warning: LF will be replaced by CRLF”

    感谢原文作者:萌新李同学(李俊德-大连理工大学) 原文链接:https://blog.csdn.net/wq6ylg08/article/details/88761581 问题描述 windows平台 ...

  8. java命令-(学习)jstack 工具

    一.介绍 jstack是java虚拟机自带的一种堆栈跟踪工具.jstack用于打印出给定的java进程ID或core file或远程调试服务的Java堆栈信息,如果是在64位机器上,需要指定选项&qu ...

  9. UIFont

    UIFont代表字体,常见创建方法有以下几个:+ (UIFont *)systemFontOfSize:(CGFloat)fontSize; 系统默认字体+ (UIFont *)boldSystemF ...

  10. iOS中播放音效

    #import "ViewController.h" #import <AVFoundation/AVFoundation.h> @interface ViewCont ...