Myisam-存储引擎-动态格式-DELETED ROWS

在上一节中,我们简单地谈到了:
如果行被删除,那么其标志位为被置为"00".而且行的部分数据会被重新赋值.
在这一章节中,我们将详细讨论:
在动态格式的表中,如果行数据被删除了,这一行的数据将如何发生变化,以及其数据所包含的具体含义.[@more@]1.测试环境
OS : LINUX 2.6.9-42.ELsmp
DB : MYSQL 5.0.51a
ENGINE : MYISAM DEFAULT CHARSET=latin1

2. 动态格式表中被删除的记录存储
2.1 模拟数据
drop table if exists heyf ;
create table heyf (id int , name varchar(50)) type myisam DEFAULT CHARSET=latin1;
insert into heyf values
(1,'aaaaa'),(2,'bbbbb') ,(45,'ssssss') ,
(65,'dddddddd'),(23,'hhhhhhhhhhhh'),(5,'jjjjjjj');
system hexdump /opt/mysql/data/test/heyf.MYD;
------------------------------------------------
0000000 0003 040c fc00 0001 0000 6105 6161 6161
0000010 0000 0000 0003 040c fc00 0002 0000 6205
0000020 6262 6262 0000 0000 0003 030d fc00 002d
0000030 0000 7306 7373 7373 0073 0000 0003 010f
0000040 fc00 0041 0000 6408 6464 6464 6464 0064
0000050 0003 0113 fc00 0017 0000 680c 6868 6868
0000060 6868 6868 6868 0068 0003 020e fc00 0005
0000070 0000 6a07 6a6a 6a6a 6a6a 0000
------------------------------------------------
我们根据定义读出每行的数据:
===========================================================
ROW1: 03 00 0c 04 00 fc 01 00 00 00 05 61 61 61 61 61 00 00 00 00
ROW2: 03 00 0c 04 00 fc 02 00 00 00 05 62 62 62 62 62 00 00 00 00
ROW3: 03 00 0d 03 00 fc 2d 00 00 00 06 73 73 73 73 73 73 00 00 00
ROW4: 03 00 0f 01 00 fc 41 00 00 00 08 64 64 64 64 64 64 64 64 00
ROW5: 03 00 13 01 00 fc 17 00 00 00 0c 68 68 68 68 68 68 68 68 68 68 68 68 00
ROW6: 03 00 0e 02 00 fc 05 00 00 00 07 6a 6a 6a 6a 6a 6a 6a 00 00
===========================================================
根据题意,我们先删除第1,3,5行数据:
delete from heyf where id in (1,45,23) ;
system hexdump /opt/mysql/data/test/heyf.MYD;
------------------------------------------------
0000000 0000 1400 ffff ffff ffff ffff 0000 0000
0000010 0000 2800 0003 040c fc00 0002 0000 6205
0000020 6262 6262 0000 0000 0000 1400 0000 0000
0000030 0000 0000 0000 0000 0000 5000 0003 010f
0000040 fc00 0041 0000 6408 6464 6464 6464 0064
0000050 0000 1800 0000 0000 0000 2800 ffff ffff
0000060 ffff ffff 6868 0068 0003 020e fc00 0005
0000070 0000 6a07 6a6a 6a6a 6a6a 0000
------------------------------------------------

