1. 程式人生 > >Innodb單表資料物理恢復 • cenalulu's Tech Blog

Innodb單表資料物理恢復 • cenalulu's Tech Blog

本文將介紹使用物理備份恢復Innodb單表資料的方法

前言:

隨著innodb的普及,innobackup也成為了主流備份方式。物理備份對於新建slave,全庫恢復的需求都能從容應對。 但當面臨單表資料誤刪,或者單表誤drop的情況,如果使用物理全備進行恢復呢? 下文將進行詳細分析。 恢復過程中需要用到的工具,percona data recover tool PS:以下所有方案僅支援 innodb-file-per-table = 1 的情況 注意: 以下操作非文件推薦,切勿在沒有測試的情況下直接在production環境使用!!!

情況一:邏輯誤操作,誤刪部分資料

這種情況可以用來自同一臺機器的的最近一次物理備份中的ibd恢復覆蓋,且備份後table沒有被recreate過。 這種情況是最簡單的,備份時的ibd檔案(後稱老ibd)中的space id和index id 與 新ibd的space id 和index id一致。 且和ibdata檔案中的space id和index id一致。因此,物理檔案可以直接覆蓋做恢復。

以下是詳細步驟

準備階段

Step pre 1: 物理備份

innobackupex --defaults-file=/usr/local/mysql3321/my.cnf --socket=/xfs/mysql3321/mysql.sock --user=
root --password=password /xfs/backup/

Step pre 2 : 停止資料庫對外服務

service mysqld restart #(起在另外一個埠上)

或者 停止所有業務連線並且set global innodb_max_dirty_pages_pct =0

操作階段

Step 0 : apply log

innobackupex --apply-log --defaults-file=/usr/local/mysql3321/my.cnf  /xfs/backup/2012-10-17_11-29-20/

Step 1 : 備份現在的ibd檔案(可選)

cp -a testibd.ibd testibd.bak

Step 2 : 捨棄現在ibd檔案

mysql> alter table testibd discard tablespace

Step 3 : 複製備份ibd檔案

shell> cp /xfs/backup/2012-10-17_11-29-20/test/testibd.ibd /xfs/mysql3321/test/ 
shell> chown mysql:mysql /xfs/mysql3321/test/testibd.ibd

Step 4 : 匯入ibd檔案

mysql> alter table testibd import tablespace

情況二:誤刪 table,表結構已經被drop了

這種情況稍複雜,不過恢復過程還是比較容易操作的。由於table被drop後的space id會留空因此備份檔案的space id不會被佔用。

我們只需要重建表結構,然後把ibdata中該表的space id還原,物理檔案可以直接覆蓋做恢復了。

Step 1 : 重建表

mysql> alter table testibd import tablespace

mysql> create table testibd (UserID int);

Step 2 : 關閉mysql服務(必須)

shell> service mysqld3321 stop

Step 3: 準備ibd檔案 apply log

shell> innobackupex --apply-log --defaults-file=/usr/local/mysql3321/my.cnf  /xfs/backup/2012-10-17_11-29-20/

Step 4 : 備份現在的ibd檔案(可選)

cp -a testibd.ibd testibd.bak

Step 5 : 複製備份ibd檔案

shell> cp -a /xfs/backup/2012-10-17_11-29-20/test/testibd.ibd /xfs/mysql3321/test/ 
shell> chown mysql:mysql /xfs/mysql3321/test/testibd.ibd

Step 6 : 使用percona recovery tool 修改ibdata

shell> /root/install/percona-data-recovery-tool-for-innodb-0.5/ibdconnect -o /xfs/mysql3321/ibdata1 -f /xfs/mysql3321/test/testibd.ibd -d test -t testibd

輸出結果

Initializing table definitions...
Processing table: SYS_TABLES
 - total fields: 10
 - nullable fields: 6
 - minimum header size: 5
 - minimum rec size: 21
 - maximum rec size: 555

Processing table: SYS_INDEXES
 - total fields: 9
 - nullable fields: 5
 - minimum header size: 5
 - minimum rec size: 29
 - maximum rec size: 165

