学会这个删库再也不用跑路了~ --技术流ken
?
前言
?
相信每一個學(xué)IT的人或多或少都聽說過從刪庫到跑路這個梗~下圖也是在各種交流群屢禁不止,新人聽著也是瑟瑟發(fā)抖。
?
?
人們茶余飯后,街頭巷角難免要問。。。
?
下面技術(shù)流ken就教給各位新手們一招刪庫再也不用跑路的絕技~
?
實現(xiàn)原理
?
想要學(xué)會這個技能務(wù)必先要看我的這篇有關(guān)mysql日志的博客《MySQL系列詳解三:MySQL中各類日志詳解-技術(shù)流ken》。
一定要先了解二進制日志文件的作用
二進制日志記錄了對數(shù)據(jù)庫執(zhí)行更改的所有操作,但是不包括 select 和 show 這類操作,因為這類操作對數(shù)據(jù)本身并沒有修改,如果你還想記錄select和show操作,那只能使用查詢?nèi)罩玖?#xff0c;而不是二進制日志。 此外,二進制還包括了執(zhí)行數(shù)據(jù)庫更改操作的時間和執(zhí)行時間等信息。 二進制日志主要有以下幾種作用 :恢復(fù)(recovery) :
某些數(shù)據(jù)的恢復(fù)需要二進制日志,如當(dāng)一個數(shù)據(jù)庫全備文件恢復(fù)后,我們可以通過二進制的日志進行 point-in-time 的恢復(fù)復(fù)制(replication) :
通過復(fù)制和執(zhí)行二進制日志使得一臺遠程的 MySQL 數(shù)據(jù)庫(一般是slave 或者 standby) 與一臺MySQL數(shù)據(jù)庫(一般為master或者primary) 進行實時同步審計(audit) :
用戶可以通過二進制日志中的信息來進行審計,判斷是否有對數(shù)據(jù)庫進行注入攻擊?
數(shù)據(jù)庫備份
?
有人會有疑惑數(shù)據(jù)庫都被我刪了,哪還有什么備份?
殊不知,在你刪庫之前你們公司的運維工程師或者DBA已經(jīng)悄悄的對數(shù)據(jù)庫做了備份~
而且這個備份不是在你的電腦或者mysql服務(wù)器上面,可能已經(jīng)被傳送到了你們主管,DBA或者某臺專用的備份服務(wù)器哪里去了,這個實現(xiàn)起來非常簡單,運維工程師通過腳本就可以自動完成這個工作,總之他們肯定會有一份數(shù)據(jù)庫的備份的~
但是他們的這個備份并不是完整備份,什么意思那
可能你們公司的數(shù)據(jù)庫備份策略是周末做全量備份,周一至周六是做的增量備份,而且是每天只做一次增量備份
比如你們公司做增量備份是每天的凌晨時間,而你刪庫的時間是在早晨10點鐘,那么這10個小時的數(shù)據(jù),就沒有備份了~
如果你們公司做的比較風(fēng)生水起,在這十個小時的時間內(nèi)有10萬條的寫入記錄,你是不是會心口發(fā)塞,準(zhǔn)備跑路了~
不要慌
第一時間去找你們公司的DBA問他有沒有最新的數(shù)據(jù)庫備份文件
如果他說沒有。。
告訴他你把庫刪了,讓他跟著你一起慌。。
但是你是看過我這篇博客的人,淡定
第二時間去找你們公司的運維工程師
他們肯定有!
總之無論你刪了什么重要文件,都去找運維工程師,他們肯定有!他們就是一群沒事愛做自動化備份的人
他們會告訴你:XX文件都被同步在了XX服務(wù)器上面了
?
恢復(fù)數(shù)據(jù)庫
?
在DBA手里可以拿到全量備份以及增量備份的數(shù)據(jù)庫文件,在運維工程師手里可以任何實時的二進制文件。
這個時候第一時間先去二進制服務(wù)器上面再次對二進制日志文件做一個備份!
這次能不能不跑路,就看這個二進制日志文件了。
拿到這些文件之后,現(xiàn)在就可以對數(shù)據(jù)庫進行恢復(fù)了。
刪庫之后一定要先把數(shù)據(jù)庫服務(wù)停掉,這是重點!
有了全量備份的文件,增量備份的文件以及二進制文件之后,就去拜托你們公司的DBA或者運維工程師來進行數(shù)據(jù)的恢復(fù)即可。
?
模擬刪除數(shù)據(jù)表
?
接下來就完整演示從刪表到數(shù)據(jù)恢復(fù)的過程
第一步:查看是是否開啟了二進制日志
顯示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 | +----------------------------------+--------------------------------------------+ 6 rows in set (0.00 sec)?
第二步:添加一些數(shù)據(jù)
我們首先往數(shù)據(jù)庫中添加一些數(shù)據(jù)
下面我創(chuàng)建了一個ken數(shù)據(jù)庫
ken數(shù)據(jù)庫中創(chuàng)建了一個kenken數(shù)據(jù)表
在這個表中插入了一些數(shù)據(jù)
mysql> create database ken; Query OK, 1 row affected (0.00 sec)mysql> use ken; Database changed mysql> create table kenken(id int auto_increment primary key not null,name char(30)not null,tel int)-> ; Query OK, 0 rows affected (0.03 sec)mysql> desc kenken; +-------+----------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------+----------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | name | char(30) | NO | | NULL | | | tel | int(11) | YES | | NULL | | +-------+----------+------+-----+---------+----------------+ 3 rows in set (0.06 sec) mysql> insert into kenken (id,name,tel) values (10,"魯班",123); Query OK, 1 row affected (0.01 sec)mysql> insert into kenken (id,name,tel) values (12,"后裔",1233); Query OK, 1 row affected (0.00 sec) mysql> insert into kenken (id,name,tel) values (13,"韓信",1234); Query OK, 1 row affected (0.00 sec)mysql> select * from kenken; +----+--------+------+ | id | name | tel | +----+--------+------+ | 10 | 魯班 | 123 | | 12 | 后裔 | 1233 | | 13 | 韓信 | 1234 | +----+--------+------+ 3 rows in set (0.00 sec)?
第三步:模擬DBA做全量備份
?這樣我們就獲得了一個數(shù)據(jù)庫全量備份的文件
[root@localhost ~]# mysqldump -uroot -p --all-databases --single-transaction --flush-logs --set-gtid-purged=OFF --master-data=2 >/tmp/ken.sql Enter password: [root@localhost ~]# 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 2018-11-25 15:57:20?
第四步:模擬數(shù)據(jù)寫入
備份完成之后我們模擬數(shù)據(jù)寫入,相當(dāng)于在凌晨到早上十點鐘這段時間
下面我又增加了四條記錄,在備份文件中是沒有的
mysql> insert into kenken (name,tel) values ("不知火舞",11); Query OK, 1 row affected (0.00 sec)mysql> insert into kenken (name,tel) values ("d貂蟬",11); Query OK, 1 row affected (0.00 sec)mysql> insert into kenken (name,tel) values ("明世隱",11); Query OK, 1 row affected (0.00 sec)mysql> insert into kenken (name,tel) values ("李白",11); Query OK, 1 row affected (0.00 sec)mysql> select * from kenken; +----+--------------+------+ | id | name | tel | +----+--------------+------+ | 10 | 魯班 | 123 | | 12 | 后裔 | 1233 | | 13 | 韓信 | 1234 | | 14 | 不知火舞 | 11 | | 15 | d貂蟬 | 11 | | 16 | 明世隱 | 11 | | 17 | 李白 | 11 | +----+--------------+------+ 7 rows in set (0.00 sec)?
第五步:模擬數(shù)據(jù)刪除
現(xiàn)在是早晨10點鐘,你把這個表刪掉了
現(xiàn)在在備份文件中是沒有這個新添加的表中的數(shù)據(jù)的
mysql> drop table kenken; Query OK, 0 rows affected (0.01 sec)mysql> select * from kenken; ERROR 1146 (42S02): Table 'ken.kenken' doesn't exist?
模擬恢復(fù)數(shù)據(jù)表
?
第一步:查看二進制文件
進入到你們公司的二進制日志保存位置
下面這些就是二進制日志文件
[root@localhost ~]# cd /data/mysql/mysql3306/logs/ [root@localhost logs]# ls mysql-bin.000009 mysql-bin.000010 mysql-bin.000011 mysql-bin.000012 mysql-bin.index?
第二步:查看全量備份文件
在大約22行處記錄了:
自備份起,新開始的二進制日志文件保存的位置
非常重要
[root@localhost 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`;
...?
第三步:關(guān)閉二進制日志
第一步:先停掉數(shù)據(jù)庫
第二步:修改數(shù)據(jù)庫配置文件,注釋掉改行
第三步:重啟數(shù)據(jù)庫即可
#log-bin = /data/mysql/mysql3306/logs/mysql-bin?
第四步:恢復(fù)刪除的表
先恢復(fù)這個全量備份的文件
感覺勝利在望,起碼表和之前的數(shù)據(jù)都已經(jīng)恢復(fù)了
但是還是沒有我們模擬新添加的記錄
mysql> source /tmp/ken.sql mysql> select * from ken.kenken; +----+--------+------+ | id | name | tel | +----+--------+------+ | 10 | 魯班 | 123 | | 12 | 后裔 | 1233 | | 13 | 韓信 | 1234 | +----+--------+------+ 3 rows in set (0.00 sec)?
第五步:使用備份文件
打開備份文件可以看到我的新產(chǎn)生的二進制是保存在了mysql-bin.000012,194處開始的
CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000014', MASTER_LOG_POS=194;第六步:找到刪除表的那條命令位置可以看到在1349處就是刪除表的命令 [root@localhost logs]# mysqlbinlog mysql-bin.000014... wF/6Wx4qTw8AMwAAAOUEAAAAAA8BAAAAAAEAAgAD//gRAAAABuadjueZvQsAAACuazag '/*!*/; # at 1253 #181125 16:39:28 server id 1003306 end_log_pos 1284 CRC32 0x969a0e09 Xid = 2524 COMMIT/*!*/; # at 1284 #181125 16:39:43 server id 1003306 end_log_pos 1349 CRC32 0x6e619553 GTID last_committed=4 sequence_number=rbr_only=no SET @@SESSION.GTID_NEXT= '08e1a6ce-da57-11e8-a0af-000c292d5bb8:149'/*!*/; # at 1349 #181125 16:39:43 server id 1003306 end_log_pos 1466 CRC32 0x48ac1825 Query thread_id=18 exec_time=0 error_code=0 use `ken`/*!*/; SET TIMESTAMP=1543135183/*!*/; 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@localhost logs]# mysqlbinlog --start-position=194 --stop-position=1349 mysql-bin.000014 >/tmp/kenken.sql第七步:恢復(fù)全部數(shù)據(jù)
可以發(fā)現(xiàn)數(shù)據(jù)一個沒有丟又都回來了!
恢復(fù)完數(shù)據(jù)之后千萬記得開啟配置文件中的二進制!! mysql> source /tmp/kenken.sql mysql> select * from ken.kenken; +----+--------------+------+ | id | name | tel | +----+--------------+------+ | 10 | 魯班 | 123 | | 12 | 后裔 | 1233 | | 13 | 韓信 | 1234 | | 14 | 不知火舞 | 11 | | 15 | d貂蟬 | 11 | | 16 | 明世隱 | 11 | | 17 | 李白 | 11 | +----+--------------+------+ 7 rows in set (0.00 sec)
?
模擬刪除數(shù)據(jù)庫
?
現(xiàn)在我們來模擬刪除一個數(shù)據(jù)庫
其實和上面的步驟是一樣的
千萬記得恢復(fù)完數(shù)據(jù)之后重新啟動二進制日志
這里我還是以上面的數(shù)據(jù)庫為列
第一步:模擬備份
[root@localhost logs]# mysqldump -uroot -p --all-databases --single-transaction --flush-logs --set-gtid-purged=OFF --master-data=2 >/tmp/ken.sql?
第二步:添加數(shù)據(jù)
mysql> insert into kenken (name,tel) values ("莊周",121); Query OK, 1 row affected (0.01 sec)mysql> insert into kenken (name,tel) values ("馬可波羅",121); Query OK, 1 row affected (0.00 sec)mysql> insert into kenken (name,tel) values ("黃忠",121); Query OK, 1 row affected (0.00 sec)mysql> select * from kenken; +----+--------------+------+ | id | name | tel | +----+--------------+------+ | 10 | 魯班 | 123 | | 12 | 后裔 | 1233 | | 13 | 韓信 | 1234 | | 14 | 不知火舞 | 11 | | 15 | d貂蟬 | 11 | | 16 | 明世隱 | 11 | | 17 | 李白 | 11 | | 18 | 東皇太一 | 121 | | 19 | 項羽 | 121 | | 20 | 荊軻 | 121 | | 21 | 孫尚香 | 121 | | 22 | 莊周 | 121 | | 23 | 馬可波羅 | 121 | | 24 | 黃忠 | 121 | +----+--------------+------+ 14 rows in set (0.00 sec)?
第三步:刪除ken數(shù)據(jù)庫
mysql> drop database ken; Query OK, 1 row affected (0.01 sec)mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | +--------------------+ 4 rows in set (0.00 sec)?
模擬恢復(fù)數(shù)據(jù)庫
?
第一步:關(guān)閉數(shù)據(jù)庫,關(guān)閉二進制日志,并重新啟動
[root@localhost logs]# ps aux | grep mysql mysql 2515 0.2 37.3 1088560 186484 pts/3 Sl 17:01 0:01 mysqld root 2552 0.0 0.1 112704 968 pts/3 R+ 17:11 0:00 grep --color=auto mysql [root@localhost logs]# kill -9 2515 [root@localhost logs]# vim /etc/my.cnf [1]+ Killed mysqld [root@localhost logs]# mysqld &?
第二步:恢復(fù)全量備份數(shù)據(jù)
可以發(fā)現(xiàn)現(xiàn)在已經(jīng)恢復(fù)了數(shù)據(jù)庫以及一部分的數(shù)據(jù)
但是我們最后添加的數(shù)據(jù)還是沒有
mysql> source /tmp/ken.sql mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | ken | | mysql | | performance_schema | | sys | +--------------------+ 5 rows in set (0.00 sec)mysql> use ken; Database changed mysql> select * from kenken; +----+--------------+------+ | id | name | tel | +----+--------------+------+ | 10 | 魯班 | 123 | | 12 | 后裔 | 1233 | | 13 | 韓信 | 1234 | | 14 | 不知火舞 | 11 | | 15 | d貂蟬 | 11 | | 16 | 明世隱 | 11 | | 17 | 李白 | 11 | | 18 | 東皇太一 | 121 | | 19 | 項羽 | 121 | | 20 | 荊軻 | 121 | | 21 | 孫尚香 | 121 | +----+--------------+------+ 11 rows in set (0.00 sec)?
第三步:截取二進制日志
首先查看備份文件中開始的位置
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000016', MASTER_LOG_POS=194;再查看誤操作的位置
... # at 1010 #181125 17:09:31 server id 1003306 end_log_pos 1075 CRC32 0x66b9786f GTID last_committed=3 sequence_number=rbr_only=no SET @@SESSION.GTID_NEXT= '08e1a6ce-da57-11e8-a0af-000c292d5bb8:157'/*!*/; # at 1075 #181125 17:09:31 server id 1003306 end_log_pos 1164 CRC32 0x6f04e5b3 Query thread_id=4 exec_time=0 error_code=0 SET TIMESTAMP=1543136971/*!*/; 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@localhost logs]# mysqlbinlog --start-position=194 --stop-position=1075 mysql-bin.000016 >/tmp/kenken.sql?
第四步:恢復(fù)所有的數(shù)據(jù)
發(fā)現(xiàn)現(xiàn)在所有的數(shù)據(jù)都回來了
mysql> source /tmp/kenken.sql mysql> use ken; Database changed mysql> select * from kenken; +----+--------------+------+ | id | name | tel | +----+--------------+------+ | 10 | 魯班 | 123 | | 12 | 后裔 | 1233 | | 13 | 韓信 | 1234 | | 14 | 不知火舞 | 11 | | 15 | d貂蟬 | 11 | | 16 | 明世隱 | 11 | | 17 | 李白 | 11 | | 18 | 東皇太一 | 121 | | 19 | 項羽 | 121 | | 20 | 荊軻 | 121 | | 21 | 孫尚香 | 121 | | 22 | 莊周 | 121 | | 23 | 馬可波羅 | 121 | | 24 | 黃忠 | 121 | +----+--------------+------+ 14 rows in set (0.00 sec)?
看完這篇博客,刪掉數(shù)據(jù)庫你還會怕嗎?
總結(jié)
以上是生活随笔為你收集整理的学会这个删库再也不用跑路了~ --技术流ken的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 语言学和计算机结合的例子,举例说明语言学
- 下一篇: GitChat·技术管理 | Cynef