再次读出各行数据:
===========================================================
ROW1: 00 00 00 14 ff ff ff ff ff ff ff ff 00 00 00 00 00 00 00 28
ROW2: 03 00 0c 04 00 fc 02 00 00 00 05 62 62 62 62 62 00 00 00 00
ROW3: 00 00 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 50
ROW4: 03 00 0f 01 00 fc 41 00 00 00 08 64 64 64 64 64 64 64 64 00
ROW5: 00 00 00 18 00 00 00 00 00 00 00 28 ff ff ff ff ff ff ff ff 68 68 68 00
ROW6: 03 00 0e 02 00 fc 05 00 00 00 07 6a 6a 6a 6a 6a 6a 6a 00 00
===========================================================
2.2 开始分析数据
下来我们来解释一下:
当一行被删除. 那么该行数据的前20个字节将被置为含有特殊意义的数字,该行20个字节以后的内容不变.
前20位的具体含义如下: (第1行)
---------------------------------------------------------
00 : 1B, FLAG, 0X00 -> Deleted
00 00 14 : 3B, Block_len ,0X14 -> 20B
ff ff ff ff ff ff ff ff : 8B,Prev deleted row's address .
00 00 00 00 00 00 00 28 : 8B,Next deleted row's address .
---------------------------------------------------------
上面的意思是说,下一个已经被删除的行的地址是0X0000028,
核对一下,这个地址确实刚好是被删除的第三行ADDR.
我们把第3行数据也拿出来分析一下:
前20位的具体含义如下: (第3行)
---------------------------------------------------------
00 : 1B, FLAG, 0X00 -> Deleted
00 00 14 : 3B, Block_len ,0X14 -> 20B
00 00 00 00 00 00 00 00 : 8B, Prev deleted row's address .
00 00 00 00 00 00 00 50 : 8B, Next deleted row's address .
---------------------------------------------------------
这里意思是:
上一个被删除的行的地址是: 0x0000000, 就是我们的第1行ADDR
下一个被删除的行的地址是: 0x0000050, 就是我们的第5行ADDR.
我们来看第5行数据.
前20位的具体含义如下: (第5行)
---------------------------------------------------------
00 : 1B, FLAG, 0X00 -> Deleted
00 00 18 : 3B, Block_len ,0X18 -> 24B
00 00 00 00 00 00 00 28 : 8B,Prev deleted row's address .
ff ff ff ff ff ff ff ff : 8B,Next deleted row's address .
---------------------------------------------------------
这里说:
上一个被删除的行的地址是: 0x0000028, 就是我们的第3行ADDR
下一个被删除的行的地址是: 0xfffffff, 就是说文件结尾.

2.3 在删除过程中,MYISAM是如何处理碎片的
如果相邻的行被删除,MYSQL如何处理
2.3.0 首先来制造一些数据
drop table if exists heyf ;
create table heyf (id int , name varchar(50)) type myisam ;
insert into heyf values (1,'aaaaa'),(2,'bbbbb') ,(45,'ssssss') ,(65,'dddddddd'),(23,'hhhhhhhhhhhh'),(5,'jjjjjjj');
system hexdump /opt/mysql/data/test/heyf.MYD;
delete from heyf where id in (45) ;
system hexdump /opt/mysql/data/test/heyf.MYD;
------------------------------------------------
0000000 0003 040c fc00 0001 0000 6105 6161 6161
0000010 0000 0000 0003 040c fc00 0002 0000 6205
0000020 6262 6262 0000 0000 0000 1400 ffff ffff
0000030 ffff ffff ffff ffff ffff ffff 0003 010f
0000040 fc00 0041 0000 6408 6464 6464 6464 0064
0000050 0003 0113 fc00 0017 0000 680c 6868 6868
0000060 6868 6868 6868 0068 0003 020e fc00 0005
0000070 0000 6a07 6a6a 6a6a 6a6a 0000
------------------------------------------------
在这里我们删除了第3行数据:
-----------------------------------------------------
ROW3: 0000 1400 ffff ffff ffff ffff ffff ffff ffff ffff
-----------------------------------------------------
FLAG+LEN PREV_DEL_ADDRESS NEXT_DEL_ADDRESS
DELETED ROWS LIST 指针的方向:
START END

2.3.1 新删除的行在空行(已经删除的行)的后面
继续上面的测试:
delete from heyf where id in (65) ;
system hexdump /opt/mysql/data/test/heyf.MYD;
------------------------------------------------
0000000 0003 040c fc00 0001 0000 6105 6161 6161
0000010 0000 0000 0003 040c fc00 0002 0000 6205
0000020 6262 6262 0000 0000 0000 1400 ffff ffff
0000030 ffff ffff 0000 0000 0000 3c00 0000 1400
0000040 0000 0000 0000 2800 ffff ffff ffff ffff
0000050 0003 0113 fc00 0017 0000 680c 6868 6868
0000060 6868 6868 6868 0068 0003 020e fc00 0005
0000070 0000 6a07 6a6a 6a6a 6a6a 0000
------------------------------------------------
我们删除了第4行数据(在第3行后面),
现在被删除的行有: ROW3,ROW4,我们来看一下:
-----------------------------------------------------
ROW3: 0000 1400 ffff ffff ffff ffff 0000 0000 0000 3c00
ROW4: 0000 1400 0000 0000 0000 2800 ffff ffff ffff ffff
-----------------------------------------------------
FLAG+LEN PREV_DEL_ADDRESS NEXT_DEL_ADDRESS
首先ROW3的数据首先了变化,他的NEXT_DEL_ADDRESS 指向了ROW4的地址.
而ROW4的数据: 他的PREV_DEL_ADDRESS指向了ROW3的地址.NEXT_DEL_ADDRESS指向FF.
DELETED ROWS LIST 指针的方向:
START ROW4 -> END
这个我们可以把它理解成为一个双向链条.
(不相邻的行也一样处理,有兴趣的同学可以自已测一下)

