zoukankan      html  css  js  c++  java
  • 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

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

  • 相关阅读:
    2020软件工程作业01
    2020软件工程—06—个人作业
    团队二次作业
    软件工程作业05
    软件工程作业00--问题清单
    软件工程作业04二期
    2020软件工程作业04
    oracle11安装过程中常出现的问题和解决办法
    2020软件工程作业03
    2020软件工程作业02
  • 原文地址:https://www.cnblogs.com/xuanzhi201111/p/4090213.html
Copyright © 2011-2022 走看看