Myisam-儲存引擎-靜態格式-DELETED ROWS

Steven1981發表於2009-03-19
在上一節的介紹中,我們對DELETED ROWS留下了疑問:
疑問1: 行被刪除後,該行有6個位元組被重置了,在這裡為什麼只置6個位元組? 為什麼需要置這6個位元組,光有header不能識別嗎?

帶著疑問,進入我們這一章節.[@more@]
--MYISAM 靜態格式資料儲存結構-DELETED ROWS
1. 介紹

在上一節的介紹中,我們對DELETED ROWS留下了疑問:
疑問1: 行被刪除後,該行有6個位元組被重置了,在這裡為什麼只置6個位元組? 為什麼需要置這6個位元組,光有header不能識別嗎?

帶著疑問,進入我們這一章節.

2. 深入研究靜態格式中被刪除的行
2.1 搭建環境
2.1.1 系統,DB

OS : Linux 2.6.9-42.ELsmp
DB : MYSQL 5.0.51a
ENGIRE: MYISAM DEFAULT CHARSET=latin1
2.1.2 建立測試資料
use test;
drop table if exists heyf ;
create table heyf (id int , name char(8)) type myisam DEFAULT CHARSET=latin1;
insert into heyf values (1,'aaa'),(2,'bbb'),(3,'ccc'),(4,'ddd'),(5,'eee') ;
system hexdump /opt/mysql/data/test/heyf.MYD;
-------------------------------------------------
0000000 01f9 0000 6100 6161 2020 2020 f920 0002
0000010 0000 6262 2062 2020 2020 03f9 0000 6300
0000020 6363 2020 2020 f920 0004 0000 6464 2064
0000030 2020 2020 05f9 0000 6500 6565 2020 2020
0000040 0020
-------------------------------------------------
2.2 開始分析
把上面的行分解一下:
-------------------------------------------------
ROW1: f9 01 00 00 00 61 61 61 20 20 20 20 20
ROW2: f9 02 00 00 00 62 62 62 20 20 20 20 20
ROW3: f9 03 00 00 00 63 63 63 20 20 20 20 20
ROW4: f9 04 00 00 00 64 64 64 20 20 20 20 20
ROW5: f9 05 00 00 00 65 65 65 20 20 20 20 20
-------------------------------------------------
2.2.1 我們來刪除第3行資料:
delete from heyf where id=3 ;
system hexdump /opt/mysql/data/test/heyf.MYD;
-------------------------------------------------
0000000 01f9 0000 6100 6161 2020 2020 f920 0002
0000010 0000 6262 2062 2020 2020 ff00 ffff ffff
0000020 63ff 2020 2020 f920 0004 0000 6464 2064
0000030 2020 2020 05f9 0000 6500 6565 2020 2020
0000040 0020
-------------------------------------------------
我們看到ROW3變成了:
-------------------------------------------------
ROW3: 00 ff ff ff ff ff ff 63 20 20 20 20 20
-------------------------------------------------

2.2.2 我們來再刪除第4行資料:
delete from heyf where id=4 ;
system hexdump /opt/mysql/data/test/heyf.MYD;
-------------------------------------------------
0000000 01f9 0000 6100 6161 2020 2020 f920 0002
0000010 0000 6262 2062 2020 2020 ff00 ffff ffff
0000020 63ff 2020 2020 0020 0000 0000 0200 2064
0000030 2020 2020 05f9 0000 6500 6565 2020 2020
0000040 0020
-------------------------------------------------
我們看到ROW3,ROW4變成了:
-------------------------------------------------
ROW3: 00 ff ff ff ff ff ff 63 20 20 20 20 20
ROW4: 00 00 00 00 00 00 02 64 20 20 20 20 20
-------------------------------------------------

2.2.3 我們來再刪除第5行資料:
delete from heyf where id=5 ;
system hexdump /opt/mysql/data/test/heyf.MYD;
-------------------------------------------------
0000000 01f9 0000 6100 6161 2020 2020 f920 0002
0000010 0000 6262 2062 2020 2020 ff00 ffff ffff
0000020 63ff 2020 2020 0020 0000 0000 0200 2064
0000030 2020 2020 0000 0000 0000 6503 2020 2020
0000040 0020
-------------------------------------------------
我們看到ROW3,ROW4,ROW5變成了:
-------------------------------------------------
ROW3: 00 ff ff ff ff ff ff 63 20 20 20 20 20
ROW4: 00 00 00 00 00 00 02 64 20 20 20 20 20
ROW5: 00 00 00 00 00 00 03 65 20 20 20 20 20
-------------------------------------------------

2.2.4 我們來再刪除第1行資料:
delete from heyf where id=1 ;
system hexdump /opt/mysql/data/test/heyf.MYD;
-------------------------------------------------
0000000 0000 0000 0000 6104 2020 2020 f920 0002
0000010 0000 6262 2062 2020 2020 ff00 ffff ffff
0000020 63ff 2020 2020 0020 0000 0000 0200 2064
0000030 2020 2020 0000 0000 0000 6503 2020 2020
0000040 0020
-------------------------------------------------
我們看到ROW1,ROW3,ROW4,ROW5變成了:
-------------------------------------------------
ROW1: 00 00 00 00 00 00 04 61 20 20 20 20 20
ROW3: 00 ff ff ff ff ff ff 63 20 20 20 20 20
ROW4: 00 00 00 00 00 00 02 64 20 20 20 20 20
ROW5: 00 00 00 00 00 00 03 65 20 20 20 20 20
-------------------------------------------------

2.3 小結

到了這裡,我們基本上能看明白MYISAM在DELETE的時候幹了什麼.
在這裡小結一下:
MYISAM在刪除行的時候:
1)將該行的第1個位元組置為"00"
2)將該行的第2~7個位元組置為上一個被刪除行的"行序列號",
(MYSQL靜態格式中,每一個行都會有一個編號,從000000開始編號)
如果是第一條被刪除的行,那麼這6位會被置為"FF FF FF FF FF FF".
大家可以試著看一下上面的資料

也許你在這裡會問:
"行序列號" 需要6個位元組,那麼如果每行長度(標誌位除外)<6B的時候,MYISAM如何來儲存的呢?
為此也進一步做了一個測試,我們會發現,當我們的行長度<6B的時候,MYISAM一律按每行6B進行分配空間.
來看測試:
use test;
drop table if exists heyf ;
create table heyf (id TINYINT , name char(2)) type myisam DEFAULT CHARSET=latin1;
insert into heyf values (1,'aa'),(2,'bb'),(3,'cc'),(4,'dd'),(5,'ee') ;
system hexdump /opt/mysql/data/test/heyf.MYD;
------------------------------------------------
0000000 01f9 6161 0000 f900 6202 0062 0000 03f9
0000010 6363 0000 f900 6404 0064 0000 05f9 6565
0000020 0000 0000
-------------------------------------------------
讀出資料:
------------------------------
ROW1: f9 01 61 61 00 00 00
ROW2: f9 02 62 62 00 00 00
... ...
------------------------------
我們看到,每行分配1B(FLAG)+6B(DATA). 沒有資料的部分填上00.
這樣做完全是為了滿足DELETE的標誌位

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/703656/viewspace-1019042/,如需轉載,請註明出處,否則將追究法律責任。

相關文章