首頁 系統教程 Linux MySQL借助ibd檔案恢復資料技巧?

MySQL借助ibd檔案恢復資料技巧?

Jan 02, 2024 am 10:42 AM
linux linux教程 紅帽 linux系統 linux指令 linux認證 紅帽linux linux視頻

導讀 磁碟壞道、斷電等意外不是常態,但遇上了就足夠你「驚心動魄」!如果是資料庫損壞造成的資料遺失,Binlog也不可用了,怎麼辦?為了在短時間內無損恢復資料以確保業務穩定性,除了利用binlog,我們還修練了一招新的恢復技能!

還記得我們之前寫過的《只需一招,讓失控的研發愛上你》嗎?前文提到我們日常使用的比較多的兩種資料庫復原方法是:

MySQL借助ibd檔案恢復資料技巧?

#以上兩種方法都可以實現即時性的回檔,但是你會認為有了這兩種技能就夠了嗎?

不….!

在線上這種錯綜複雜的架構中,其實還有很多未知的原因,我們是沒法預知的。例如以下這種情況:

因辛勤工作而折壽的磁碟產生成長壞道,導致資料庫損壞。而又剛好損壞了ibdata檔和binlog檔。那如果還想著以定時備份 binlog恢復的方案就不可能了,難道只能用定點備份回檔嗎?經過深思熟慮後,身為維運人員,我們是絕對不會在萬不得已的情況下實行有損回檔,因為這對業務產生太大的影響了,但是除此之外又能怎麼辦呢?下面我們將要放一門大招! ! !

先檢查資料庫環境,是否開啟了獨立表空間,如果已經開啟的話,那恭喜你,有很大的機會可以恢復全部資料。我們可以依賴每個資料庫目錄下的frm和ibd檔來實現資料恢復,一般來說如果使用了InnoDB但沒開啟獨立表空間的話,所有的資料庫表資訊和元資料都會寫入ibdata檔裡,這樣長久運行的話,ibdata檔案會變得越來越大,資料庫效能下降。 InnoDB提供了開啟獨立表空間參數,可以讓資料獨立存放起來,這樣子ibdata檔案只用於存放一些引擎相關的索引信息,實際的資料寫入到獨立的frm和ibd檔裡。

好,有了frm和ibd文件,我們可以開始嘗試資料恢復了,他的過程比binlog還原既驚險又有趣!首先我們來看看關於ibd和frm的說明:

.frm檔案:保存了每個表的元數據,包括表結構的定義等,該文件與資料庫引擎無關。

.ibd檔案:InnoDB引擎開啟了獨立表空間(my.ini中配置innodb_file_per_table = 1)產生的存放該表的資料和索引的檔案。

我們都知道,對於InnoDB的資料庫,如果不把整個資料目錄拷貝,只拷貝指定資料庫目錄到新的實例下,資料庫是認不出來的。那麼如何根據這兩個檔案還恢復資料庫呢?

復原思路:

由於ibdata檔案上存放了一些關於引擎的索引信息,ibdata檔案損壞導致表名索引遺失而無法啟動。那我們可以先把原來舊的整個資料目錄改名備份,然後重新初始化資料庫產生新的ibdata文件,然後重新建立原有的資料庫以及對應的表,最後把備份的表空間id號改為新建的表空間id號(ibdata檔案裡有每個表唯一的表空間索引id,該id由建立新表的數量依序遞增),這樣就可以恢復原來的資料庫了。
舉個例子:
庫名:test_restore
表結構:db_struc.sql
表格檔案:G_RESTORE.ibd、G_RESTORE.frm

1. 建立新庫,導入表格結構

#mysql -uroot –p****  -e “create database test_restore”

#mysql -uroot –p****  test_restore 2. 檢視並修改test_restore庫中表在新實例中的id#

#vim -b /data/database/mysql/test_restore/G_RESTORE.ibd
登入後複製

直接開啟為亂碼,轉換成16進位檢視。 Vi中執行  :%!xxd 轉換為16進位。結果為 :

MySQL借助ibd檔案恢復資料技巧?

#如圖所示。 G_RESTORE表在mysql資料庫中的id為00fe。

修改備份的G_RESTORE.ibd檔。操作同上,注意需先備份。

#cp G_RESTORE.ibd{,_back}

#vim -v G_RESTORE.ibd
登入後複製

MySQL借助ibd檔案恢復資料技巧?

#將011b修改為00fe 。注意。修改完成後需要在vim中先執行 :%!xxd  -r

再wq 儲存退出檔案。不然儲存到的是16進位查看的結果。

儲存結果如下:

MySQL借助ibd檔案恢復資料技巧?

將修改好的G_RESTORE.ibd 取代掉新資料庫中的G_RESTORE.ibd檔。

關於ibdata表id的解釋:

MySQL借助ibd檔案恢復資料技巧?

#

