前言

相信每一个学IT的人或多或少都听说过从删库到跑路这个梗~下图也是在各种交流群屡禁不止,新人听着也是瑟瑟发抖。

人们茶余饭后,街头巷角难免要问。。。

下面技术流ken就教给各位新手们一招删库再也不用跑路的绝技~

实现原理

想要学会这个技能务必先要看我的这篇有关mysql日志的博客《MySQL系列详解三:MySQL中各类日志详解-技术流ken》。

一定要先了解二进制日志文件的作用

二进制日志记录了对数据库执行更改的所有操作,但是不包括 select 和 show 这类操作,因为这类操作对数据本身并没有修改,如果你还想记录select和show操作,那只能使用查询日志了,而不是二进制日志。
 
此外,二进制还包括了执行数据库更改操作的时间和执行时间等信息。 二进制日志主要有以下几种作用 :
 

恢复(recovery) :

 
某些数据的恢复需要二进制日志,如当一个数据库全备文件恢复后,我们可以通过二进制的日志进行 point-in-time 的恢复
 

复制(replication) :

通过复制和执行二进制日志使得一台远程的 MySQL 数据库(一般是slave 或者 standby) 与一台MySQL数据库(一般为master或者primary) 进行实时同步
 

审计(audit) :

用户可以通过二进制日志中的信息来进行审计,判断是否有对数据库进行注入攻击

数据库备份

有人会有疑惑数据库都被我删了,哪还有什么备份?

殊不知,在你删库之前你们公司的运维工程师或者DBA已经悄悄的对数据库做了备份~

而且这个备份不是在你的电脑或者mysql服务器上面,可能已经被传送到了你们主管,DBA或者某台专用的备份服务器哪里去了,这个实现起来非常简单,运维工程师通过脚本就可以自动完成这个工作,总之他们肯定会有一份数据库的备份的~

但是他们的这个备份并不是完整备份,什么意思那

可能你们公司的数据库备份策略是周末做全量备份,周一至周六是做的增量备份,而且是每天只做一次增量备份

比如你们公司做增量备份是每天的凌晨时间,而你删库的时间是在早晨10点钟,那么这10个小时的数据,就没有备份了~

如果你们公司做的比较风生水起,在这十个小时的时间内有10万条的写入记录,你是不是会心口发塞,准备跑路了~

不要慌

第一时间去找你们公司的DBA问他有没有最新的数据库备份文件

如果他说没有。。

告诉他你把库删了,让他跟着你一起慌。。

但是你是看过我这篇博客的人,淡定

第二时间去找你们公司的运维工程师

他们肯定有!

总之无论你删了什么重要文件,都去找运维工程师,他们肯定有!他们就是一群没事爱做自动化备份的人

他们会告诉你:XX文件都被同步在了XX服务器上面了

恢复数据库

在DBA手里可以拿到全量备份以及增量备份的数据库文件,在运维工程师手里可以任何实时的二进制文件。

这个时候第一时间先去二进制服务器上面再次对二进制日志文件做一个备份!

这次能不能不跑路,就看这个二进制日志文件了。

拿到这些文件之后,现在就可以对数据库进行恢复了。

删库之后一定要先把数据库服务停掉,这是重点!

有了全量备份的文件,增量备份的文件以及二进制文件之后,就去拜托你们公司的DBA或者运维工程师来进行数据的恢复即可。

模拟删除数据表

接下来就完整演示从删表到数据恢复的过程

第一步:查看是是否开启了二进制日志

显示log_bin是开启的,没有问题

mysql> show global variables like "%log%bin%";
+----------------------------------+--------------------------------------------+
| Variable_name | Value |
+----------------------------------+--------------------------------------------+
| log_bin | ON |
| log_bin_basename | /data/mysql/mysql3306/logs/mysql-bin |
| log_bin_index | /data/mysql/mysql3306/logs/mysql-bin.index |
| log_bin_trust_function_creators | ON |
| log_bin_use_v1_row_events | OFF |
| log_statements_unsafe_for_binlog | ON |
+----------------------------------+--------------------------------------------+
rows in set (0.00 sec)

