你想删库吗
Posted 程序员大咖
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了你想删库吗相关的知识,希望对你有一定的参考价值。
????????关注后回复 “进群” ,拉你进程序员交流群????????
作者丨故里
来源丨故里学Java
删库跑路的案例不在少数,今年最出名的删库跑路当属微盟,造成公司市值蒸发几十亿,赔偿商家1.5亿元,最终在腾讯云的协助下经过7*24小时的不懈努力,最终找回全部数据。我们都知道,数据就是一个公司的“命根子”,无论什么时候,数据安全都是最重要的。所以我们今天来聊聊数据恢复的几种方式。以mysql为例。
binlog是二进制日志文件,用户记录用户对数据库的操作,各个从库的同步也是通过binlog,是非常重要的数据库日志文件,其他的关系型数据库的数据恢复也是大同小异的,例如Oracle数据库可以通过它的归档日志进行恢复。
我们该如何数据恢复?
具体如何恢复数据,要看使用的哪种备份方案,主流的备份方案主要有以下几种:
全量备份
数据量比较小,全量恢复比较快,例如每天晚上零点进行全量备份,如果想恢复20号以前的数据,直接把20号以前的备份全量恢复就行了
还有一种情况是恢复7号0:00到23:59的数据,这种情况就只能用binlog来恢复了。
全量+增量备份
全量+增量的备份方案适合数据量较大的数据库,节约磁盘空间,但是全量恢复较慢。如每月1号进行全量备份,后续的每天晚上零点进行增量备份,如果想恢复7号零点以前数据,就只需要恢复1号的全量数据,和2号到7号的增量备份。这种情况如果要恢复7号0:00到23:59的数据也是只能用binlog来恢复。
我们先不讨论每一种方案的效率问题,先看一下如果利用binlog进行恢复。
binlog的三种模式:
在MySQL5.7.7以前的版本默认模式是Statement Level,之后默认模式就是Row Level。
Statement Level:基于SQL语句复制的,只会讲SQL语句存储到日志中,因为这种模式只存储SQL,没有真正的数据,所以我们无法进行数据恢复。生产环境也一般不用这种模式。
Row Level:它是基于行的复制,并且会将每一条数据的变化记录到日志文件中,是没有sql语句的,可以解析出数据,一些生产环境是使用这种模式,但是它也有一定的缺点,比如记录数据时产生大佬的binlog,面对存储过程时可能出现数据不一致的情况。
Mixed:混合模式,默认情况下是Statement模式,某些情况下切换到Row模式,结合了Row Level和Statement Level的优点,同时binlog结构也更加复杂。
查看数据库采用的模式:
以MySQL5.7.21为例:
mysql>show variables like 'binlog_format';
下边开始尝试用binlog进行数据解析和恢复了。
先建立一些基础数据:
root@localhost(demo) 14:23:31> CREATE TABLE 't1' (
-> 'id' int NOT NULL AUTO_INCREMENT,
-> 'name' varchar(60) DEFAULT NULL,
-> ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSE=utf8;
Query OK,0 rows affected (0.02 sec)
root@localhost(demo) 14:23:31> insert into t1(name) values('demo1'),('demo2');
Query OK,2 rows affected (0.00 sec)
Records:2duplicates:0 Warnings:0
查找包含插入数据的时间(14:23:31)的binlog文件
[root@localhost binlog]# ll mysql-bin.000009
-rw-r----- 1 mysql mysql 837Mar 2 14:23 mysql-bin.000009
我们可以看到是mysql-bin.000009文件,它是一个二进制文件,我们可以用MySQL自带的工具mysqlbinlog进行解析,看看具体的内容
[root@10-0-4-162 binlog]# /usr/local/mysql/bin/mysqlbinlog --base64-output=decode-rows -v mysql-bin.000009
解析后删除无关的内容后,正向解析得到的sql和我们先前插入数据的sql一致
......
# at 259
......
CREATE TABLE 't1' (
'id' int NOT NULL AUTO_INCREMENT,
'name' varchar(60) DEFAULT NULL,
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSE=utf8
......
### INSERT INTO `demo`.`t1`
### SET
### @1=1
### @2='demo1'
###INSERT INTO `demo`.`t1`
###SET
### @1=2
### @2='demo2'
COMMIT/*!*/;
......
我们解析数据的目的是恢复数据,例如,将前面的insertSQL解析成deleteSQL语句,因为insert可能是误插入的数据,如果数据量较小可以手动删除,如果是生产环境,binlog文件可能非常大,解析后的SQL可能有千万行,手动修改不太现实,那么如何生成反向sql呢,我们将介绍两个数据恢复工具,binlog-rollback和MyFlash。
我们先用binlog-rollback试一下,其实这就是给perl脚本。
[root@localhost ~]# perl binlog-rollback.pl -f '/u01/mysql/3306/log/binlog/mysql-bin.000009' -h 127.0.0.1 -u 'root' -p '1234' -P 3306 -i -o '/tmp/t.sql'
[root@localhost ~]# more /tmp/t.sql
DELETE FROM `demo`.`t1`WHERE 'id' = 2 AND `name` = 'demo2';
DELETE FROM `demo`.`t1`WHERE 'id' = 1 AND `name` = 'demo1';
可以看的我们之前insert的两行数据,这里解析成了delete了,达到了我们恢复数据的目的,当我们误删除数据时候,反解的SQL就成了insert,这样就可以达到数据恢复的目的。
我们再来试试MyFlash工具,这个工具在反解binlog的时候不需要用户名密码。同时我们也进行了查看发现确实由insert语句变成了delete。
但是这两种方式是有差别的,binlog-rollback生成sql,可读性更好,但是当数据量比较大的时候,MyFlash就比较快。
[root@localhost MyFlash-master]# ./binary/flashback -- binlogFileNames=/u01/mysql/3306/log/binlog/mysql-bin.000009
[root@localhost MyFlash-master]# mysqlbinlog --base64-output=decode-rows -v binlog_output_base.flashback
......
### DELETE FROM `demo`.`t1`
### WHERE
### @1=1
### @2='demo1'
###DELETE FROM `demo`.`t1`
### WHERE
### @1=2
### @2='demo2'
......
总结:正向解析sql我们可以使用mysql自带的mysqlbinlog,反向解析我们可以使用binlog-rollback和MyFlash。
-End-
最近有一些小伙伴,让我帮忙找一些 面试题 资料,于是我翻遍了收藏的 5T 资料后,汇总整理出来,可以说是程序员面试必备!所有资料都整理到网盘了,欢迎下载!
点击????卡片,关注后回复【面试题
】即可获取
在看点这里好文分享给更多人↓↓
以上是关于你想删库吗的主要内容,如果未能解决你的问题,请参考以下文章
ruby 如果你想在heroku上为你的中间人应用程序添加基本身份验证,这是一个添加到middleman的config.ru文件的片段