InnoDB逻辑存储结构

  从InnoDB存储引擎的逻辑存储结构看,所有数据都被逻辑地存放在一个空间中,称之为表空间(tablespace)。表空间又由段(segment)、区(extent)、页(page)组成。页在一些文档中有时也称为(block),InnoDB存储引擎的逻辑存储结构大致如图:

                      

   表空间可以看做是InnoDB存储引擎逻辑结构的最高层,所有的数据都存放在表空间中。默认情况下InnoDB存储引擎有一个共享表空间ibdata1,即所有数据都存放在这个表空间内。如果用户启动了innodb_file_per_table,则每个表内的数据可以单独放到一个表空间内,但要注意的是每张表的表空间内存放的只是数据、索引和插入缓存Bitmap页,而其他类的数据,如回滚(undo)信息插入缓存索引页系统事务信息二次写缓存(Double write buffer)等还是存放在原来的共享表空间内。

    现在想说明一个问题的就是,即使设置了innodb_file_per_table为ON了,共享表空间还是会不断地增加其大小,以下做个实验来验证下:

mysql> show global variables like 'innodb_file_per_table'; 
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| innodb_file_per_table | ON    |
+-----------------------+-------+
1 row in set (0.00 sec)

查看共享表空间idbata1目前的大小:

mysql> system du -sh /data/mysql-5.5/ibdata1
26M     /data/mysql-5.5/ibdata1

关掉默认的自动提交:

mysql> show variables like '%autocommit%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit    | ON    |
+---------------+-------+
1 row in set (0.01 sec)

mysql> set autocommit = 0;
Query OK, 0 rows affected (0.05 sec)

mysql> show variables like '%autocommit%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit    | OFF   |
+---------------+-------+
1 row in set (0.00 sec)

下面创建一个表,并向表里插入20万条数据:

mysql> create table test(id int(2),name char(80))engine=innodb;
Query OK, 0 rows affected (0.05 sec)
mysql> delimiter //
mysql> create procedure load3(count int unsigned)
    -> begin
    -> declare s int unsigned default 1;
    -> declare c char(80) default repeat('a',80);
    -> start transaction;
    -> while s <= count do
    -> insert into test select s,c;
    -> set s = s+1;
    -> end while;
    -> end;
    -> //
mysql> call load3(200000)//
Query OK, 1 row affected (6.36 sec)

再查看ibdate1表空间大小,发现已经增大了:

mysql> system du -sh /data/mysql-5.5/ibdata1
35M     /data/mysql-5.5/ibdata1

上面插入数据的函数,我没有commit的操作,意味着事务还没提交,下面做回滚操作再查看ibdate1大小:

mysql> rollback//
Query OK, 0 rows affected (1.00 sec)

mysql> system du -sh /data/mysql-5.5/ibdata1
35M     /data/mysql-5.5/ibdata1

可以看到ibdata1表空间并没有变回之前的26M,虽然InnoDB存储引擎不会回收这些空间,但是会自动判断这些undo信息是否需要,如果不需要,则会将这些空间标记为可用空间,供下次undo使用,master thead每10秒执行一次full purge操作,很有可能的一种情况是:用户再次执行上述的创建数据语句后,会发现ibdata1不会再增大了,那就是这个原因,看以下图

mysql> call load3(100000);
    -> //
Query OK, 1 row affected (2.56 sec)

mysql> commit//
Query OK, 0 rows affected (0.05 sec)

mysql> system du -sh /data/mysql-5.5/ibdata1
35M     /data/mysql-5.5/ibdata1


希望写此博客,可以让大家对InnoDB逻辑存储结构有了更深的了解,想了解更多内容,请参考《MySQL技术内幕  InnoDB存储引擎  第2版》

 

作者:陆炫志

出处:xuanzhi的博客 http://www.cnblogs.com/xuanzhi201111

您的支持是对博主最大的鼓励,感谢您的认真阅读。本文版权归作者所有,欢迎转载,但请保留该声明。

posted @ 2014-11-27 11:51  GoogSQL  阅读(1275)  评论(0编辑  收藏  举报