第二步:添加一些数据

我们首先往数据库中添加一些数据

下面我创建了一个ken数据库

ken数据库中创建了一个kenken数据表

在这个表中插入了一些数据

mysql> create database ken;
Query OK, row affected (0.00 sec) mysql> use ken;
Database changed
mysql> create table kenken(id int auto_increment primary key not null,name char()not null,tel int)
-> ;
Query OK, rows affected (0.03 sec) mysql> desc kenken;
+-------+----------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+----------------+
| id | int() | NO | PRI | NULL | auto_increment |
| name | char() | NO | | NULL | |
| tel | int() | YES | | NULL | |
+-------+----------+------+-----+---------+----------------+
rows in set (0.06 sec) mysql> insert into kenken (id,name,tel) values (,"鲁班",);
Query OK, row affected (0.01 sec) mysql> insert into kenken (id,name,tel) values (,"后裔",);
Query OK, row affected (0.00 sec) mysql> insert into kenken (id,name,tel) values (,"韩信",);
Query OK, row affected (0.00 sec) mysql> select * from kenken;
+----+--------+------+
| id | name | tel |
+----+--------+------+
| | 鲁班 | |
| | 后裔 | |
| | 韩信 | |
+----+--------+------+
rows in set (0.00 sec)

第三步:模拟DBA做全量备份

这样我们就获得了一个数据库全量备份的文件

[root@ken ~]# mysqldump -uroot -p --all-databases --single-transaction --flush-logs --set-gtid-purged=OFF --master-data= >/tmp/ken.sql
Enter password:
[root@ken ~]# tail /tmp/ken.sql /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; -- Dump completed on -- ::

第四步:模拟数据写入

备份完成之后我们模拟数据写入,相当于在凌晨到早上十点钟这段时间

下面我又增加了四条记录,在备份文件中是没有的

mysql> insert into kenken (name,tel) values ("不知火舞",);
Query OK, row affected (0.00 sec) mysql> insert into kenken (name,tel) values ("d貂蝉",);
Query OK, row affected (0.00 sec) mysql> insert into kenken (name,tel) values ("明世隐",);
Query OK, row affected (0.00 sec) mysql> insert into kenken (name,tel) values ("李白",);
Query OK, row affected (0.00 sec) mysql> select * from kenken;
+----+--------------+------+
| id | name | tel |
+----+--------------+------+
| | 鲁班 | |
| | 后裔 | |
| | 韩信 | |
| | 不知火舞 | |
| | d貂蝉 | |
| | 明世隐 | |
| | 李白 | |
+----+--------------+------+
rows in set (0.00 sec)

第五步:模拟数据删除

现在是早晨10点钟,你把这个表删掉了

现在在备份文件中是没有这个新添加的表中的数据的

mysql> drop table kenken;
Query OK, rows affected (0.01 sec) mysql> select * from kenken;
ERROR (42S02): Table 'ken.kenken' doesn't exist

模拟恢复数据表

第一步:查看二进制文件

进入到你们公司的二进制日志保存位置

下面这些就是二进制日志文件

[root@ken ~]# cd /data/mysql/mysql3306/logs/
[root@ken logs]# ls
mysql-bin. mysql-bin. mysql-bin. mysql-bin. mysql-bin.index

第二步:查看全量备份文件

在大约22行处记录了:

自备份起,新开始的二进制日志文件保存的位置

非常重要

[root@ken logs]# vim /tmp/ken.sql
...

/*!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.000014', MASTER_LOG_POS=194;


--
-- Current Database: `ken`
--


CREATE DATABASE /*!32312 IF NOT EXISTS*/ `ken` /*!40100 DEFAULT CHARACTER SET utf8 */;


USE `ken`;

...

第三步:关闭二进制日志

第一步:先停掉数据库

第二步:修改数据库配置文件,注释掉改行

