表结构 create table dml_file(id int,name1varchar(5),name2 char(5),primary key (id)); 表数据 mysql> select * from dml_file; +----+-------+-------+ | id | name1 | name2 | +----+-------+-------+ | 3| aaa | aaa | | 10 | ccc | ccc | +----+-------+-------+
一、表空间分析
此时表空间内容(数据页)
0000c000 ff 27 b4 28 00 00 00 03 ff ff ff ff ff ff ff ff |.‘.(............|
0000c010 00 00 00 00 0c 93 55 c7 45 bf 00 00 00 00 00 00 |......U.E.......|
0000c020 00 00 00 00 00 3a 00 02 00 ba 80 04 00 00 00 00 |.....:..........|
0000c030 00 a1 00 02 00 01 00 02 00 00 00 00 00 00 0000 |................|
0000c040 00 00 00 00 00 00 00 00 00 59 0000 00 3a 00 00 |.........Y...:..|
0000c050 00 02 00 f2 00 00 00 3a 00 00 0002 00 32 01 00 |.......:.....2..|
0000c060 02 00 1d 69 6e 66 69 6d 75 6d 00 03 00 0b 00 00 |...infimum......|
0000c070 73 75 70 72 65 6d 75 6d 05 03 00 00 00 10 00 21 |supremum.......!|
0000c080 80 00 00 03 00 00 00 02 d9 bd bb 00 0002 28 00 |..............(.|
0000c090 84 61 61 61 61 6161 20 20 05 03 00 00 00 18ff |.aaaaaa .......|
0000c0a0 cf 80 00 00 0a 00 00 00 02 d9 be bc 00 00 01 ca |................|
0000c0b0 00 84 63 63 63 63 63 63 20 20 0000 00 00 00 00 |..cccccc ......|
0000c0c0 00 00 00 00 00 00 00 00 00 00 0000 00 00 00 00 |................|
0000c0d0 00 00 00 00 00 00 00 00 00 00 0000 00 00 00 00 |................|
0000c0e0 00 00 00 00 00 00 00 00 00 00 0000 00 00 00 00 |................|
文件头信息
0000c000 行 ff 27 b4 28 表示checksum的值
0000c010行 00 00 00 00 0c 93 55 c7 表示最后被修改的日志记录位置
页头信息
0000c020 行 00 ba表示页头空信息偏移量 ,c000+ ba=c0ba, 可以看到空闲的位置就是为0000 c0ba
0000c020 行00 00 00 00 表示前两个00表示被删除记录的偏移量,后两个00表示被删除的字节数
0000c030 行00 a1 表示最后插入的位置c000+ 00a1 =c0a1 第二条记录id=10的位置,02 表示一共有两个记录
0000c060 行 1d表示第一条记录的表偏移量 0000c063+1d=0000c80 ,即第一条记录id=3
0000c070 行 03表示第一条记录varchar列有3个字符,21下一个记录的偏移量0000c080+21=c0a1 即id=10的位置
0000c080行05 表示数据为utf字符集80 00 00 03 该记录主键的数据id=3,00 00 00 02 d9 bd为修改数据的事务号
bb 00 00 02 28 00 84 表示回滚指针
0000c081行61 61 61 61 61 61表示第一条记录第二列 61 61 61( ccc )第三列 61 61 6120 20(ccc 0 0 )其中00是char所要补足字符数
0000c0a0 行cf 表示下一个记录的指针位置
二、DML语句操作的影响
insert
insert into dml_file values(5,‘bbb‘,‘bbb‘);
红色为变化值
可以看出
C000 行 8d 18 0e 94 表示checksum在变化
C010 行 00 00 00 00 0c 93 5b cc表示日志的变化,0c 93 5b cc- 0c 93 55 c7日志文件有1541个字 节新增
C020 行 00db表示空闲指针变化c000+db=c0db 空闲位置变为c0db 。8005 变化表示堆记录数变化, 记录增加了1。
C030 行 00c2表示最后插入的位置,从c0a1改变为c0c2 0005 00 00表示插入记录的方向和这个方向 的个数,00 03 记录个数变化 记录了3条记录
C070 行 42 表示id=3的下一条记录的变更,c080+42=c0c2 可以看到本身id=3指向下一条记 录id=10的指针指向了id=5的记录
C0b0 增加了新的一条记录id=5
总结:insert时,将数据顺序插入到空闲队列,然后更改其相邻记录的下一条记录指针,使之指向它,而达到插入数据。与此同时,更改相应的数据统计信息。
update
更新固定字符:
可以看到
文件头更新了checksum 和日志记录点
C080行D9 c6表示事务号改变 41 00 00 01 da 1776 回滚id改变
C090行 61 61 61 2020表示(ccc)改为 62 62 20 20(aa)可以看到ccc更新为aa时,少出的1个字符直接改为20填充字。
总结:更新事务号和回滚号,更新内容(更新引起空出来的字符直接用20代替),然后更改checksum和日志记录点。因此固定字符虽然占的空字符较多,费空间,但是更新操作步骤简单。
更新可变字符:
当更新字符数小于原来字符数
update dml_file set name1=‘bb‘ where id=3;
可以看到
文件头更新了checksum 和日志记录点
c030 行 00 80表示最后插入数据位置,改成了 c080的位置,因为字符数变化所以最后插入位置也改变了
c070 行 02表示varchar字段的字段数改为2 ,原来可变字段aaa被更新成了bb,所以只有两个字符
c080 行 rollid和事务id也改变了
c090 行 62 62 表示更新的数据(aa)
61(a)可以看出次数a没有改变,但也不会显示,因为Mysql将根据可变字段长度来读取数据,即此时只会读取前2个变量
2.当更新字符数大于原来字符数
mysql>select * from dml_file; +----+-------+-------+ | id |name1 | name2 | +----+-------+-------+ | 3 | bb | bb | | 5 | bbb | bbb | | 10 |ccc | ccc | +----+-------+-------+ update dml_file set name1=‘kkkkkkk‘ whereid=3;
可以看到
除了改变checksum和日志记录位置外
C020 行 oofe表示空闲指针位置改变指向c0fe 8006堆的数量改变,改成8006,即堆里增加了一行数据。
C030行 最后被插入的位置进行了改变,改成了c0e3
综上Update时增加了记录
C060行 80 表示第一条记录的位置,63+80=c0e3 ,即第一条记录的指针从原来id=3记录的位置直接挪到了新id=3的位置。
C090 原来id=3的记录数据没有被删除
可知,通过指针指向新记录的方式跳过原来数据,而不需再删除原来数据,减少删除开销
C0d0开始增加新数据
总结:这里可以看出对于varchar字段update更新并且字符增加时,他会增加一条新记录,然后更改链表指针(此时update做了插入并且删除工作)。
Delete
mysql> select * from dml_file; +----+-------+-------+ | id | name1 | name2 | +----+-------+-------+ | 5 | bbb | bbb | | 10 | ccc | ccc | +----+-------+-------+ delete from dml_file where id=3;
更改了checksum和日志记录点
c010 e3 表示被删除记录的偏移量 c000+e3=c0e3则为id=3d的记录位置。44表示删除的字符数。
C030 00表示最后插入的位置改成了00。 02记录行数说明现在只有2条记录
C060 5f表示第一条记录的位置5f 63+5F=c0c2,即id=5的位置
总结:可以看出通过指针直接指向id=5的记录来删除id=3的记录,而id=3的数据内容并没有被清空。因此用delete并不能减少表空间
Ce0 和C0f0行更改事务id和回滚id,更改指针方向试之不在指向id=5的记录
Truancat
truncate dml_file
0000c000 e6 e0 67 30 00 00 0003 ff ff ff ff ff ff ff ff |..g0............|
0000c010 00 00 00 00 0c 93 6ed2 45 bf 00 00 00 00 00 00 |......n.E.......|
0000c020 00 00 00 00 00 3b 0002 00 78 80 02 00 00 00 00 |.....;...x......|
0000c030 00 00 00 05 00 00 0000 00 00 00 00 00 00 00 00 |................|
0000c040 00 00 00 00 00 00 0000 00 59 00 00 00 3b 00 00 |.........Y...;..|
0000c050 00 02 00 f2 00 00 003b 00 00 00 02 00 32 01 00 |.......;.....2..|
0000c060 02 00 0d 69 6e 66 696d 75 6d 00 01 00 0b 00 00 |...infimum......|
0000c070 73 75 70 72 65 6d 756d 00 00 00 00 00 00 00 00 |supremum........|
0000c080 00 00 00 00 00 00 0000 00 00 00 00 00 00 00 00 |................|
0000c090 00 00 00 00 00 00 0000 00 00 00 00 00 00 00 00 |................|
0000c0a0 00 00 00 00 00 00 0000 00 00 00 00 00 00 00 00 |................|
0000c0b0 00 00 00 00 00 00 0000 00 00 00 00 00 00 00 00 |................|
0000c0c0 00 00 00 00 00 00 0000 00 00 00 00 00 00 00 00 |................|
0000c0d0 00 00 00 00 00 00 0000 00 00 00 00 00 00 00 00 |................|
0000c0e0 00 00 00 00 00 00 0000 00 00 00 00 00 00 00 00 |................|
0000c0f0 00 00 00 00 00 00 0000 00 00 00 00 00 00 00 00 |................|
0000c100 00 00 00 00 00 00 0000 00 00 00 00 00 00 00 00 |................|
总结:可以看出truncate后,除了表结构外,所有数据都将被清除,所以truncate使用后将释放磁盘空间
本文出自 “业精于勤而荒于嬉” 博客,请务必保留此出处http://10574662.blog.51cto.com/10564662/1716839
原文地址:http://10574662.blog.51cto.com/10564662/1716839