参考官方文档解释,每个表空间分配了4个字节存储了表空间id信息,最后偏移量地址为38。还有一组预留的表空间id,同样是4个字节,最后偏移量地址为42。

3. 验证并还原mysql数据

关闭mysql。修改my.conf。
innodb_force_recovery=6 innodb_purge_threads=0

启动数据库。如果不修改。数据库会认为G_RESTORE已被损坏。

Select 一下,即可查看到还原结果,但此时插入数据会报错,应尽快将数据dump出来 ,导回原来的实例中。

导出数据,再导入数据,恢复完毕!

#mysqldump -uroot –p****** test_restore > test_restore.sql

#mysql -uroot –p****** test_restore 
<p>说明:变更了新的space id后的.ibd表文件,启动数据库后只能认出数据,但不能写入,这是因为原ibdata文件不仅保存了space id索引,还同时保存了一些其它的元数据。为了使元数据补全,所以采取导出、再导入的操作。</p>
<p>以上举例为单个库表的恢复过程,看到这里大家一定会产生另一个疑问吧?线上的场景不可能是只有一个表的,数据库表很多的情况下,这样一个个表的修改,速度无疑是太慢了。那么存在大量表的情况下如何恢复呢?思路是,取得备份的ibd文件的id值,按id值顺序来建表,中间跨度随便建表语句来凑够数(每个表空间索引id由创建新表的数量依次递增)。实现方式如下:</p>
<p><span style="color: #339966;"><strong>1. 获取备份数据库ibd文件的space id号,并排序。</strong></span></p>
<pre class="brush:php;toolbar:false">for ibd in `find test_restore/ -name “*.ibd”` ; do  echo -e “${ibd///// }   /c” ;hexdump -C ${ibd} |head -n 3 |tail -n 1|awk ‘{print  strtonum(“0x”$6$7)}’ ;done | sort -n  -k 3 | column -t > /tmp/
登入後複製

生成的ibd.txt文件,格式如下:(库名–表名–SpaceId)

MySQL借助ibd檔案恢復資料技巧?
2. 新建表,查看当前表空间id(假设space id为10)

#mysql -uroot –p****** -e”create table test.tt(a bool)”

#hexdump -C mysql/test/tt.ibd |head -n 3 |tail -n 1|awk ‘{print  strtonum(“0x”$6$7)}’
登入後複製

3. 先创建所有库,准备所有表结构,写脚本,依据space id号自动创建新表

准备好数据库表结构,可以从备份文件里取出来(我们备份方式是把结构和数据分开备份的),或者从其他有相同表结构的服务器上备份再拷贝过来。

参考备份语句:

mysqldump -uroot –p****** -d ${db} –T /data/backup/${db}/
登入後複製

创建原有的数据库:

mysql -uroot –p****** -e “create database ${db}”
登入後複製

恢复表id创建表脚本:

#!/bin/bash
#因为前面假设为10,所以从11开始创建
oid=11

#打开前面生成的ibd.txt文件,按行读取”库名–表名–SpaceId”
cat /tmp/ibd.txt | while read db tb id ;do

#假如我们需要恢复catetory表,他的id为415,基于id是创表自增的原则,即415-11=404,
#我们还需要循环创建404个表后,才真正导入catetory表结构。
for ((oid;oid<id do mysql table test.t bool echo ok done let oid="oid+1">
<p><span style="color: #339966;"><strong>4. 检查表空间id 和备份的是否一致</strong></span></p>
<pre class="brush:php;toolbar:false">for ibd in `find test_restore/ -name “*.ibd”` ; do  echo -e “${ibd///// }   /c” ;hexdump -C ${ibd} |head -n 3 |tail -n 1|awk ‘{print  strtonum(“0x”$6$7)}’ ;done | sort -n  -k 3 | column -t > /tmp/ibd2.txt
登入後複製

确认一致后,拷贝备份的.ibd文件到新数据库实例目录下,修改my.cnf

innodb_force_recovery=6

innodb_purge_threads=0

启动数据库。后续步骤如同单表恢复,直接导出恢复到原来实例中即可。

当然,这种方式是在数据库出现极端情况下,不得不采取的一种方式,线上最重要的还是做好主从同步和定时备份,从而规避此类风险。

关于InnoDB引擎独立表空间说明:

使用过MySQL的同学,刚开始接触最多的莫过于MyISAM表引擎了,这种引擎的数据库会分别创建三个文件:表结构、表索引、表数据空间。我们可以将某个数据库目录直接迁移到其他数据库也可以正常工作。然而当你使用InnoDB的时候,一切都变了。

InnoDB默认会将所有的数据库InnoDB引擎的表数据存储在一个共享空间中:ibdata1,这样就感觉不爽,增删数据库的时候,ibdata1文件不会自动收缩,单个数据库的备份也将成为问题。通常只能将数据使用mysqldump导出,然后再导入解决这个问题。

但是可以通过修改MySQL配置文件[mysqld]部分中innodb_file_per_table的参数来开启独立表空间模式,每个数据库的每个表都会生成一个数据空间。

优点:

1.每个表都有自已独立的表空间。

2.每个表的数据和索引都会存在自已的表空间中。

3.可以实现单表在不同的数据库中移动。

4.空间可以回收(除drop table操作处,表空不能自已回收)

a) Drop table操作自动回收表空间,如果对于统计分析或是日值表,删除大量数据后可以通过:alter table TableName engine=innodb;回缩不用的空间。

b) 对于使innodb-plugin的Innodb使用turncate table也会使空间收缩。

c) 对于使用独立表空间的表,不管怎么删除,表空间的碎片不会太严重的影响性能,而且还有机会处理。

缺點:

單表增加過大,如超過100個G。

結論:

共享表空間在Insert操作上少有優勢。其它都沒獨立表空間表現好。啟用獨立表空間時,請合理調整一下:innodb_open_files。

配置方式:
1.innodb_file_per_table設定.開啟方法:

在my.cnf中[mysqld]下設定

innodb_file_per_table=1
2.查看是否開啟:
mysql> show variables like ‘%per_table%’;

3.關閉獨享錶空間
innodb_file_per_table=0關閉獨立的表空間

mysql> show variables like ‘%per_table%’;

以上是MySQL借助ibd檔案恢復資料技巧?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

vscode需要什麼電腦配置 vscode需要什麼電腦配置 Apr 15, 2025 pm 09:48 PM

VS Code 系統要求:操作系統:Windows 10 及以上、macOS 10.12 及以上、Linux 發行版處理器:最低 1.6 GHz,推薦 2.0 GHz 及以上內存:最低 512 MB,推薦 4 GB 及以上存儲空間:最低 250 MB,推薦 1 GB 及以上其他要求:穩定網絡連接,Xorg/Wayland(Linux)

Linux體系結構:揭示5個基本組件 Linux體系結構:揭示5個基本組件 Apr 20, 2025 am 12:04 AM

Linux系統的五個基本組件是:1.內核,2.系統庫,3.系統實用程序,4.圖形用戶界面,5.應用程序。內核管理硬件資源,系統庫提供預編譯函數,系統實用程序用於系統管理,GUI提供可視化交互,應用程序利用這些組件實現功能。

vscode終端使用教程 vscode終端使用教程 Apr 15, 2025 pm 10:09 PM

vscode 內置終端是一個開發工具,允許在編輯器內運行命令和腳本,以簡化開發流程。如何使用 vscode 終端:通過快捷鍵 (Ctrl/Cmd ) 打開終端。輸入命令或運行腳本。使用熱鍵 (如 Ctrl L 清除終端)。更改工作目錄 (如 cd 命令)。高級功能包括調試模式、代碼片段自動補全和交互式命令歷史。

git怎麼查看倉庫地址 git怎麼查看倉庫地址 Apr 17, 2025 pm 01:54 PM

要查看 Git 倉庫地址,請執行以下步驟:1. 打開命令行並導航到倉庫目錄;2. 運行 "git remote -v" 命令;3. 查看輸出中的倉庫名稱及其相應的地址。

notepad怎麼運行java代碼 notepad怎麼運行java代碼 Apr 16, 2025 pm 07:39 PM

雖然 Notepad 無法直接運行 Java 代碼,但可以通過借助其他工具實現:使用命令行編譯器 (javac) 編譯代碼,生成字節碼文件 (filename.class)。使用 Java 解釋器 (java) 解釋字節碼,執行代碼並輸出結果。

vscode在哪寫代碼 vscode在哪寫代碼 Apr 15, 2025 pm 09:54 PM

在 Visual Studio Code(VSCode)中編寫代碼簡單易行,只需安裝 VSCode、創建項目、選擇語言、創建文件、編寫代碼、保存並運行即可。 VSCode 的優點包括跨平台、免費開源、強大功能、擴展豐富,以及輕量快速。

Linux的主要目的是什麼? Linux的主要目的是什麼? Apr 16, 2025 am 12:19 AM

Linux的主要用途包括:1.服務器操作系統,2.嵌入式系統,3.桌面操作系統,4.開發和測試環境。 Linux在這些領域表現出色,提供了穩定性、安全性和高效的開發工具。

vscode終端命令不能用 vscode終端命令不能用 Apr 15, 2025 pm 10:03 PM

VS Code 終端命令無法使用的原因及解決辦法:未安裝必要的工具(Windows:WSL;macOS:Xcode 命令行工具)路徑配置錯誤(添加可執行文件到 PATH 環境變量中)權限問題(以管理員身份運行 VS Code)防火牆或代理限制(檢查設置,解除限制)終端設置不正確(啟用使用外部終端)VS Code 安裝損壞(重新安裝或更新)終端配置不兼容(嘗試不同的終端類型或命令)特定環境變量缺失(設置必要的環境變量)

See all articles