Setting SPACE=1 in SYS_TABLE for `test`.`testibd`
Check if space id 1 is already used
Page_id: 8, next page_id: 4294967295
Record position: 65
Checking field lengths for a row (SYS_TABLES): OFFSETS: 16 8 50 3 2 0 0 0 0 0 
Db/table: infimum
Space id: 1768842857 (0x696E6669)
Next record at offset: 8D
Record position: 8D
Checking field lengths for a row (SYS_TABLES): OFFSETS: 16 11 17 24 32 36 40 48 52 52 
Db/table: SYS_FOREIGN
Space id: 0 (0x0)
Next record at offset: D5
Record position: D5
Checking field lengths for a row (SYS_TABLES): OFFSETS: 16 16 22 29 37 41 45 53 57 57 
Db/table: SYS_FOREIGN_COLS
Space id: 0 (0x0)
Next record at offset: 122
Record position: 122
Checking field lengths for a row (SYS_TABLES): OFFSETS: 16 12 18 25 33 37 41 49 53 53 
Db/table: test/testibd
Space id: 2 (0x2)
Next record at offset: 74
Space id 1 is not used in any of the records in SYS_TABLES
Page_id: 8, next page_id: 4294967295
Record position: 65
Checking field lengths for a row (SYS_TABLES): OFFSETS: 16 8 50 3 2 0 0 0 0 0 
Db/table: infimum
Space id: 1768842857 (0x696E6669)
Next record at offset: 8D
Record position: 8D
Checking field lengths for a row (SYS_TABLES): OFFSETS: 16 11 17 24 32 36 40 48 52 52 
Db/table: SYS_FOREIGN
Space id: 0 (0x0)
Next record at offset: D5
Record position: D5
Checking field lengths for a row (SYS_TABLES): OFFSETS: 16 16 22 29 37 41 45 53 57 57 
Db/table: SYS_FOREIGN_COLS
Space id: 0 (0x0)
Next record at offset: 122
Record position: 122
Checking field lengths for a row (SYS_TABLES): OFFSETS: 16 12 18 25 33 37 41 49 53 53 
Db/table: test/testibd
Space id: 2 (0x2)
Updating test/testibd (table_id 17) with id 0x01000000
SYS_TABLES is updated successfully
Initializing table definitions...
Processing table: SYS_TABLES
 - total fields: 10
 - nullable fields: 6
 - minimum header size: 5
 - minimum rec size: 21
 - maximum rec size: 555

Processing table: SYS_INDEXES
 - total fields: 9
 - nullable fields: 5
 - minimum header size: 5
 - minimum rec size: 29
 - maximum rec size: 165

Setting SPACE=1 in SYS_INDEXES for TABLE_ID = 17
Page_id: 11, next page_id: 4294967295
Record position: 65
Checking field lengths for a row (SYS_INDEXES): OFFSETS: 15 8 50 7 2 0 0 0 0 
TABLE_ID: 3798561113125514496
SPACE: 1768842857
Next record at offset: 8C
Record position: 8C
Checking field lengths for a row (SYS_INDEXES): OFFSETS: 15 8 16 22 29 35 39 43 47 
TABLE_ID: 11
SPACE: 0
Next record at offset: CE
Record position: CE
Checking field lengths for a row (SYS_INDEXES): OFFSETS: 15 8 16 22 29 36 40 44 48 
TABLE_ID: 11
SPACE: 0
Next record at offset: 111
Record position: 111
Checking field lengths for a row (SYS_INDEXES): OFFSETS: 15 8 16 22 29 36 40 44 48 
TABLE_ID: 11
SPACE: 0
Next record at offset: 154
Record position: 154
Checking field lengths for a row (SYS_INDEXES): OFFSETS: 15 8 16 22 29 35 39 43 47 
TABLE_ID: 12
SPACE: 0
Next record at offset: 22C
Record position: 22C
Checking field lengths for a row (SYS_INDEXES): OFFSETS: 15 8 16 22 29 44 48 52 56 
TABLE_ID: 17
SPACE: 2
Updating SPACE(0x00000001 , 0x01000000) for TABLE_ID: 17
sizeof(s)=4
Next record at offset: 74
SYS_INDEXES is updated successfully

Step 7 : 使用percona recovery tool 重新checksum ibdata

重複執行以下命令,直到程式沒有輸出為止。

shell> /root/install/percona-data-recovery-tool-for-innodb-0.5/innochecksum -f /xfs/mysql3321/ibdata1

輸出結果

page 8 invalid (fails old style checksum)
page 8: old style: calculated = 0xF4AD74CB; recorded = 0xEECB309D
fixing old checksum of page 8
page 8 invalid (fails new style checksum)
page 8: new style: calculated = 0x6F0C29B4; recorded = 0x3D02308C
fixing new checksum of page 8
page 11 invalid (fails old style checksum)
page 11: old style: calculated = 0x3908087C; recorded = 0xF9E8D30C
fixing old checksum of page 11
page 11 invalid (fails new style checksum)
page 11: new style: calculated = 0xB26CFD77; recorded = 0xDB25D39D
fixing new checksum of page 11

Step 8 : 啟動mysql服務

shell> service mysqld3321 start

參考文件:

http://www.chriscalender.com/?p=28

http://www.mysqlperformanceblog.com/2011/05/13/connecting-orphaned-ibd-files/

http://blogs.innodb.com/wp/2012/04/innodb-transportable-tablespaces/

http://www.mysqlperformanceblog.com/2012/01/25/how-to-recover-a-single-innodb-table-from-a-full-backup/