这片文章主要是对innodb表空间的一些说明:

innodb中表空间可以分为以下几种:

  • 系统表空间
  • 独立表空间
  • undo表空间
  • 临时表空间(temporary tablespace)
  • 通用表空间(general tablespace)

 系统表空间与独立表空间

表空间可以看做是innodb存储引擎结构的最高层,所有的数据都存放在表空间中。在默认情况下innodb存储引擎有一个共享表空间ibdata1,即所有的数据都存放在这个表空间中。如果启用了innodb_file_per_table参数,则每张表的数据可以单独放到一个表空间。

  • 系统表空间(即共享表空间)

系统表空间可以通过参数innodb_data_file_path对其进行配置,默认配置如下:

mysql> show variables like "innodb_data_file_path";
+-----------------------+------------------------+
| Variable_name         | Value                  |
+-----------------------+------------------------+
| innodb_data_file_path | ibdata1:12M:autoextend |
+-----------------------+------------------------+
1 row in set (0.00 sec)

#ibdata1:指定默认文件名
#12M:指定默认文件大小
#autoextend: 表示文件是自增的,当超过12M时,会自动增加大小,没有指定表空间的位置,默认是在数据库目录下面的。
采用了默认的表空间,但实际大小如下

  mysql> system ls -lh /data/mysql/ibdata1;
  -rw-rw---- 1 mysql mysql 76M Oct 16 15:30 /data/mysql/ibdata1

可以通过指定多个文件组成一个表空间,同时设置文件的属性。

#注意添加文件时的格式写法
innodb_data_file_path=ibdata1:100M:autoestend;/data/ibdata2:200M

这里使用了两个文件来组成表空间,若这两个文件位于不同的磁盘上,磁盘的负载可能被平均,因此可以提高数据库的整体性能。

  • 独立表空间

如果启用了innodb_file_per_table的参数,则每张表内的数据可以单独放到一个表空间中(tabname.ibd的形式命名)。

需要注意的是: 每张表的表空间内存放的只是数据,索引,和插入缓冲Bitmap页,其他类型的数据,如回滚信息,插入缓冲索引页,系统事务信息,二次写缓冲等,还是存在在原来的系统表空间中。

即便启用了独立表空间,共享表空间还是会不断增大。

即便是执行了rollback撤回了事务,共享表空间的大小也不会变小,虽然innodb存储引擎不会回收这些表空间,但是innodb存储引擎 会自动判断这些undo信息是否还需要,如果不需要则会将这些空间标记为可用空间,供下次使用。

undo表空间

【待续】

临时表空间

临时表空间,即在创建表时使用temporary参数,来创建临时表;

具体创建临时表在这片博客写过https://www.cnblogs.com/wxzhe/p/9767991.html

通用表空间

 通用表空间是在MySQL5.7中添加的一个新功能。

可以数据库中指定的某几张表的数据写到同一个表空间,类似于系统的共享存储空间。

创建通用表空间的语法如下:

CREATE TABLESPACE tablespace_name
    ADD DATAFILE 'file_name'
    [FILE_BLOCK_SIZE = value]    #指定通用表空间文件块的大小
        [ENGINE [=] engine_name] #指定存储引擎 
#创建通用表空间
mysql> create tablespace ts add datafile "ts1.ibd" engine=innodb;
Query OK, 0 rows affected (0.04 sec)
#datafile若是使用绝对路径,则可以指定datadir之外的目录,默认是在datadir指定的目录
#创建的表空间已经存在
mysql> system ls -lh /data/mysql/ts1.ibd
-rw-r----- 1 mysql mysql 64K Oct 23 06:42 /data/mysql/ts1.ibd

绑定表空间,把创建的表的表空间指定到上面创建的通用表空间。

#把多张表指向一个表空间
mysql> create table test1(id int, name varchar(20)) tablespace=ts;
Query OK, 0 rows affected (0.02 sec)

mysql> create table test2(id int, name varchar(20)) tablespace=ts;
Query OK, 0 rows affected (0.02 sec)

mysql> create table test3(id int, name varchar(20)) tablespace=ts;
Query OK, 0 rows affected (0.01 sec)

#使用show create table 语句可以发现上面三张表的表空间均为ts。 #删除表空间 mysql
> create tablespace ts2 add datafile "ts2.ibd" engine=innodb; Query OK, 0 rows affected (0.01 sec) mysql> drop tablespace ts2; Query OK, 0 rows affected (0.02 sec)

当表空间的file_block_size大小与innodb_file_size大小不一致的时候,表空间可以使用压缩方式,后面会讲到。

innodb存储引擎结构

从存储引擎的逻辑存储结构上看,所有数据都被逻辑地存放在一个空间中,称之为表空间。表空间又由段,区,页(也可以称为块)组成。

INNODB存储引擎表空间

 

段,区均为逻辑概念,并且段管理由innodb存储引擎内部完成!

B+树的特征,叶子节点存储数据。上面图中表空间包含了数据段(leaf node segment),索引段(Non-leaf node segment),回滚段(rollback segment)!

 

是由连续的页(Page)组成的空间,在任何情况下每个区大小都为1MB,为了保证页的连续性,InnoDB存储引擎每次从磁盘一次申请4-5个区。默认情况下,InnoDB存储引擎的页大小为16KB,即一个区中有64个连续的页。 (1MB/16KB=64)

InnoDB1.0.x版本开始引入压缩页,每个页的大小可以通过参数KEY_BLOCK_SIZE设置为2K、4K、8K,因此每个区对应的页尾512、256、128.

默认页的大小是16KB,但是InnpDB1.2.x版本新增了参数innodb_page_size,通过该参数可以将默认页的大小设置为4K、8K,但是页中的数据不是压缩的。(注意这两个参数的区别)

在启用了innodb_file_per_table后,创建的表默认大小是96KB。但区的大小是1M,因此表的大小至少应该为1M?
原因:在每个段开始的时候,先用32个页大小的碎片页来存放数据,在使用完这些页之后才是64个连续页的申请。这样做的目的是,对于一些小表,或者undo段,可以在开始时候申请较少的表空间,节省磁盘的开销。
innodb创建表时的技巧

相关文章: