今天跟大家分享了一種誤刪數(shù)據(jù)文件利用內(nèi)存數(shù)據(jù)恢復(fù)的方法,其實還有一些其他的恢復(fù)方法,需要根據(jù)不同場景去選取最優(yōu)的處理方案。
?hello,大家好,我是張張,「架構(gòu)精進(jìn)之路」公號作者。
在我們實際工作中,尤其在公司的測試環(huán)境下,經(jīng)常會有多個業(yè)務(wù)方服務(wù)共用同一套服務(wù)器,部署自身MySQL環(huán)境。很不巧的是,會出現(xiàn)有MySQL數(shù)據(jù)文件被刪除/誤刪除的情況發(fā)生。假如真的發(fā)生了,想想就很令人崩潰對不對?
先別著急,今天來跟大家分享一個對于MySQL數(shù)據(jù)文件被誤刪除后嘗試恢復(fù)的辦法。一旦發(fā)生上述情況,同時實例數(shù)據(jù)未做備份,是否有機會進(jìn)行數(shù)據(jù)恢復(fù)呢?
接下來,就讓我們來嘗試下數(shù)據(jù)恢復(fù)過程的演示:
1.構(gòu)建模擬數(shù)據(jù)
模擬數(shù)據(jù)準(zhǔn)備:
CREATE TABLE `t1` (
`id` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
mysql> select * from t1;
+------+
| id |
+------+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
+------+
5 rows in set (0.00 sec)
2.刪除數(shù)據(jù)文件
在操作系統(tǒng)層進(jìn)行數(shù)據(jù)文件的刪除。
[root@admin-db12 test]# ll
total 112
-rw-r----- 1 mysql mysql 67 Nov 22 10:01 db.opt
-rw-r----- 1 mysql mysql 8556 Nov 22 11:48 t1.frm
-rw-r----- 1 mysql mysql 98304 Nov 22 11:48 t1.ibd
[root@admin-db12 test]# pwd
/mysql/dba/mysql/multi/3303/data/test
[root@admin-db12 test]# ll
total 112
-rw-r----- 1 mysql mysql 67 Nov 22 10:01 db.opt-rw-r----- 1 mysql mysql 8556 Nov 22 11:48 t1.frm-rw-r----- 1 mysql mysql 98304 Nov 22 11:48 t1.ibd
[root@admin-db12 test]# rm -rf *
[root@admin-db12 test]# ll
total 0
3.查詢驗證數(shù)據(jù)
在數(shù)據(jù)庫層,查看當(dāng)前表中數(shù)據(jù),發(fā)現(xiàn)當(dāng)前表數(shù)據(jù)目前已空空如也。
#當(dāng)前實例
mysql> select * from t1;
Empty set (0.00 sec)
4.OS層獲取內(nèi)存中的數(shù)據(jù)
當(dāng)前實例沒有關(guān)閉的情況下,查看實例pid。
[root@admin-db62 test]# ps aux | grep 3303
root 21952 0.0 0.0 113304 1648 ? S 11:47 0:00 /bin/sh /mysql/dba/mysql/multi/3303/private/bin/mysqld_safe --defaults-file=/mysql/dba/mysql/multi/3303/etc/my.cnf
mysql 23356 0.2 1.1 19529408 1568416 ? Sl 11:47 0:04 /mysql/dba/mysql/multi/3303/private/bin/mysqld --defaults-file=/mysql/dba/mysql/multi/3303/etc/my.cnf --basedir=/mysql/dba/mysql/multi/3303/private --datadir=/mysql/dba/mysql/multi/3303/data --plugin-dir=/mysql/dba/mysql/multi/3303/private/lib/plugin --user=mysql --log-error=/mysql/dba/mysql/multi/3303/log/mysql-error.log --open-files-limit=65535 --pid-file=/mysql/dba/mysql/multi/3303/pid/mysql.pid --socket=/mysql/dba/mysql/multi/3303/socket/mysql.sock --port=3303
[root@admin-db62 fd]# cd /proc/23356/fd
[root@admin-db62 fd]# ll
lrwx------ 1 root root 64 Nov 22 11:52 39 -> /mysql/dba/mysql/multi/3303/data/mysql/time_zone.ibdlrwx------ 1 root root 64 Nov 22 11:52 4 -> /mysql/dba/mysql/multi/3303/data/ib_logfile0lrwx------ 1 root root 64 Nov 22 11:52 40 -> /mysql/dba/mysql/multi/3303/data/mysql/time_zone_transition.ibdlrwx------ 1 root root 64 Nov 22 11:52 42 -> /mysql/dba/mysql/multi/3303/data/test/t1.ibd (deleted)
通過上述操作我們發(fā)現(xiàn),被我們干掉的數(shù)據(jù)文件顯示狀態(tài)為”deleted“,被刪除。
5.獲取處理數(shù)據(jù)
為保護好當(dāng)前服務(wù)器現(xiàn)場、在另一臺服務(wù)器上開始恢復(fù)數(shù)據(jù)。
#目標(biāo)端
[root@admin-db64 3306]# nc -l 13306 > /mysql/dba/mysql/multi/3306/data/t1.ibd #db64這臺服務(wù)器上,3306實例中來恢復(fù)上述被刪除的數(shù)據(jù)。/mysql/dba/mysql/multi/3306/data為臨時存放數(shù)據(jù)目錄
#源端
lrwx------ 1 root root 64 Nov 22 11:52 42 -> /mysql/dba/mysql/multi/3303/data/test/t1.ibd (deleted)
[root@admin-db62 fd]# cat 42 | nc 10.26.65.74 13306
#如上操作,將在OS層,內(nèi)存里的數(shù)據(jù)拷貝并傳輸至遠(yuǎn)程恢復(fù)服務(wù)器上。
【注意】不要在本機進(jìn)行恢復(fù)、保留線上環(huán)境,避免二次傷害。
6.恢復(fù)數(shù)據(jù)處理
在源端服務(wù)器進(jìn)行數(shù)據(jù)恢復(fù)操作。
[root@admin-db64 3306]# nc -l 13306 > /mysql/dba/mysql/multi/3306/data/t1.ibd
[root@admin-db64 3306]# cd data/
[root@admin-db64 data]# ll
total 100
-rw-r----- 1 mysql mysql 67 Nov 22 12:36 db.opt-rw-r--r-- 1 root root 98304 Nov 22 12:37 t1.ibd
[root@admin-db64 data]# chown -R mysql.mysql t1.ibd #更改屬主
登錄源端進(jìn)行恢復(fù)實例操作:
mysql > use test;
Database changed
mysql> show tables;
Empty set (0.00 sec)
#1、根據(jù)表結(jié)構(gòu)創(chuàng)建表(不要告訴我表結(jié)構(gòu)也已經(jīng)沒有了...)
CREATE TABLE `t1` (
`id` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
#2、discard 表空間
mysql> alter table t1 discard tablespace;
Query OK, 0 rows affected, 1 warning (0.01 sec)
#3、將上面準(zhǔn)備好的數(shù)據(jù)文件放入正確目錄
[root@admin-db64 data]#mv t1.ibd test/
#4、import 表空間
mysql> alter table t1 import tablespace;
Query OK, 0 rows affected, 1 warning (0.01 sec)
#5、查看數(shù)據(jù)是否可以正常查看
mysql> select * from t1;
+------+
| id |
+------+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
+------+
5 rows in set (0.00 sec)
通過上述步驟的操作,發(fā)現(xiàn)數(shù)據(jù)已經(jīng)可以正常查看,后面只需要將其備份出來,恢復(fù)到待恢復(fù)實例即可。此處不再贅述。
寫在最后
今天跟大家分享了一種誤刪數(shù)據(jù)文件利用內(nèi)存數(shù)據(jù)恢復(fù)的方法,其實還有一些其他的恢復(fù)方法,需要根據(jù)不同場景去選取最優(yōu)的處理方案。
最后,需要跟大家強調(diào)的是:預(yù)防遠(yuǎn)比處理的意義大得多。
另外,在 MySQL 的集群方案中,會時不時地用到備份來恢復(fù)實例,因此定期檢查備份的有效性也很有必要。如果你是業(yè)務(wù)開發(fā)同學(xué),你可以用 show grants 命令查看賬戶的權(quán)限,如果權(quán)限過大,可以建議 DBA 同學(xué)給你分配權(quán)限低一些的賬號;你也可以評估業(yè)務(wù)的重要性,和 DBA 商量備份的周期、是否有必要創(chuàng)建延遲復(fù)制的備庫等等。
記住,數(shù)據(jù)和服務(wù)的可靠性不止是運維團隊的工作,最終是各個合作環(huán)節(jié)一起保障的結(jié)果。