第三步:重启数据库即可

#log-bin = /data/mysql/mysql3306/logs/mysql-bin

第四步:恢复删除的表

先恢复这个全量备份的文件

感觉胜利在望,起码表和之前的数据都已经恢复了

但是还是没有我们模拟新添加的记录

mysql> source /tmp/ken.sql
mysql> select * from ken.kenken;
+----+--------+------+
| id | name | tel |
+----+--------+------+
| | 鲁班 | |
| | 后裔 | |
| | 韩信 | |
+----+--------+------+
rows in set (0.00 sec)

第五步:使用备份文件

打开备份文件可以看到我的新产生的二进制是保存在了mysql-bin.000012,194处开始的

CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000014', MASTER_LOG_POS=194;

第六步:找到删除表的那条命令位置可以看到在1349处就是删除表的命令
[root@ken logs]# mysqlbinlog mysql-bin.

...
wF/6Wx4qTw8AMwAAAOUEAAAAAA8BAAAAAAEAAgAD//gRAAAABuadjueZvQsAAACuazag
'/*!*/;
# at
# :: server id end_log_pos CRC32 0x969a0e09 Xid =
COMMIT/*!*/;
# at
# :: server id end_log_pos CRC32 0x6e619553 GTID last_committed= sequence_number=rbr_only=no
SET @@SESSION.GTID_NEXT= '08e1a6ce-da57-11e8-a0af-000c292d5bb8:149'/*!*/;
# at
# :: server id end_log_pos CRC32 0x48ac1825 Query thread_id= exec_time= error_code=
use `ken`/*!*/;
SET TIMESTAMP=/*!*/;
DROP TABLE `kenken` /* generated by server */
/*!*/;
SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
DELIMITER ;
# End of log file
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;

第六步:截取二进制日志

开始位置是你全量备份显示的位置

停止位置是你误操作的位置

[root@ken logs]# mysqlbinlog  --start-position= --stop-position= mysql-bin. >/tmp/kenken.sql
第七步:恢复全部数据
可以发现数据一个没有丢又都回来了!
恢复完数据之后千万记得开启配置文件中的二进制!!
mysql> source /tmp/kenken.sql
mysql> select * from ken.kenken;
+----+--------------+------+
| id | name | tel |
+----+--------------+------+
| | 鲁班 | |
| | 后裔 | |
| | 韩信 | |
| | 不知火舞 | |
| | d貂蝉 | |
| | 明世隐 | |
| | 李白 | |
+----+--------------+------+
rows in set (0.00 sec)

模拟删除数据库

现在我们来模拟删除一个数据库

其实和上面的步骤是一样的

千万记得恢复完数据之后重新启动二进制日志

这里我还是以上面的数据库为列

第一步:模拟备份

[root@ken logs]# mysqldump -uroot -p --all-databases --single-transaction --flush-logs --set-gtid-purged=OFF --master-data= >/tmp/ken.sql

第二步:添加数据

mysql> insert into kenken (name,tel) values ("庄周",);
Query OK, row affected (0.01 sec) mysql> insert into kenken (name,tel) values ("马可波罗",);
Query OK, row affected (0.00 sec) mysql> insert into kenken (name,tel) values ("黄忠",);
Query OK, row affected (0.00 sec) mysql> select * from kenken;
+----+--------------+------+
| id | name | tel |
+----+--------------+------+
| | 鲁班 | |
| | 后裔 | |
| | 韩信 | |
| | 不知火舞 | |
| | d貂蝉 | |
| | 明世隐 | |
| | 李白 | |
| | 东皇太一 | |
| | 项羽 | |
| | 荆轲 | |
| | 孙尚香 | |
| | 庄周 | |
| | 马可波罗 | |
| | 黄忠 | |
+----+--------------+------+
rows in set (0.00 sec)

第三步:删除ken数据库

mysql> drop database ken;
Query OK, row affected (0.01 sec) mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
rows in set (0.00 sec)