2.3.2 新删除的行在空行(已经删除的行)的前面
继续上面的测试:
delete from heyf where id in (2) ;
system hexdump /opt/mysql/data/test/heyf.MYD;
------------------------------------------------
0000000 0003 040c fc00 0001 0000 6105 6161 6161
0000010 0000 0000 0000 2800 0000 0000 0000 3c00
0000020 ffff ffff ffff ffff 0000 1400 ffff ffff
0000030 ffff ffff 0000 0000 0000 3c00 0000 1400
0000040 ffff ffff ffff ffff 0000 0000 0000 1400
0000050 0003 0113 fc00 0017 0000 680c 6868 6868
0000060 6868 6868 6868 0068 0003 020e fc00 0005
0000070 0000 6a07 6a6a 6a6a 6a6a 0000
------------------------------------------------

我们又删除了第2行数据(在第3行前面),
现在被删除的行有(根据先后顺序): ROW3,ROW4,ROW2 ,我们来看一下:
-----------------------------------------------------
ROW2: 0000 2800 0000 0000 0000 3c00 ffff ffff ffff ffff
ROW3: 0000 1400 ffff ffff ffff ffff 0000 0000 0000 3c00
ROW4: 0000 1400 ffff ffff ffff ffff 0000 0000 0000 1400
-----------------------------------------------------
FLAG+LEN PREV_DEL_ADDRESS NEXT_DEL_ADDRESS
我们发现,MYISAM把ROW2的BLOCK_LEN设成了0X28 -> 40B ,也就是他认为ROW2,ROW3这两行是一个连续的可用空间.
而ROW4的PREV_DEL_ADDRESS和 NEXT_DEL_ADDRESS都发生了变化.
DELETED ROWS LIST 指针链变成了:
START "ROW2,ROW3" -> END
^ | |
|-----
这也就是说,MYISAM在DELETE的同时,会对连续的可用空间进行整理.(条件是新删除行的物理位置必须在空行的前面)
再接着删除第1行, 按上面的推测,1,2,3应该是连续的块了.
delete from heyf where id in (1) ;
system hexdump /opt/mysql/data/test/heyf.MYD;
------------------------------------------------
0000000 0000 3c00 0000 0000 0000 3c00 ffff ffff
0000010 ffff ffff 0000 2800 0000 0000 0000 3c00
0000020 0000 0000 0000 0000 0000 1400 ffff ffff
0000030 ffff ffff 0000 0000 0000 3c00 0000 1400
0000040 ffff ffff ffff ffff 0000 0000 0000 0000
0000050 0003 0113 fc00 0017 0000 680c 6868 6868
0000060 6868 6868 6868 0068 0003 020e fc00 0005
0000070 0000 6a07 6a6a 6a6a 6a6a 0000
------------------------------------------------
读出各行数据:
-----------------------------------------------------
ROW1: 0000 3c00 0000 0000 0000 3c00 ffff ffff ffff ffff
ROW2: 0000 2800 0000 0000 0000 3c00 0000 0000 0000 0000
ROW3: 0000 1400 ffff ffff ffff ffff 0000 0000 0000 3c00
ROW4: 0000 1400 ffff ffff ffff ffff 0000 0000 0000 0000
-----------------------------------------------------
我们发现ROW1的BLOCK_LEN设成了0X3C -> 60B ,也就是他认为ROW1,ROW2,ROW3这3行是一个连续的可用空间.
而ROW4的NEXT_DEL_ADDRESS也发生了变化,指向ROW1.
DELETED ROWS LIST 指针链变成了:
START "ROW1,ROW2,ROW3" -> END
* ^ * | |
* |-----****>>>****
3. 小结
3.1.行被删除后,在其原物理位置还占20B,用来标识该行被删除以及删除链的PREV_DEL_ADDRESS和NEXT_DEL_ADDRESS.
具体标识和含义如下:
FLAG:00 (1B) + BLOCK_LEN (3B) + PREV_DEL_ADDRESS(8B) + NEXT_DEL_ADDRESS(8B)
3.2.如果新删除行的物理位置后面刚好有空行(以前删除的). 那么这两个空间会被合并成一个连续的块.

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/703656/viewspace-1019041/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/703656/viewspace-1019041/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值