MariaDB通過物理文件進行數據恢復
1、起因
時間:2022.03.12 10:10。
事件:網站的 mariadb 數據庫 server 突然崩潰,嘗試各種辦法啟動無果。
過程:不幸的是數據庫沒有備份,萬幸的是可以通過數據庫物理文件恢復數據。
結果:恢復數據,并特此記錄整個過程,以備急時之需。
2、數據庫與數據文件
眾所周知,數據庫中的數據會以文件的形式落盤進行保存(這些文件是以某種特定格式存儲的,不是text格式,試圖用文本編輯器打開會看到亂碼)。在數據庫中,每一個 database 都是一個單獨的文件夾,文件夾下存儲著每一張表的相關文件(不同的存儲引擎生成的表文件可能不同,這里使用 innodb 引擎)。
例如,筆者網站數據庫名稱叫做 ivansli,有一個用戶表 - user,脫敏之后的數據文件布局大致如下:
? /usr/local/data tree -L 2
.
├── aria_log.00000001
├── aria_log_control
├── ib_buffer_pool
├── ibdata1
├── ib_logfile0
├── ibtmp1
├── iZuf63yp8w5ku4znrskda8Z.err
├── iZuf63yp8w5ku4znrskda8Z.pid
├── multi-master.info
├── mysql-bin.000001
├── mysql-bin.000002
├── mysql-bin.000003
├── mysql-bin.index
├── mysql-slow.log
├── performance_schema
│ └── db.opt
└── ivansli
├── db.opt
├── user.frm
├── user.MYD
└── user.MYI
這里的 /usr/local/data 數據庫存儲數據的目錄。
ivansli文件夾下可以看到有三個不同格式,相同名稱的文件,作用分別為:user.frm,存儲數據表的元數據 user.MYD,存儲數據表的具體數據 user.MYI,存儲數據表的索引。
除了每張表的若干個文件之外,對于數據庫server來說還有一個重要的 ibdata1 文件(位于數據庫 server 存儲數據的根目錄)。
3、 ibdata 作用
ibdata (是InnoDB基礎結構的系統表空間) 包含幾個對InnoDB至關重要的信息:
- 表格數據頁。
- 表索引頁。
- 數據字典。
- MVCC控制數據。
撤消空間、回滾段
- 雙重寫入緩沖區(在后臺寫頁面以避免操作系統緩存)。
- 插入緩沖區(對二級索引的更改)。
筆者這里 innodb_file_per_table=0,使用共享表空間 ibdata1,所以恢復數據時需要拷貝這個文件 關于這個文件具體可以查閱相關資料。
對于筆者來說,雖然 數據庫 server 掛了,但是這些關鍵性的文件還是完整的。那么,就有辦法通過這些文件來恢復對應的數據。
舉個不太恰當的例子:
這里的數據恢復有點像器官移植,器官捐獻者可能已經大腦死亡。
但是捐獻者的心臟等器官還是有活力的,找到適合的目標受體,這些器官還是能夠繼續工作的。
4、 恢復過程
這里以 ivansli database 數據庫的恢復為例,整個恢復過程大致如下:
(1)查看當前待恢復的數據所在的 server(這里稱為 源數據庫server) 類型以及版本 筆者這里使用的是 mariadb - 10.7.0。
為什么要看已經 crash 掉的數據庫 server 的類型、版本呢?
主要是為數據恢復找到一個匹配的環境(類比器官移植,也是需要找到相同、相近的匹配受體,否則就會出問題)。
(2)在其他服務器搭建 與 源數據庫server 相同或者相近版本的 數據庫server (這里稱為 目標數據庫server) 搭建好之后,先把 目標數據庫server 停掉,暫時不啟動,為后面拷貝數據做準備。
(3)把 源數據庫server 待恢復的文件夾(這里是 ivansli 文件夾)與 ibdata1 文件拷貝到 目標數據庫server 數據目錄下 ivansli 文件夾在 目標數據庫server 數據庫存儲數據目錄下不存在,直接拷貝。ibdata1 文件在 目標數據庫server 數據庫存儲數據目錄下有同名文件,直接覆蓋。
(4)修改 目標數據庫server 數據庫存儲數據目錄下相關文件權限。
chmod -R 660 ivansli ibdata1
chown -R mysql:mysql ivansli ibdata1
chmod +x ivansli
(5)啟動 目標數據庫server。
(6)使用 root 賬號登錄 目標數據庫server,查看數據恢復情況。
(7)目標數據庫server上 能夠看到待恢復數據,做數據備份導出保存。
(8)在 源數據庫server 服務器上搭建新的 數據庫server,把恢復的數據導入進來。
5、 總結
對于開發人員來說,會經常聽到刪庫跑路、刪庫坐牢之類的事情發生。對于公司來說,最重要的是用戶的數據信息,尤其是金融等行業,寧可服務不可用,數據安全是一定要保證的。
這篇文章所描述的是在數據文件存在的特定情況下進行簡單的數據恢復。對于數據文件被刪除掉的情況,可能要進行掃描磁盤等更專業的操作了。
總之一句話:善待每一行代碼,謹慎敲打每一個命令。還有就是:做好數據備份、做好數據備份、做好數據備份。