模拟恢复数据库

第一步:关闭数据库,关闭二进制日志,并重新启动

[root@ken logs]# ps aux | grep mysql
mysql 0.2 37.3 pts/ Sl : : mysqld
root 0.0 0.1 pts/ R+ : : grep --color=auto mysql
[root@ken logs]# kill -
[root@ken logs]# vim /etc/my.cnf
[]+ Killed mysqld
[root@ken logs]# mysqld &

第二步:恢复全量备份数据

可以发现现在已经恢复了数据库以及一部分的数据

但是我们最后添加的数据还是没有

mysql> source /tmp/ken.sql
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| ken |
| mysql |
| performance_schema |
| sys |
+--------------------+
rows in set (0.00 sec) mysql> use ken;
Database changed
mysql> select * from kenken;
+----+--------------+------+
| id | name | tel |
+----+--------------+------+
| | 鲁班 | |
| | 后裔 | |
| | 韩信 | |
| | 不知火舞 | |
| | d貂蝉 | |
| | 明世隐 | |
| | 李白 | |
| | 东皇太一 | |
| | 项羽 | |
| | 荆轲 | |
| | 孙尚香 | |
+----+--------------+------+
rows in set (0.00 sec)

第三步:截取二进制日志

首先查看备份文件中开始的位置

-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000016', MASTER_LOG_POS=;

再查看误操作的位置

...
# at
# :: server id end_log_pos CRC32 0x66b9786f GTID last_committed= sequence_number=rbr_only=no
SET @@SESSION.GTID_NEXT= '08e1a6ce-da57-11e8-a0af-000c292d5bb8:157'/*!*/;
# at
# :: server id end_log_pos CRC32 0x6f04e5b3 Query thread_id= exec_time= error_code=
SET TIMESTAMP=/*!*/;
drop database ken
/*!*/;
SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
DELIMITER ;
# End of log file
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;

开始截图日志

[root@ken logs]# mysqlbinlog  --start-position= --stop-position= mysql-bin. >/tmp/kenken.sql

第四步:恢复所有的数据

发现现在所有的数据都回来了

mysql> source /tmp/kenken.sql
mysql> use ken;
Database changed
mysql> select * from kenken;
+----+--------------+------+
| id | name | tel |
+----+--------------+------+
| | 鲁班 | |
| | 后裔 | |
| | 韩信 | |
| | 不知火舞 | |
| | d貂蝉 | |
| | 明世隐 | |
| | 李白 | |
| | 东皇太一 | |
| | 项羽 | |
| | 荆轲 | |
| | 孙尚香 | |
| | 庄周 | |
| | 马可波罗 | |
| | 黄忠 | |
+----+--------------+------+
rows in set (0.00 sec)

看完这篇博客,删掉数据库你还会怕吗?

