InnoDB通过表空间为各类存储数据,表空间在磁盘上表现为不同的表空间文件。InnoDB共有3种表空间:
一、System tablespace
System tablespace是InnoDB存储data dictionary、doublewrite buffer、change buffer和undo logs的地方。如果未启用独立表空间(innodb_file_per_table),则表和索引也会存储在系统表空间。
参数innodb_data_file_path定义了系统表空间的名字、大小、属性。如果在初始化实例时未修改此参数,则默认系统表空名称为ibdata1,大小12M,属性为自动扩展。
show variables like 'innodb_data_file_path';
1. 系统表空间扩容
正常情况下,系统表空间会自动扩展,我们无法通过修改表空间的size来改变表空间的大小。但可以通过给系统表空间增加文件的方式给系统表空间扩容。具体步骤如下:
1. 停止MySQL
mysqladmin shutdown
2. 修改innodb_data_file_path参数。将当前表空间文件修改为其实际大小,并新增一个表空间文件。(autoextend属性只能在最后一个文件上指定,之前表空间的需要移除)。
示例新增了一个ibdata2,初始大小50M,自增。
[mysqld]
#innodb_data_file_path = ibdata1:12M:autoextend
innodb_data_file_path = ibdata1:780M;ibdata2:50M:autoextend
3. 启动MySQL server.
mysqld_safe &
此时可以发现表空间扩容已经成功,新增了一个初始值为50M的表空间文件。
以上是系统表空间扩容的方式。如果要收缩系统表空间,目前唯一的方法是将所有的数据库导出,然后删除系统表空间文件和表的.ibd和.frm文件,通过重新导入的方式重建系统表空间。
二、File-per-table tablespace
File-per-table tablespace是将每张InnoDB表放入独立的表空间文件中。此特性由innodb_file_per_table控制,默认是打开的。禁用此参数则所有的表都建立在系统表空间,可能会造成系统表空间过大及访问争用。
每个独立的表空间由两个文件组成:table_name.ibd和table_name.frm。.ibd后缀的文件存放的是数据和索引,.frm后缀的文件存放的是表的元数据(定义)。启用独立表空间后会带来一系列的优点。
主要优点:
- 独立表空间在drop table或truncate table的时候,空间会还给操作系统。而system表空间中表删除时只是标注空间可用,但并不会收缩系统表空间。
- 可以使用Barracuda文件格式,此文件格式可使用dynamic和compressed row format,更好的兼容存储需求。
- 可以使用表空间导入的方式跨实例移动表,此特性在移动大表时可采用操作系统的复制移动数据,效率更高。
- 使用create table建表时,可以使用data directory子句将表存储在自定义路径。可以分散磁盘I/O压力,提升性能。
主要缺点:
- 由于每个表都是独立文件,系统打开表时需要更多的文件描述符。
- 要写的文件数量变多,大量表I/O时,fsync操作需要对每个表执行,无法合并。
- 每张表中的空闲空间只能被自己使用,一定程度上导致空间浪费。
三、Undo tablespace
Undo records是用来保存撤销近期变更的信息,用来保证数据库的回滚特性及一致性读。Undo logs默认存储在系统表空间中,但是也可以存储在独立的undo tablespace中。
Undo tablespaces的数量由参数innodb_undo_tablespaces指定,但是这个参数只能在实例初始化的时候设定,后续无法更改。在运行的实例中修改此参数会导致实例无法启动。
配置undo tablespaces:
1. 设置参数innodb_undo_directory为undo tablespaces指定目录,如果此参数未配置,则undo tablespaces的文件将存储在数据目录。
2. 设置参数innodb_rollback_segments指定回滚段数量的值(默认128,也是最大值)。由于总是有1个回滚段会分配给系统表空间,所以如果要使用独立的undo tablespaces时,必须要保证此值大于1。例如,是有2个undo tablespaces,可以将此参数设置为3。
3. 设置innodb_undo_tablespaces参数的值指定undo表空间的数量。
4.创建实例,一旦创建后,undo 表空间的数量就无法修改了。