在操作数据库的时候,总会有些时候那么的手贱,导致数据丢失,如果是测试环境还好,但是要是正式环境,那就删库跑路吧。其实,如果你打开的bin-log,这些操作还是可以被还原的。
开启bin-log
bin-log是MySQL的主从复制中开启的一个选项,在 /etc/my.cnf
中有两个配置如下
1 | # Remove leading # to turn on a very important data integrity option: logging |
其中 我们需要关注的 log_bin
server_id
这两个,配置到你需要的地方即可,server_id
可以随意,主从不要冲突即可,个人配置如下
1 | log_bin=/data/logs/mysql/mysql-bin.log # binlog日志文件 |
重启一下MySQL,然后进入数据库,查看一下bin-log的状态
1 | mysql> show variables like 'log_bin%'; |
其中 log_bin
的值为On
即表明已经开启了 log_bin
开始手贱吧
制作点假数据
我们开始创建点假数据,用于我们的测试
1 | mysql> create database test; |
先来5条数据,然后我们备份一下这个表,备份之前,先介绍一下--master-data
这个参数
1 | --master-data[=#] This causes the binary log position and filename to be |
我们在备份的时候,需要加上这条参数,并将其设置为2,以方便我们查找我们丢失的那部分数据
1 | mysqldump -uroot -p --master-data=2 test > test.sql |
备份完成了,我们再加点假数据,最后看一下这些数据会不会还在
1 | mysql> insert into binlog_test values (6), (7), (8), (9), (10); |
手贱吧
1 | mysql> delete from binlog_test; |
这样的话,binlog_test表的数据应该全部都没有了。
开始正文了-恢复数据
先查看一下 备份的偏移
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23λ /data/mysql more test.sql
-- MySQL dump 10.13 Distrib 5.7.18, for Linux (x86_64)
--
-- Host: localhost Database: test
-- ------------------------------------------------------
-- Server version 5.7.18-log
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Position to start replication or point-in-time recovery from
--
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000002', MASTER_LOG_POS=627;从备份的sql文件可以看到,我们备份的偏移文件是 mysql-bin.000002 ,偏移量是 627
查看手贱命令的偏移
我们这时候应该就是查找一下 我们执行的delete操作的偏移
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18λ /data/mysql mysqlbinlog --base64-output=decode-rows mysql-bin.000002 | grep Delete -8
# at 974
#180717 16:37:59 server id 1 end_log_pos 1046 CRC32 0x19b80686 Query thread_id=6 exec_time=0 error_code=0
SET TIMESTAMP=1531816679/*!*/;
BEGIN
/*!*/;
# at 1046
#180717 16:37:59 server id 1 end_log_pos 1100 CRC32 0x2daa51e1 Table_map: `test`.`binlog_test` mapped to number 514
# at 1100
#180717 16:37:59 server id 1 end_log_pos 1185 CRC32 0x05ebafa5 Delete_rows: table id 514 flags: STMT_END_F
# at 1185
#180717 16:37:59 server id 1 end_log_pos 1216 CRC32 0x56c7fe9e Xid = 80
COMMIT/*!*/;
# at 1216
#180717 16:44:14 server id 1 end_log_pos 1281 CRC32 0xa285c84c Anonymous_GTID last_committed=4 sequence_number=5
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 1281
#180717 16:44:14 server id 1 end_log_pos 1405 CRC32 0x4474e0a7 Query thread_id=10 exec_time=0 error_code=0我们可以看到,在第10行的时候进行了删除操作,在第8行进行了表的map映射查找,那我们这时候,将结束的偏移就可以定位到 mysql-bin.000002 的 1100 position
生成备份到手贱这段时间的数据
由于,我们仅仅对test库进行处理,所以我们可以在使用
mysqbinlog
处理的时候指定test
库即可,主要用到了以下几个参数,可参考1
2
3
4
5
6
7λ /data/mysql mysqlbinlog --help | grep position -8
-j, --start-position=#
Start reading the binlog at position N. Applies to the
first binlog passed on the command line.
--stop-position=# Stop reading the binlog at position N. Applies to the
last binlog passed on the command line.
-d, --database=name List entries for just this database (local log only).1
mysqlbinlog --start-position=627 --stop-position=1100 --database=test mysql-bin.000002 > binlog_test_drop.sql
这样,我们需要的原始备份文件,和中间缺失的时间段的备份文件就都生成好了,下一步就可以恢复了
恢复
1
2mysql -uroot -p test < test.sql
mysql -uroot -p test < binlog_test_drop.sql查看一下吧
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15mysql> select * from binlog_test;
+----+
| id |
+----+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
| 7 |
| 8 |
| 9 |
| 10 |
+----+至此,基本大功告成了,当然bin-log不仅仅是用来恢复数据的,上文也讲过了,MySQL的主从就是要依靠他来完成的,下一篇文章《MySQL主从配置》将会简单的介绍一下