学会这个删库再也不用跑路了~ --技术流ken的更多相关文章

  1. MySQL数据库无完整备份删库,除了跑路还能怎么办?

    1.背景 前段时间,由于运维同事的一次误操作,清空了内网核心数据库,导致了公司内部管理系统长时间不可用,大量知识库内容由于没有备份险些丢失. 结合这两天微盟的删库跑路事件,我们可以看到,数据库的备份与 ...

  2. 五分钟彻底学会iptables防火墙--技术流ken

    iptables简介 IPTABLES 是与最新的 3.5 版本 Linux内核集成的 IP 信息包过滤系统.如果 Linux 系统连接到因特网或 LAN.服务器或连接 LAN 和因特网的代理服务器, ...

  3. Mysql如何在删库后可以不用跑路

    我一直在想,地球上这么多程序员,应该有很多人在团队做项目的时候,出过很大的错误,比如说不小心删了库,活动福利字段多写了个零导致全服务器玩家领到数倍奖励,听了沙雕群友的话执行rm -rf命令. 记得有一 ...

  4. 学会这些CSS,再也不用切图!!!

    三角形 利用border-color支持transparent这一特性,隐藏三条边框,实现三角形. <style> .triangle { width: 0; height: 0; bor ...

  5. Yum搭建LNMP环境(动、静、库分离)(week4_day5)--技术流ken

    前言 本篇博客使用yum来搭建lnmp环境,将采用动态,静态以及数据库分开安装的方式即nginx,php,mysql.会被分开安装在不同的服务器之上,搭建出来一套lnmp环境,并部署wordpress ...

  6. 理解Linux文档的默认安全机制、隐藏属性、特殊权限,妈妈在也不用担心你从删库到跑路!!!

    写在前面 前面的章节 详解Linux文档属性.拥有者.群组.权限.差异,介绍了文档的基本权限,包括读写执行(r,w,x),还有文档若干的属性,包括是否为目录(d).文件(-).链接文件(l).拥有者. ...

  7. Mysql binlog备份数据及恢复数据,学会这个,我在也不怕删库跑路啦~

    导读 我一直都主张,技多不压身(没有学不会的技术,只有不学习的人),多学一项技能,未来就少求人一次.网上经常听到xxx删库跑路,万一真的遇到了,相信通过今天的学习,也能将数据再恢复回来~~~ 当然啦, ...

  8. Oracle删库跑路

    --10g R2 startup mount exclusive restrict; alter system enable restricted session; drop database; -- ...

  9. P5270 无论怎样神树大人都会删库跑路

    题目地址:P5270 无论怎样神树大人都会删库跑路 第一眼看上去是模拟,似乎是 \(O(n)\) 的 水题 信心满满的写完: #include <bits/stdc++.h> using ...

随机推荐

  1. MySQL数据库(四)多表查询

    两张假设有两张表格A和B,把表格当作一个集合,那么表格中的记录就是集合中的一个元素. 两张表格如下: TableA:TableB: 2.1 内连接(只有一种场景) inner join 或者join( ...

  2. now

  3. python计时器类

    import time as t class MyTimer(): def __init__(self): self.unit = ['年', '月', '日', '时', '分', '秒'] sel ...

  4. 用js实现贪吃蛇

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. 二进制安装mysql5.7

    1.创建用户和组 groupadd mysql useradd -r -g mysql mysql 2.上传二进制包至/usr/local下解压并改名为mysql tar zxvf mysql-5.7 ...

  6. Delphi XE2 新增 System.Zip 单元, 可用一句话压缩整个文件夹了

    内主要就是 TZipFile 类, 最方便使用的是它的类方法: TZipFile.ExtractZipFile() //解压 Zip 文件到指定文件夹 TZipFile.IsValid() //判断指 ...

  7. Jenkins可用环境变量列表以及环境变量的使用(Shell/Command/Maven/Ant)

    一.可用环境变量列表(以下来自google翻译): BRANCH_NAME 对于多分支项目,这将被设置为正在构建的分支的名称,例如,如果您希望从而master不是从特征分支部署到生产. CHANGE_ ...

  8. 手把手教你读取Android版微信和手Q的聊天记录(仅作技术研究学习)

    1.引言 特别说明:本文内容仅用于即时通讯技术研究和学习之用,请勿用于非法用途.如本文内容有不妥之处,请联系JackJiang进行处理!   我司有关部门为了获取黑产群的动态,有同事潜伏在大量的黑产群 ...

  9. Android开发之如何避免ANR(Keeping Your App Responsive)

    一:什么是ANR 如果应用程序不能响应用户的输入了,那么就可以说应用ANR了. 如果需要运行一个耗时较长的操作的时候,不要把这个任务放在UI线程上运行,而是单独创建一个线程运行那些操作. 以下情况会出 ...

  10. Javascript高级编程学习笔记(70)—— 事件(14)内存和性能

    由于事件处理程序是现代的web程序交互能力的提供者 所以在日常实践中,我们免不了要向页面中添加大量的事件处理程序(不管是用于用户交互还是用于统计用户数据) 在创建GUI(图形用户界面)的语言(如C#) ...