这片文章主要是对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存储引擎内部完成!
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段,可以在开始时候申请较少的表空间,节省磁盘的开销。