MySQL使用mysqldump+binlog完整恢復被刪除的資料庫(轉)
(一)概述
在日常MySQL資料庫運維過程中,可能會遇到使用者誤刪除資料,常見的誤刪除資料操作有:
- 使用者執行delete,因為條件不對,刪除了不應該刪除的資料(DML操作);
- 使用者執行update,因為條件不對,更新資料出錯(DML操作);
- 使用者誤刪除表drop table(DDL操作);
- 使用者誤清空表truncate(DDL操作);
- 使用者刪除資料庫drop database,跑路(DDL操作)
- …等
這些情況雖然不會經常遇到,但是遇到了,我們需要有能力將其恢復,下面講述如何恢復。
(二)恢復原理
如果要將資料庫恢復到故障點之前,那麼需要有資料庫全備和全備之後產生的所有二進位制日誌。
全備作用 :使用全備將資料庫恢復到上一次完整備份的位置;
二進位制日誌作用:利用全備的備份集將資料庫恢復到上一次完整備份的位置之後,需要對上一次全備之後資料庫產生的所有動作進行重做,而重做的過程就是解析二進位制日誌檔案為SQL語句,然後放到資料庫裡面再次執行。
舉個例子:小明在4月1日晚上8:00使用了mysqldump對資料庫進行了備份,在4月2日早上12:00的時候,小華不小心刪除了資料庫,那麼,在執行資料庫恢復的時候,需要使用4月1日晚上的完整備份將資料庫恢復到“4月1日晚上8:00”,那4月1日晚上8:00以後到4月2日早上12:00之前的資料如何恢復呢?就得通過解析二進位制日誌來對這段時間執行過的SQL進行重做。
(三)刪庫恢復測試
(3.1)實驗目的
在本次實驗中,我直接測試刪庫,執行drop database lijiamandb,確認是否可以恢復。
(3.2)測試過程
在測試資料庫lijiamandb中建立測試表test01和test02,然後執行mysqldump對資料庫進行全備,之後執行drop database,確認database是否可以恢復。
STEP1:建立測試資料,為了模擬日常繁忙的生產環境,頻繁的運算元據庫產生大量二進位制日誌,我特地使用儲存過程和EVENT產生大量資料。
建立測試表:
use lijiamandb;
create table test01 ( id1 int not null auto_increment, name varchar(30), primary key(id1) );create table test02 ( id2 int not null auto_increment, name varchar(30), primary key(id2) );
建立儲存過程,往測試表裡面插入資料,每次執行該儲存過程,往test01和test02各自插入10000條資料:
CREATE DEFINER=`root`@`%` PROCEDURE `p_insert`() BEGIN #Routine body goes here... DECLARE str1 varchar(30);DECLARE str2 varchar(30); DECLARE i int; set i = 0; while i < 10000 do set str1 = substring(md5(rand()),1,25); insert into test01(name) values(str1); set str2 = substring(md5(rand()),1,25); insert into test02(name) values(str1); set i = i + 1; end while; END
制定事件,每隔10秒鐘,執行上面的儲存過程:
use lijiamandb; create event if not exists e_insert on schedule every 10 second on completion preserve do call p_insert();
啟動EVENT,每個10s自動向test01和test02各自插入10000條資料
mysql> show variables like '%event_scheduler%'; +----------------------------------------------------------+-------+ | Variable_name | Value | +----------------------------------------------------------+-------+ | event_scheduler | OFF | +----------------------------------------------------------+-------+ mysql> set global event_scheduler = on; Query OK, 0 rows affected (0.08 sec)
--過3分鐘。。。
STEP2:第一步生成大量測試資料後,使用mysqldump對lijiamandb資料庫執行完全備份
mysqldump -h192.168.10.11 -uroot -p123456 -P3306 --single-transaction --master-data=2 --events --routines --databases lijiamandb > /mysql/backup/lijiamandb.sql
注意:必須要新增--master-data=2,這樣才會備份集裡面mysqldump備份的終點位置。
--過3分鐘。。。
STEP3:為了便於資料庫刪除前與刪除後資料一致性校驗,先停止表的資料插入,此時test01和test02都有930000行資料,我們後續恢復也要保證有930000行資料。
mysql> set global event_scheduler = off; Query OK, 0 rows affected (0.00 sec) mysql> select count(*) from test01; +----------+ | count(*) | +----------+ | 930000 | +----------+1 row in set (0.14 sec) mysql> select count(*) from test02; +----------+ | count(*) | +----------+ | 930000 | +----------+1 row in set (0.13 sec)
STEP4:刪除資料庫
mysql> drop database lijiamandb; Query OK, 2 rows affected (0.07 sec)
STEP5:使用mysqldump的全備匯入
mysql> create database lijiamandb; Query OK, 1 row affected (0.01 sec) mysql> exit Bye [root@masterdb binlog]# mysql -uroot -p123456 lijiamandb < /mysql/backup/lijiamandb.sql mysql: [Warning] Using a password on the command line interface can be insecure.
在執行全量備份恢復之後,發現只有753238筆資料:
[root@masterdb binlog]# mysql -uroot -p123456 lijiamandb mysql> select count(*) from test01; +----------+ | count(*) | +----------+ | 753238 | +----------+1 row in set (0.12 sec) mysql> select count(*) from test02; +----------+ | count(*) | +----------+ | 753238 | +----------+1 row in set (0.11 sec)
很明顯,全量匯入之後, 資料不完整,接下來使用mysqlbinlog對二進位制日誌執行增量恢復。
使用mysqlbinlog進行增量日誌恢復最重要的就是確定待恢復的起始位置(start-position)和終止位置(stop-position),起始位置(start-position)是我們執行全被之後的位置,而終止位置則是故障發生之前的位置。
STEP6:確認mysqldump備份到的最終位置
[root@masterdb backup]# cat lijiamandb.sql |grep "CHANGE MASTER"-- CHANGE MASTER TO MASTER_LOG_FILE='master-bin.000044', MASTER_LOG_POS=8526828
備份到了44號日誌的8526828位置,那麼恢復的起點可以設定為:44號日誌的8526828。
--接下來確認要恢復的終點位置,即執行"DROP DATABASE LIJIAMAN"之前的位置,需要到binlog裡面確認。
[root@masterdb binlog]# ls master-bin.000001 master-bin.000010 master-bin.000019 master-bin.000028 master-bin.000037 master-bin.000046 master-bin.000055 master-bin.000002 master-bin.000011 master-bin.000020 master-bin.000029 master-bin.000038 master-bin.000047 master-bin.000056 master-bin.000003 master-bin.000012 master-bin.000021 master-bin.000030 master-bin.000039 master-bin.000048 master-bin.000057 master-bin.000004 master-bin.000013 master-bin.000022 master-bin.000031 master-bin.000040 master-bin.000049 master-bin.000058 master-bin.000005 master-bin.000014 master-bin.000023 master-bin.000032 master-bin.000041 master-bin.000050 master-bin.000059 master-bin.000006 master-bin.000015 master-bin.000024 master-bin.000033 master-bin.000042 master-bin.000051 master-bin.index master-bin.000007 master-bin.000016 master-bin.000025 master-bin.000034 master-bin.000043 master-bin.000052 master-bin.000008 master-bin.000017 master-bin.000026 master-bin.000035 master-bin.000044 master-bin.000053 master-bin.000009 master-bin.000018 master-bin.000027 master-bin.000036 master-bin.000045 master-bin.000054# 多次查詢,發現drop database在54號日誌檔案[root@masterdb binlog]# mysqlbinlog -v master-bin.000056 | grep -i "drop database lijiamandb" [root@masterdb binlog]# mysqlbinlog -v master-bin.000055 | grep -i "drop database lijiamandb" [root@masterdb binlog]# mysqlbinlog -v master-bin.000055 | grep -i "drop database lijiamandb" [root@masterdb binlog]# mysqlbinlog -v master-bin.000054 | grep -i "drop database lijiamandb"
drop database lijiamandb# 儲存到文字,便於搜尋[root@masterdb binlog]# mysqlbinlog -v master-bin.000054 > master-bin.txt# 確認drop database之前的位置為:54號檔案的9019487 # at 9019422 #200423 16:07:46 server id 11 end_log_pos 9019487 CRC32 0x86f13148 Anonymous_GTID last_committed=30266 sequence_number=30267 rbr_only=no SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/; # at 9019487 #200423 16:07:46 server id 11 end_log_pos 9019597 CRC32 0xbd6ea5dd Query thread_id=100 exec_time=0 error_code=0 SET TIMESTAMP=1587629266/*!*/; SET @@session.sql_auto_is_null=0/*!*/; /*!\C utf8 *//*!*/; SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=33/*!*/; drop database lijiamandb /*!*/; # at 9019597 #200423 16:09:25 server id 11 end_log_pos 9019662 CRC32 0x8f7b11dc Anonymous_GTID last_committed=30267 sequence_number=30268 rbr_only=no SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/; # at 9019662 #200423 16:09:25 server id 11 end_log_pos 9019774 CRC32 0x9b42423d Query thread_id=100 exec_time=0 error_code=0 SET TIMESTAMP=1587629365/*!*/; create database lijiamandb
STEP7:確定了開始結束點,執行增量恢復
開始:44號日誌的8526828
結束:54號檔案的9019487
這裡分為3條命令執行,起始日誌檔案涉及到引數start-position引數,單獨執行;中止檔案涉及到stop-position引數,單獨執行;中間的日誌檔案不涉及到特殊引數,全部一起執行。
mysqlbinlog --start-position=8526828 /mysql/binlog/master-bin.000044 | mysql -uroot -p123456
# 中間日誌檔案
mysqlbinlog /mysql/binlog/master-bin.000045 /mysql/binlog/master-bin.000046 /mysql/binlog/master-bin.000047 /mysql/binlog/master-bin.000048 /mysql/binlog/master-bin.000049 /mysql/binlog/master-bin.000050 /mysql/binlog/master-bin.000051 /mysql/binlog/master-bin.000052 /mysql/binlog/master-bin.000053 | mysql -uroot -p123456
# 終止日誌檔案
mysqlbinlog --stop-position=9019487 /mysql/binlog/master-bin.000054 | mysql -uroot -p123456
STEP8:恢復結束,確認全部資料已經還原
[root@masterdb binlog]# mysql -uroot -p123456 lijiamandb mysql> select count(*) from test01; +----------+ | count(*) | +----------+ | 930000 | +----------+ 1 row in set (0.15 sec) mysql> select count(*) from test02; +----------+ | count(*) | +----------+ | 930000 | +----------+ 1 row in set (0.13 sec)
(四)總結
1.對於DML操作,binlog記錄了所有的DML資料變化:
--對於insert,binlog記錄了insert的行資料
--對於update,binlog記錄了改變前的行資料和改變後的行資料
--對於delete,binlog記錄了刪除前的資料
假如使用者不小心誤執行了DML操作,可以使用mysqlbinlog將資料庫恢復到故障點之前。
2.對於DDL操作,binlog只記錄使用者行為,而不記錄行變化,但是並不影響我們將資料庫恢復到故障點之前。
總之,使用mysqldump全備加binlog日誌,可以將資料恢復到故障前的任意時刻。
出自: https://www.cnblogs.com/lijiaman/p/12764268.html
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/25583515/viewspace-2721894/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 寶塔資料庫恢復 mysql資料庫丟失恢復 mysql資料庫刪除庫恢復 寶塔mysql資料庫恢復資料庫MySql
- MySQL資料庫表誤刪除恢復(一)MySql資料庫
- 【資料庫資料恢復】HP-UX系統ORACLE資料庫被誤刪除的資料恢復資料庫資料恢復UXOracle
- 【北亞資料恢復】輸入錯誤命令導致MySQL資料庫資料被刪除的資料恢復案例資料恢復MySql資料庫
- [Oracle]Oracle資料庫資料被修改或者刪除恢復資料Oracle資料庫
- 【北亞資料庫資料恢復】使用delete未加where子句刪除全表資料的Mysql資料庫資料恢復資料庫資料恢復deleteMySql
- Mysql資料庫delete刪除後資料恢復報告MySql資料庫delete資料恢復
- Sybase ASE資料庫恢復,Sybase資料恢復,資料誤刪除恢復工具READSYBDEVICE資料庫資料恢復dev
- 【資料庫資料恢復】LINUX環境下ORACLE資料庫誤刪除的資料恢復資料庫資料恢復LinuxOracle
- Git恢復被刪除的分支Git
- 恢復Oracle資料庫誤刪除資料的語句Oracle資料庫
- 【oracle資料庫資料恢復】誤操作導致的資料庫誤刪除的資料恢復案例Oracle資料庫資料恢復
- Sybase SQL Anywhere(ASA)資料庫恢復,ASA資料恢復,資料誤刪除恢復工具ReadASADBSQL資料庫資料恢復
- 誤刪除儲存SqlServer資料庫資料恢復SQLServer資料庫資料恢復
- 伺服器資料恢復—EMC儲存資料卷被誤刪除如何恢復資料?伺服器資料恢復
- SQL Server資料庫恢復,SQL Server資料恢復,SQL Server資料誤刪除恢復工具SQLRescueSQLServer資料庫資料恢復
- 新司機的致勝法寶,使用ApexSql Log2018快速恢復資料庫被刪除的資料SQL資料庫
- 刪庫不跑路-詳解MySQL資料恢復MySql資料恢復
- mysql誤刪資料恢復MySql資料恢復
- 【伺服器資料恢復】NetApp儲存中lun被誤刪除的資料恢復過程伺服器資料恢復APP
- 【伺服器資料恢復】VMFS分割槽被刪除並格式化的資料恢復案例伺服器資料恢復
- 【伺服器資料恢復】XenServer虛擬機器被誤操作刪除的資料恢復案例伺服器資料恢復Server虛擬機
- 【北亞資料恢復】分散式儲存hbase和hive資料庫底層檔案被誤刪除的資料恢復案例資料恢復分散式Hive資料庫
- 【北亞資料恢復】誤刪除oracle表和誤刪除oracle表資料的資料恢復方法資料恢復Oracle
- MySQL資料庫的恢復MySql資料庫
- 【伺服器資料恢復】linux ext3檔案系統下誤刪除mysql資料庫的資料恢復案例伺服器資料恢復LinuxMySql資料庫
- 如何恢復被刪除的 GitLab 專案?Gitlab
- 【NetApp資料恢復案例】針對NetApp誤刪除資料的恢復APP資料恢復
- [20210930]bbed恢復刪除的資料.txt
- LINUX下資料被誤刪除、LINUX下資料被誤格式化後資料恢復Linux資料恢復
- 【儲存資料恢復案例】Netapp誤操作刪除lun的資料恢復資料恢復APP
- 【儲存資料恢復】NetApp儲存誤刪除的資料恢復案例資料恢復APP
- SQLSERVER完整資料庫還原(完整恢復模式)SQLServer資料庫模式
- EMC NAS中虛擬機器被誤刪除的資料恢復案例虛擬機資料恢復
- 伺服器資料恢復—雲伺服器mysql資料庫表資料被delete的資料恢復案例伺服器資料恢復MySql資料庫delete
- MySQL 如何重建/恢復刪除的 sys SchemaMySql
- MySQL資料庫故障恢復MySql資料庫
- 【伺服器資料恢復】LINUX誤刪除、格式化的資料恢復伺服器資料恢復Linux