首頁 系統教程 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 &gt; /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 &gt; /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

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
1 週前 By 尊渡假赌尊渡假赌尊渡假赌
倉庫:如何復興隊友
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒險:如何獲得巨型種子
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
1 週前 By 尊渡假赌尊渡假赌尊渡假赌
倉庫:如何復興隊友
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒險:如何獲得巨型種子
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱門文章標籤

記事本++7.3.1

記事本++7.3.1

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

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

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

Android TV Box 獲得非官方 Ubuntu 24.04 升級 Android TV Box 獲得非官方 Ubuntu 24.04 升級 Sep 05, 2024 am 06:33 AM

Android TV Box 獲得非官方 Ubuntu 24.04 升級

deepseek網頁版入口 deepseek官網入口 deepseek網頁版入口 deepseek官網入口 Feb 19, 2025 pm 04:54 PM

deepseek網頁版入口 deepseek官網入口

deepseek怎麼安裝 deepseek怎麼安裝 Feb 19, 2025 pm 05:48 PM

deepseek怎麼安裝

BitPie比特派錢包app下載位址 BitPie比特派錢包app下載位址 Sep 10, 2024 pm 12:10 PM

BitPie比特派錢包app下載位址

BITGet官方網站安裝(2025新手指南) BITGet官方網站安裝(2025新手指南) Feb 21, 2025 pm 08:42 PM

BITGet官方網站安裝(2025新手指南)

詳解:Shell腳本變數判斷參數指令 詳解:Shell腳本變數判斷參數指令 Sep 02, 2024 pm 03:25 PM

詳解:Shell腳本變數判斷參數指令

Zabbix 3.4 原始碼編譯安裝 Zabbix 3.4 原始碼編譯安裝 Sep 04, 2024 am 07:32 AM

Zabbix 3.4 原始碼編譯安裝

歐易okx安裝包直接進 歐易okx安裝包直接進 Feb 21, 2025 pm 08:00 PM

歐易okx安裝包直接進

See all articles