MYSQL Space id in fsp header,but in the page header錯誤
今天啟動MYSQL的時候發現如下問題:
2015-12-14 20:51:59 2098 [ERROR] InnoDB: Space id in fsp header 131225,but in the page header 65
2015-12-14 20:51:59 2098 [ERROR] InnoDB: inconsistent data in space header in tablespace ./test/oneblock.ibd (table test/oneblock)
innodb的儲存包含
tablespace--segment--extent--block(pages)
而tablespace有一個space id 及用於描述表空間的唯一編號,ibdata的space id為0,這個ibdata為,
SYSTEM SPACE,其中會包含很多普通SPACE_ID 不包含的資料段,或者說資料塊,如回滾段。
如果開啟了innodb_file_per_table,每個innodb 表檔案都有space id,其中檔案包含了表的資料和索引資料。
而普通的space 包含的資訊較少一些
我們這裡主要分析這裡也只要分析普通的space,也就是innodb_file_per_table建立的ibd檔案。
使用工具(自己寫的工具):
[root@hadoop1 test]# mysqlblock c1.ibd -t
***************************************************
USEAGE: mysqlblock datafile -t/-d
This small tool used in study and test database,not
uesd on online database!
This tool is used to find how many blocks and types
in specified datafile,Exp:how many undo block in d
ata file!
QQ:22389860
***************************************************
-t Only Total blocks types in ibdata!
-d Blocks types detail in ibdata!
***************************************************
FILE SIZE IS : 10485760
Total Block Status :
Total block : 640,Total size is: 10.000000 MB
Total undo block : 0,Total size is: 0.000000 MB
Total index node block : 1,Total size is: 0.015625 MB
Total insert buffer free blocks: 0,Total size is: 0.000000 MB
Total data(leaf node) block : 113,Total size is: 1.765625 MB
Total new allocate blocks : 524,Total size is: 8.187500 MB
Total insert buf bitmap blocks : 1,Total size is: 0.015625 MB
Total system blocks : 0,Total size is: 0.000000 MB
Total transaction system blocks: 0,Total size is: 0.000000 MB
Total file space header blocks : 1,Total size is: 0.015625 MB
Total extrenl disc blocks : 0,Total size is: 0.000000 MB
Total LOB blocks : 0,Total size is: 0.000000 MB
Total Unkown blocks : 0,Total size is: 0.000000 MB
這裡我們可以清晰的看到每種塊的數量,其中注意一個特殊的塊
Total file space header blocks及FSP_HDR BLOCK,這個塊是每個space 必須的,
即使SYSTEM SPACE也包含,他總是SPACE的第一個塊。
而每個塊同樣包含了file header.
Space id in fsp header 131225,but in the page header 65
這裡的fsp header就是 file space header ,及第一個塊的後38到150位元組,
而 page header這裡實際上是file header 及 FIL header,這個是塊固有的前38位元組。
這裡有點繞:
一個是file header(每個塊固有的前38位元組)
一個是file space header(space的第一個塊的38-150位元組)
file header(FIL header)
包含如下0-37位元組
checksum(4) 0-3
offset(4) 4-7
previous page(4) 8-11
next page(4) 12-15
LSN for last page modification(8) 16-23
page type (2) 24-25
FLUSH LSN(8) 26-33
SPACE ID(4) 34-37
其中的每個值的意思有些是自解釋的,而有些需要更深入的研究,但是一個塊是一個雙向指標的節點可以肯定。
並且記錄每個塊的LSN記錄,應該用於塊恢復。這部分是每個塊都一樣的。而這裡SPCAE ID在
page header 中說明每個塊中都會有個這個值。記錄的就是SPACE_ID不用過多解釋
接下來我們來看file space header block 特有的
38-150位元組:file space header(FSP HEADER)
SPACE_ID (4)
unused(4)
highest page number in file(size)(4)
highest page number initialized (free limit)(4)
flags(4)
number of pages uesd in "free_frag" list(4)
list base node for "free" list(16)
list base node for "free_frag" list(16)
list base node for "full_frag" list(16)
nex unused segment id(8)
list base node for "full_nodes" list(16)
list base node for "free_nodes" list(16)
其中很多值還需要深入的研究 但是我們發現在38-41位元組就包含了SPACE_ID。
那麼我們就找到了
Space id in fsp header 131225,but in the page header 65
中的 fsp header 來自哪裡 ,他來自FSP HEADER及ibd 檔案的第一個塊的第38-41位元組
而page header 65,來自每個塊的第34-37位元組。
既然如此我們可以進行測試模擬這種現象,我們手動修改這4個位元組。使用我自己寫的工具,由於LINUX下沒找到合適工具乾脆自己寫了兩個。
bctool和bcview
bctool 用於修改
bcview 用於檢視
主要測試方式
1、修改FSP HEADER的38-41位元組檢視MYSQL INNODB 報錯,然後修改回去後是否能夠順利啟動
2、修改第一個塊file space header的34-37位元組 檢視看MYSQL INNODB 報錯,然後修改回去後是否能夠順利啟動
3、修改任意一個塊的file space header的34-37位元組 檢視看MYSQL INNODB 報錯,然後修改回去後是否能夠順利啟動
我們依然使用test資料庫下的c1 表其innodb 資料檔案為c1.ibd
一、修改FSP HEADER的38-41位元組檢視MYSQL INNODB 報錯,然後修改回去後是否能夠順利啟動
透過bcview檢視塊的34-37位元組
[root@hadoop1 test]# bcview c1.ibd 16 34 4|more
******************************************************************
This Tool Is Uesed For Find The Data In Binary format(Hexadecimal)
Usage:./bcview file blocksize offset cnt-bytes!
file: Is Your File Will To Find Data!
blocksize: Is N kb Block.Eg: 8 Is 8 Kb Blocksize(Oracle)!
Eg: 16 Is 16 Kb Blocksize(Innodb)!
offset:Is Every Block Offset Your Want Start!
cnt-bytes:Is After Offset,How Bytes Your Want Gets!
Edtor QQ:22389860!
Used gcc version 4.1.2 20080704 (Red Hat 4.1.2-46)
******************************************************************
----Current file size is :10.000000 Mb
----Current use set blockszie is 16 Kb
current block:00000000--Offset:00034--cnt bytes:04--data is:00000048
current block:00000001--Offset:00034--cnt bytes:04--data is:00000048
current block:00000002--Offset:00034--cnt bytes:04--data is:00000048
current block:00000003--Offset:00034--cnt bytes:04--data is:00000048
current block:00000004--Offset:00034--cnt bytes:04--data is:00000048
current block:00000005--Offset:00034--cnt bytes:04--data is:00000048
current block:00000006--Offset:00034--cnt bytes:04--data is:00000048
current block:00000007--Offset:00034--cnt bytes:04--data is:00000048
current block:00000008--Offset:00034--cnt bytes:04--data is:00000048
current block:00000009--Offset:00034--cnt bytes:04--data is:00000048
current block:00000010--Offset:00034--cnt bytes:04--data is:00000048
.......
當然後面還有很多塊,但是這裡bcview c1.ibd 16 34 4 就是16KB大小34位元組開始,一共4個位元組輸出。
我們發現全是00000048,因為每個space_id在page header 都會記錄,
那麼他的space id 就是0X48 10進位制就是72,我們在MYSQL中驗證一下:
mysql> select * from INNODB_SYS_TABLESPACES where space=72;
+-------+---------+------+-------------+----------------------+-----------+---------------+
| SPACE | NAME | FLAG | FILE_FORMAT | ROW_FORMAT | PAGE_SIZE | ZIP_PAGE_SIZE |
+-------+---------+------+-------------+----------------------+-----------+---------------+
| 72 | test/c1 | 0 | Antelope | Compact or Redundant | 16384 | 0 |
+-------+---------+------+-------------+----------------------+-----------+---------------+
1 row in set (0.01 sec)
可以看到沒有問題。
那麼接下我們來看38到41位元組,為了更好的說明我使用 mysqlblock c1.ibd -d|more的d選項檢視詳細塊資訊
並且使用bcview c1.ibd 16 38 4|more
current block:00000000--Offset:00038--cnt bytes:04--data is:00000048
current block:00000001--Offset:00038--cnt bytes:04--data is:00000000
current block:00000002--Offset:00038--cnt bytes:04--data is:ffffffff
current block:00000003--Offset:00038--cnt bytes:04--data is:000601c8
current block:00000004--Offset:00038--cnt bytes:04--data is:00343b26
current block:00000005--Offset:00038--cnt bytes:04--data is:00663b26
current block:00000006--Offset:00038--cnt bytes:04--data is:00663b26
current block:00000007--Offset:00038--cnt bytes:04--data is:00663b26
current block:00000008--Offset:00038--cnt bytes:04--data is:00663b26
current block:00000009--Offset:00038--cnt bytes:04--data is:00663b26
current block:00000010--Offset:00038--cnt bytes:04--data is:00663b26
current block:00000011--Offset:00038--cnt bytes:04--data is:00663b26
current block:00000012--Offset:00038--cnt bytes:04--data is:00663b26
current block:00000013--Offset:00038--cnt bytes:04--data is:00663b26
current read blocks is : 0 --This Block is file space header blocks!
current read blocks is : 1 --This Block is insert buffer bitmap blocks!
current read blocks is : 2 --This Block is index node blocks!
current read blocks is : 3 --This Block is data blocks(Tree leaf node)!
current read blocks is : 4 --This Block is data blocks(Tree leaf node)!
current read blocks is : 5 --This Block is data blocks(Tree leaf node)!
current read blocks is : 6 --This Block is data blocks(Tree leaf node)!
current read blocks is : 7 --This Block is data blocks(Tree leaf node)!
current read blocks is : 8 --This Block is data blocks(Tree leaf node)!
current read blocks is : 9 --This Block is data blocks(Tree leaf node)!
current read blocks is : 10 --This Block is data blocks(Tree leaf node)!
current read blocks is : 11 --This Block is data blocks(Tree leaf node)!
current read blocks is : 12 --This Block is data blocks(Tree leaf node)!
current read blocks is : 13 --This Block is data blocks(Tree leaf node)!
current read blocks is : 14 --This Block is data blocks(Tree leaf node)!
現在我們清楚的看到了38-41這4個位元組只有fsp_header塊是00000048就是space_id
其他型別的塊並不是。
接下來我們使用bctool進行修改FSP HEADER的38-41位元組。還是關閉資料庫後進行更改
為了安全首先備份一下
[root@hadoop1 test]# cp c1.ibd c1.ibdbak
然後:
[root@hadoop1 test]# bctool c1.ibd 0 38 000000ee
******************************************************************
This tool is uesed to check data ues binary format,no Big-Endian
or Little-Endian diff,this tool is base one byte on byte to change
!block is 16k.if want change other block eg:8k! please set blocks
0 and offset blocks*8192+offset!
usage:./bctool yfile blocks offset yourdata(XX)!
Warings:backup file frist!!!!!!!!!
Editor QQ:22389860
Ues gcc version 4.1.2 20080704 (Red Hat 4.1.2-46)
******************************************************************
0-0-0-ee
再次檢視:
bcview c1.ibd 16 38 4|more
current block:00000000--Offset:00038--cnt bytes:04--data is:000000ee
current block:00000001--Offset:00038--cnt bytes:04--data is:00000000
current block:00000002--Offset:00038--cnt bytes:04--data is:ffffffff
current block:00000003--Offset:00038--cnt bytes:04--data is:000601c8
已經被我更改為ee了
然後啟動MYSQL,雖然資料庫起來了但是
mysql> select count(*) from c1;
ERROR 2013 (HY000): Lost connection to MySQL server during query
資料庫立即當機
[root@hadoop1 test]# service mysqldefault start
Starting MySQL..The server quit without updating PID file (/mysql/data/hadoop1.pid).[FAILED]
再次啟動已經無用,檢視日誌:
2015-12-26 01:05:38 5074 [ERROR] InnoDB: Space id in fsp header 238,but in the page header 72
2015-12-26 01:05:38 5074 [ERROR] InnoDB: checksum mismatch in tablespace ./test/c1.ibd (table test/c1)
2015-12-26 01:05:38 5074 [Note] InnoDB: Page size:1024 Pages to analyze:64
2015-12-26 01:05:38 5074 [Note] InnoDB: Page size: 1024, Possible space_id count:0
2015-12-26 01:05:38 5074 [Note] InnoDB: Page size:2048 Pages to analyze:64
2015-12-26 01:05:38 5074 [Note] InnoDB: Page size: 2048, Possible space_id count:0
2015-12-26 01:05:38 5074 [Note] InnoDB: Page size:4096 Pages to analyze:64
2015-12-26 01:05:38 5074 [Note] InnoDB: Page size: 4096, Possible space_id count:0
2015-12-26 01:05:38 5074 [Note] InnoDB: Page size:8192 Pages to analyze:64
2015-12-26 01:05:38 5074 [Note] InnoDB: Page size: 8192, Possible space_id count:0
2015-12-26 01:05:38 5074 [Note] InnoDB: Page size:16384 Pages to analyze:64
.....
我們發現錯誤重現238 換算為16進位制就是我們修改的0XEE.
這種情況也許innodb_force_recovery > 0 有用,但是我沒有試驗。
接著我來將fsp header 的38-41位元組改回0X48,然後啟動。
[root@hadoop1 test]# bctool c1.ibd 0 38 00000048
再次檢視
[root@hadoop1 test]# bcview c1.ibd 16 38 4|more
current block:00000000--Offset:00038--cnt bytes:04--data is:00000048
啟動:
[root@hadoop1 test]# service mysqldefault start
Starting MySQL...[ OK ]
啟動完成。
mysql> select count(*) from c1;
+----------+
| count(*) |
+----------+
| 8192 |
+----------+
1 row in set (0.01 sec)
查詢沒有問題。
二、修改第一個塊file space header的34-37位元組 檢視看MYSQL INNODB 報錯,然後修改回去後是否能夠順利啟動
再次關閉資料,
使用bcview檢視
[root@hadoop1 test]# bcview c1.ibd 16 34 4|more
current block:00000000--Offset:00034--cnt bytes:04--data is:00000048
修改:
[root@hadoop1 test]# bctool c1.ibd 0 34 00000099
檢視
[root@hadoop1 test]# bcview c1.ibd 16 34 4|more
current block:00000000--Offset:00034--cnt bytes:04--data is:00000099
啟動資料庫,檢視資料
mysql> select count(*) from c1;
ERROR 2013 (HY000): Lost connection to MySQL server during query
檢視日誌:
2015-12-26 01:17:46 6122 [ERROR] InnoDB: Space id in fsp header 72,but in the page header 153
這裡的153就是0X99對比剛才的
2015-12-26 01:05:38 5074 [ERROR] InnoDB: Space id in fsp header 238,but in the page header 72
可以從日誌中看出這次是fsp header正常,file header 錯誤。
那麼我們同樣修改回來:
[root@hadoop1 test]# bctool c1.ibd 0 34 00000048
檢視
current block:00000000--Offset:00034--cnt bytes:04--data is:00000048
已經修改回來,接著啟動
mysql> select count(*) from c1;
+----------+
| count(*) |
+----------+
| 8192 |
+----------+
1 row in set (0.01 sec)
沒有問題可以查詢
三、修改任意一個塊的file space header的34-37位元組 檢視看MYSQL INNODB 報錯,然後修改回去後是否能夠順利啟動
既然每個資料塊的file header都包含了space id,那麼我們隨意更改一個塊的
current read blocks is : 0 --This Block is file space header blocks!
current read blocks is : 1 --This Block is insert buffer bitmap blocks!
current read blocks is : 2 --This Block is index node blocks!
current read blocks is : 3 --This Block is data blocks(Tree leaf node)!
current read blocks is : 4 --This Block is data blocks(Tree leaf node)!
current read blocks is : 5 --This Block is data blocks(Tree leaf node)!
這裡就選擇5號塊(0開始實際是第6個),這個塊為資料塊。
具體過程不再給出,給出命令
[root@hadoop1 test]# bctool c1.ibd 5 34 00000088
[root@hadoop1 test]# bcview c1.ibd 16 34 4|more
current block:00000005--Offset:00034--cnt bytes:04--data is:00000088
檢視資料沒有問題,但是日誌有報錯
2015-12-26 01:25:58 403be940 InnoDB: Error: space id and page n:o stored in the page
InnoDB: read in are 136:5, should be 72:5!
可以看到innodb 說 5號塊的space id是136 就是0X88,應該是72,雖然資料還能跑,這個錯誤到底
影響多大未知但是我們知道原因,修改回去
關閉資料庫:
[root@hadoop1 test]# bctool c1.ibd 0 34 00000048
[root@hadoop1 test]# bcview c1.ibd 16 34 4|more
current block:00000005--Offset:00034--cnt bytes:04--data is:00000048
錯誤消失
總結:
1、我們可以知道什麼是space id,space id 就是表空間的唯一標識
2、我們可以知道什麼是FSP HEADER BLOCK 及每個space 檔案第一個塊,
而FSP HEADER 存放在每一個SPACE檔案的第一個塊的38-150位元組,實際這個塊還會存放XDS資訊就是EXTENTS的資訊這裡不
再介紹
3、我們可以知道訪問表的時候如果第一個塊的FIL HEADER的34-37位元組的SPCAE_ID和FSP HEADER的38-41位元組對應不上資料庫會
立即當機。
報錯:
2015-12-26 01:05:38 5074 [ERROR] InnoDB: Space id in fsp header 238,but in the page header 72
4、我們還知道了如果不是第一個塊的FIL HEADER 34-37位元組 space id出現問題,日誌只會報錯,但是不影響使用
報錯:
2015-12-26 01:25:58 403be940 InnoDB: Error: space id and page n:o stored in the page
InnoDB: read in are 136:5, should be 72:5!
5、為了完成這個實驗,我使用了3個工具,均為自己寫的,如果沒有這3個工具這個實驗無法完成,或者很困難
---mysqlblock :用於檢視資料檔案中塊的型別
***************************************************
USEAGE: mysqlblock datafile -t/-d
This small tool used in study and test database,not
uesd on online database!
This tool is used to find how many blocks and types
in specified datafile,Exp:how many undo block in d
ata file!
QQ:22389860
***************************************************
-t Only Total blocks types in ibdata!
-d Blocks types detail in ibdata!
***************************************************
USEAGE: mysqlblock datafile -t/-d
---bcview:用於檢視塊的固定位元組輸出
******************************************************************
This Tool Is Uesed For Find The Data In Binary format(Hexadecimal)
Usage:./bcview file blocksize offset cnt-bytes!
file: Is Your File Will To Find Data!
blocksize: Is N kb Block.Eg: 8 Is 8 Kb Blocksize(Oracle)!
Eg: 16 Is 16 Kb Blocksize(Innodb)!
offset:Is Every Block Offset Your Want Start!
cnt-bytes:Is After Offset,How Bytes Your Want Gets!
Edtor QQ:22389860!
Used gcc version 4.1.2 20080704 (Red Hat 4.1.2-46)
******************************************************************
usage:./bcview file blocksize offset cnt-bytes!
---bctool:用於修改某個塊的某個位元組的資料(現支援16K)
******************************************************************
This tool is uesed to check data ues binary format,no Big-Endian
or Little-Endian diff,this tool is base one byte on byte to change
!block is 16k.if want change other block eg:8k! please set blocks
0 and offset blocks*8192+offset!
usage:./bctool yfile blocks offset yourdata(XX)!
Warings:backup file frist!!!!!!!!!
Editor QQ:22389860
Ues gcc version 4.1.2 20080704 (Red Hat 4.1.2-46)
******************************************************************
usage:./bctool file block offset yourdata(XX)!
當然bctool和bcview 可以修改和檢視任何檔案,不光是INNODB BLOCK。
本三個工具均上傳到了百度雲盤
LINUX下使用,注意給予執行許可權
2015-12-14 20:51:59 2098 [ERROR] InnoDB: Space id in fsp header 131225,but in the page header 65
2015-12-14 20:51:59 2098 [ERROR] InnoDB: inconsistent data in space header in tablespace ./test/oneblock.ibd (table test/oneblock)
innodb的儲存包含
tablespace--segment--extent--block(pages)
而tablespace有一個space id 及用於描述表空間的唯一編號,ibdata的space id為0,這個ibdata為,
SYSTEM SPACE,其中會包含很多普通SPACE_ID 不包含的資料段,或者說資料塊,如回滾段。
如果開啟了innodb_file_per_table,每個innodb 表檔案都有space id,其中檔案包含了表的資料和索引資料。
而普通的space 包含的資訊較少一些
我們這裡主要分析這裡也只要分析普通的space,也就是innodb_file_per_table建立的ibd檔案。
使用工具(自己寫的工具):
[root@hadoop1 test]# mysqlblock c1.ibd -t
***************************************************
USEAGE: mysqlblock datafile -t/-d
This small tool used in study and test database,not
uesd on online database!
This tool is used to find how many blocks and types
in specified datafile,Exp:how many undo block in d
ata file!
QQ:22389860
***************************************************
-t Only Total blocks types in ibdata!
-d Blocks types detail in ibdata!
***************************************************
FILE SIZE IS : 10485760
Total Block Status :
Total block : 640,Total size is: 10.000000 MB
Total undo block : 0,Total size is: 0.000000 MB
Total index node block : 1,Total size is: 0.015625 MB
Total insert buffer free blocks: 0,Total size is: 0.000000 MB
Total data(leaf node) block : 113,Total size is: 1.765625 MB
Total new allocate blocks : 524,Total size is: 8.187500 MB
Total insert buf bitmap blocks : 1,Total size is: 0.015625 MB
Total system blocks : 0,Total size is: 0.000000 MB
Total transaction system blocks: 0,Total size is: 0.000000 MB
Total file space header blocks : 1,Total size is: 0.015625 MB
Total extrenl disc blocks : 0,Total size is: 0.000000 MB
Total LOB blocks : 0,Total size is: 0.000000 MB
Total Unkown blocks : 0,Total size is: 0.000000 MB
這裡我們可以清晰的看到每種塊的數量,其中注意一個特殊的塊
Total file space header blocks及FSP_HDR BLOCK,這個塊是每個space 必須的,
即使SYSTEM SPACE也包含,他總是SPACE的第一個塊。
而每個塊同樣包含了file header.
Space id in fsp header 131225,but in the page header 65
這裡的fsp header就是 file space header ,及第一個塊的後38到150位元組,
而 page header這裡實際上是file header 及 FIL header,這個是塊固有的前38位元組。
這裡有點繞:
一個是file header(每個塊固有的前38位元組)
一個是file space header(space的第一個塊的38-150位元組)
file header(FIL header)
包含如下0-37位元組
checksum(4) 0-3
offset(4) 4-7
previous page(4) 8-11
next page(4) 12-15
LSN for last page modification(8) 16-23
page type (2) 24-25
FLUSH LSN(8) 26-33
SPACE ID(4) 34-37
其中的每個值的意思有些是自解釋的,而有些需要更深入的研究,但是一個塊是一個雙向指標的節點可以肯定。
並且記錄每個塊的LSN記錄,應該用於塊恢復。這部分是每個塊都一樣的。而這裡SPCAE ID在
page header 中說明每個塊中都會有個這個值。記錄的就是SPACE_ID不用過多解釋
接下來我們來看file space header block 特有的
38-150位元組:file space header(FSP HEADER)
SPACE_ID (4)
unused(4)
highest page number in file(size)(4)
highest page number initialized (free limit)(4)
flags(4)
number of pages uesd in "free_frag" list(4)
list base node for "free" list(16)
list base node for "free_frag" list(16)
list base node for "full_frag" list(16)
nex unused segment id(8)
list base node for "full_nodes" list(16)
list base node for "free_nodes" list(16)
其中很多值還需要深入的研究 但是我們發現在38-41位元組就包含了SPACE_ID。
那麼我們就找到了
Space id in fsp header 131225,but in the page header 65
中的 fsp header 來自哪裡 ,他來自FSP HEADER及ibd 檔案的第一個塊的第38-41位元組
而page header 65,來自每個塊的第34-37位元組。
既然如此我們可以進行測試模擬這種現象,我們手動修改這4個位元組。使用我自己寫的工具,由於LINUX下沒找到合適工具乾脆自己寫了兩個。
bctool和bcview
bctool 用於修改
bcview 用於檢視
主要測試方式
1、修改FSP HEADER的38-41位元組檢視MYSQL INNODB 報錯,然後修改回去後是否能夠順利啟動
2、修改第一個塊file space header的34-37位元組 檢視看MYSQL INNODB 報錯,然後修改回去後是否能夠順利啟動
3、修改任意一個塊的file space header的34-37位元組 檢視看MYSQL INNODB 報錯,然後修改回去後是否能夠順利啟動
我們依然使用test資料庫下的c1 表其innodb 資料檔案為c1.ibd
一、修改FSP HEADER的38-41位元組檢視MYSQL INNODB 報錯,然後修改回去後是否能夠順利啟動
透過bcview檢視塊的34-37位元組
[root@hadoop1 test]# bcview c1.ibd 16 34 4|more
******************************************************************
This Tool Is Uesed For Find The Data In Binary format(Hexadecimal)
Usage:./bcview file blocksize offset cnt-bytes!
file: Is Your File Will To Find Data!
blocksize: Is N kb Block.Eg: 8 Is 8 Kb Blocksize(Oracle)!
Eg: 16 Is 16 Kb Blocksize(Innodb)!
offset:Is Every Block Offset Your Want Start!
cnt-bytes:Is After Offset,How Bytes Your Want Gets!
Edtor QQ:22389860!
Used gcc version 4.1.2 20080704 (Red Hat 4.1.2-46)
******************************************************************
----Current file size is :10.000000 Mb
----Current use set blockszie is 16 Kb
current block:00000000--Offset:00034--cnt bytes:04--data is:00000048
current block:00000001--Offset:00034--cnt bytes:04--data is:00000048
current block:00000002--Offset:00034--cnt bytes:04--data is:00000048
current block:00000003--Offset:00034--cnt bytes:04--data is:00000048
current block:00000004--Offset:00034--cnt bytes:04--data is:00000048
current block:00000005--Offset:00034--cnt bytes:04--data is:00000048
current block:00000006--Offset:00034--cnt bytes:04--data is:00000048
current block:00000007--Offset:00034--cnt bytes:04--data is:00000048
current block:00000008--Offset:00034--cnt bytes:04--data is:00000048
current block:00000009--Offset:00034--cnt bytes:04--data is:00000048
current block:00000010--Offset:00034--cnt bytes:04--data is:00000048
.......
當然後面還有很多塊,但是這裡bcview c1.ibd 16 34 4 就是16KB大小34位元組開始,一共4個位元組輸出。
我們發現全是00000048,因為每個space_id在page header 都會記錄,
那麼他的space id 就是0X48 10進位制就是72,我們在MYSQL中驗證一下:
mysql> select * from INNODB_SYS_TABLESPACES where space=72;
+-------+---------+------+-------------+----------------------+-----------+---------------+
| SPACE | NAME | FLAG | FILE_FORMAT | ROW_FORMAT | PAGE_SIZE | ZIP_PAGE_SIZE |
+-------+---------+------+-------------+----------------------+-----------+---------------+
| 72 | test/c1 | 0 | Antelope | Compact or Redundant | 16384 | 0 |
+-------+---------+------+-------------+----------------------+-----------+---------------+
1 row in set (0.01 sec)
可以看到沒有問題。
那麼接下我們來看38到41位元組,為了更好的說明我使用 mysqlblock c1.ibd -d|more的d選項檢視詳細塊資訊
並且使用bcview c1.ibd 16 38 4|more
current block:00000000--Offset:00038--cnt bytes:04--data is:00000048
current block:00000001--Offset:00038--cnt bytes:04--data is:00000000
current block:00000002--Offset:00038--cnt bytes:04--data is:ffffffff
current block:00000003--Offset:00038--cnt bytes:04--data is:000601c8
current block:00000004--Offset:00038--cnt bytes:04--data is:00343b26
current block:00000005--Offset:00038--cnt bytes:04--data is:00663b26
current block:00000006--Offset:00038--cnt bytes:04--data is:00663b26
current block:00000007--Offset:00038--cnt bytes:04--data is:00663b26
current block:00000008--Offset:00038--cnt bytes:04--data is:00663b26
current block:00000009--Offset:00038--cnt bytes:04--data is:00663b26
current block:00000010--Offset:00038--cnt bytes:04--data is:00663b26
current block:00000011--Offset:00038--cnt bytes:04--data is:00663b26
current block:00000012--Offset:00038--cnt bytes:04--data is:00663b26
current block:00000013--Offset:00038--cnt bytes:04--data is:00663b26
current read blocks is : 0 --This Block is file space header blocks!
current read blocks is : 1 --This Block is insert buffer bitmap blocks!
current read blocks is : 2 --This Block is index node blocks!
current read blocks is : 3 --This Block is data blocks(Tree leaf node)!
current read blocks is : 4 --This Block is data blocks(Tree leaf node)!
current read blocks is : 5 --This Block is data blocks(Tree leaf node)!
current read blocks is : 6 --This Block is data blocks(Tree leaf node)!
current read blocks is : 7 --This Block is data blocks(Tree leaf node)!
current read blocks is : 8 --This Block is data blocks(Tree leaf node)!
current read blocks is : 9 --This Block is data blocks(Tree leaf node)!
current read blocks is : 10 --This Block is data blocks(Tree leaf node)!
current read blocks is : 11 --This Block is data blocks(Tree leaf node)!
current read blocks is : 12 --This Block is data blocks(Tree leaf node)!
current read blocks is : 13 --This Block is data blocks(Tree leaf node)!
current read blocks is : 14 --This Block is data blocks(Tree leaf node)!
現在我們清楚的看到了38-41這4個位元組只有fsp_header塊是00000048就是space_id
其他型別的塊並不是。
接下來我們使用bctool進行修改FSP HEADER的38-41位元組。還是關閉資料庫後進行更改
為了安全首先備份一下
[root@hadoop1 test]# cp c1.ibd c1.ibdbak
然後:
[root@hadoop1 test]# bctool c1.ibd 0 38 000000ee
******************************************************************
This tool is uesed to check data ues binary format,no Big-Endian
or Little-Endian diff,this tool is base one byte on byte to change
!block is 16k.if want change other block eg:8k! please set blocks
0 and offset blocks*8192+offset!
usage:./bctool yfile blocks offset yourdata(XX)!
Warings:backup file frist!!!!!!!!!
Editor QQ:22389860
Ues gcc version 4.1.2 20080704 (Red Hat 4.1.2-46)
******************************************************************
0-0-0-ee
再次檢視:
bcview c1.ibd 16 38 4|more
current block:00000000--Offset:00038--cnt bytes:04--data is:000000ee
current block:00000001--Offset:00038--cnt bytes:04--data is:00000000
current block:00000002--Offset:00038--cnt bytes:04--data is:ffffffff
current block:00000003--Offset:00038--cnt bytes:04--data is:000601c8
已經被我更改為ee了
然後啟動MYSQL,雖然資料庫起來了但是
mysql> select count(*) from c1;
ERROR 2013 (HY000): Lost connection to MySQL server during query
資料庫立即當機
[root@hadoop1 test]# service mysqldefault start
Starting MySQL..The server quit without updating PID file (/mysql/data/hadoop1.pid).[FAILED]
再次啟動已經無用,檢視日誌:
2015-12-26 01:05:38 5074 [ERROR] InnoDB: Space id in fsp header 238,but in the page header 72
2015-12-26 01:05:38 5074 [ERROR] InnoDB: checksum mismatch in tablespace ./test/c1.ibd (table test/c1)
2015-12-26 01:05:38 5074 [Note] InnoDB: Page size:1024 Pages to analyze:64
2015-12-26 01:05:38 5074 [Note] InnoDB: Page size: 1024, Possible space_id count:0
2015-12-26 01:05:38 5074 [Note] InnoDB: Page size:2048 Pages to analyze:64
2015-12-26 01:05:38 5074 [Note] InnoDB: Page size: 2048, Possible space_id count:0
2015-12-26 01:05:38 5074 [Note] InnoDB: Page size:4096 Pages to analyze:64
2015-12-26 01:05:38 5074 [Note] InnoDB: Page size: 4096, Possible space_id count:0
2015-12-26 01:05:38 5074 [Note] InnoDB: Page size:8192 Pages to analyze:64
2015-12-26 01:05:38 5074 [Note] InnoDB: Page size: 8192, Possible space_id count:0
2015-12-26 01:05:38 5074 [Note] InnoDB: Page size:16384 Pages to analyze:64
.....
我們發現錯誤重現238 換算為16進位制就是我們修改的0XEE.
這種情況也許innodb_force_recovery > 0 有用,但是我沒有試驗。
接著我來將fsp header 的38-41位元組改回0X48,然後啟動。
[root@hadoop1 test]# bctool c1.ibd 0 38 00000048
再次檢視
[root@hadoop1 test]# bcview c1.ibd 16 38 4|more
current block:00000000--Offset:00038--cnt bytes:04--data is:00000048
啟動:
[root@hadoop1 test]# service mysqldefault start
Starting MySQL...[ OK ]
啟動完成。
mysql> select count(*) from c1;
+----------+
| count(*) |
+----------+
| 8192 |
+----------+
1 row in set (0.01 sec)
查詢沒有問題。
二、修改第一個塊file space header的34-37位元組 檢視看MYSQL INNODB 報錯,然後修改回去後是否能夠順利啟動
再次關閉資料,
使用bcview檢視
[root@hadoop1 test]# bcview c1.ibd 16 34 4|more
current block:00000000--Offset:00034--cnt bytes:04--data is:00000048
修改:
[root@hadoop1 test]# bctool c1.ibd 0 34 00000099
檢視
[root@hadoop1 test]# bcview c1.ibd 16 34 4|more
current block:00000000--Offset:00034--cnt bytes:04--data is:00000099
啟動資料庫,檢視資料
mysql> select count(*) from c1;
ERROR 2013 (HY000): Lost connection to MySQL server during query
檢視日誌:
2015-12-26 01:17:46 6122 [ERROR] InnoDB: Space id in fsp header 72,but in the page header 153
這裡的153就是0X99對比剛才的
2015-12-26 01:05:38 5074 [ERROR] InnoDB: Space id in fsp header 238,but in the page header 72
可以從日誌中看出這次是fsp header正常,file header 錯誤。
那麼我們同樣修改回來:
[root@hadoop1 test]# bctool c1.ibd 0 34 00000048
檢視
current block:00000000--Offset:00034--cnt bytes:04--data is:00000048
已經修改回來,接著啟動
mysql> select count(*) from c1;
+----------+
| count(*) |
+----------+
| 8192 |
+----------+
1 row in set (0.01 sec)
沒有問題可以查詢
三、修改任意一個塊的file space header的34-37位元組 檢視看MYSQL INNODB 報錯,然後修改回去後是否能夠順利啟動
既然每個資料塊的file header都包含了space id,那麼我們隨意更改一個塊的
current read blocks is : 0 --This Block is file space header blocks!
current read blocks is : 1 --This Block is insert buffer bitmap blocks!
current read blocks is : 2 --This Block is index node blocks!
current read blocks is : 3 --This Block is data blocks(Tree leaf node)!
current read blocks is : 4 --This Block is data blocks(Tree leaf node)!
current read blocks is : 5 --This Block is data blocks(Tree leaf node)!
這裡就選擇5號塊(0開始實際是第6個),這個塊為資料塊。
具體過程不再給出,給出命令
[root@hadoop1 test]# bctool c1.ibd 5 34 00000088
[root@hadoop1 test]# bcview c1.ibd 16 34 4|more
current block:00000005--Offset:00034--cnt bytes:04--data is:00000088
檢視資料沒有問題,但是日誌有報錯
2015-12-26 01:25:58 403be940 InnoDB: Error: space id and page n:o stored in the page
InnoDB: read in are 136:5, should be 72:5!
可以看到innodb 說 5號塊的space id是136 就是0X88,應該是72,雖然資料還能跑,這個錯誤到底
影響多大未知但是我們知道原因,修改回去
關閉資料庫:
[root@hadoop1 test]# bctool c1.ibd 0 34 00000048
[root@hadoop1 test]# bcview c1.ibd 16 34 4|more
current block:00000005--Offset:00034--cnt bytes:04--data is:00000048
錯誤消失
總結:
1、我們可以知道什麼是space id,space id 就是表空間的唯一標識
2、我們可以知道什麼是FSP HEADER BLOCK 及每個space 檔案第一個塊,
而FSP HEADER 存放在每一個SPACE檔案的第一個塊的38-150位元組,實際這個塊還會存放XDS資訊就是EXTENTS的資訊這裡不
再介紹
3、我們可以知道訪問表的時候如果第一個塊的FIL HEADER的34-37位元組的SPCAE_ID和FSP HEADER的38-41位元組對應不上資料庫會
立即當機。
報錯:
2015-12-26 01:05:38 5074 [ERROR] InnoDB: Space id in fsp header 238,but in the page header 72
4、我們還知道了如果不是第一個塊的FIL HEADER 34-37位元組 space id出現問題,日誌只會報錯,但是不影響使用
報錯:
2015-12-26 01:25:58 403be940 InnoDB: Error: space id and page n:o stored in the page
InnoDB: read in are 136:5, should be 72:5!
5、為了完成這個實驗,我使用了3個工具,均為自己寫的,如果沒有這3個工具這個實驗無法完成,或者很困難
---mysqlblock :用於檢視資料檔案中塊的型別
***************************************************
USEAGE: mysqlblock datafile -t/-d
This small tool used in study and test database,not
uesd on online database!
This tool is used to find how many blocks and types
in specified datafile,Exp:how many undo block in d
ata file!
QQ:22389860
***************************************************
-t Only Total blocks types in ibdata!
-d Blocks types detail in ibdata!
***************************************************
USEAGE: mysqlblock datafile -t/-d
---bcview:用於檢視塊的固定位元組輸出
******************************************************************
This Tool Is Uesed For Find The Data In Binary format(Hexadecimal)
Usage:./bcview file blocksize offset cnt-bytes!
file: Is Your File Will To Find Data!
blocksize: Is N kb Block.Eg: 8 Is 8 Kb Blocksize(Oracle)!
Eg: 16 Is 16 Kb Blocksize(Innodb)!
offset:Is Every Block Offset Your Want Start!
cnt-bytes:Is After Offset,How Bytes Your Want Gets!
Edtor QQ:22389860!
Used gcc version 4.1.2 20080704 (Red Hat 4.1.2-46)
******************************************************************
usage:./bcview file blocksize offset cnt-bytes!
---bctool:用於修改某個塊的某個位元組的資料(現支援16K)
******************************************************************
This tool is uesed to check data ues binary format,no Big-Endian
or Little-Endian diff,this tool is base one byte on byte to change
!block is 16k.if want change other block eg:8k! please set blocks
0 and offset blocks*8192+offset!
usage:./bctool yfile blocks offset yourdata(XX)!
Warings:backup file frist!!!!!!!!!
Editor QQ:22389860
Ues gcc version 4.1.2 20080704 (Red Hat 4.1.2-46)
******************************************************************
usage:./bctool file block offset yourdata(XX)!
當然bctool和bcview 可以修改和檢視任何檔案,不光是INNODB BLOCK。
本三個工具均上傳到了百度雲盤
LINUX下使用,注意給予執行許可權
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/7728585/viewspace-2059798/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- [ERROR]Space id in fsp header but in the page header一列ErrorHeader
- 錯誤訊息sales area is not assigned for the header productHeader
- 關於MYSQL INNODB index page header學習和實驗總結MySqlIndexHeader
- StreamCorruptedException: invalid stream headerExceptionHeader
- InnoDB: Error: space id and page n:o stored in the page?Error
- datafilecopy header validation failure problemHeaderAI
- jQuery :headerjQueryHeader
- HTTP headerHTTPHeader
- 【maven】Maven報錯 zip END header not foundMavenHeader
- Maven專案報錯invalid LOC header (bad signature)MavenHeader
- 如何處理錯誤訊息Please install the Linux kernel header filesLinuxHeader
- Header V3 DSA signature: NOKEY, key ID e8562897 rpm HeaderHeader
- 20161110Bitmapped File Space Header恢復APPHeader
- Checkpoint log:invalid bitmap page錯誤修復
- http設定headerHTTPHeader
- HTML <header> 標籤HTMLHeader
- HTTP Header 詳解HTTPHeader
- HTTP header介紹HTTPHeader
- Oracle ASM Disk HeaderOracleASMHeader
- 新建分支 header區Header
- 從XMLHttpRequest請求響應裡getResponseHeader(header)報錯:Refused to get unsafe header "**" 問題解決XMLHTTPHeader
- oracle10g 資料檔案頭data file header(file header)OracleHeader
- Django出現DisallowedHost at / Invalid HTTP_HOST headerDjangoHTTPHeader
- MAVEN提示invalid LOC header (bad signature)MavenHeader
- header的安全配置指南Header
- ASM DISK HEADER CORRUPTION & REPAIRASMHeaderAI
- alter system dump datafile headerHeader
- X$BH與Buffer HeaderHeader
- PE教程4: Optional HeaderHeader
- The Ultimate (DLL) Header File (轉)Header
- row header format (157)HeaderORM
- Nginx的client_header_buffer_size和large_client_header_buffers學習NginxclientHeader
- invalid stream header: EFBFBDEF 問題解決Header
- HTTP header 欄位解釋HTTPHeader
- proxy_set _header Host $host;Header
- Refused to set unsafe header "cookie"HeaderCookie
- http header中cache設定HTTPHeader
- nginx配置proxy_set_headerNginxHeader