我们知道,磁盘和内存之间的数据交换是通过数据页来实现的,而最小的数据页的大小是16KB,表空间是用来存储数据页的一个池子,下面我们来说说表空间的概念。
在Innodb存储引擎中,表空间是一个抽象的概念,它可以对应文件系统上的一个或者多个真实文件,表空间中包含多个数据页。Innodb中的表空间分为好几类,最重要的表空间概念莫过于独立表空间和系统表空间了。
独立表空间(.ibd文件)
独立表空间是Innodb中为每个表创建的单独的表空间文件,这个文件名和表名一致,后缀一般是.ibd,而表结构文件的名称一般是.frm,因此,每张表对应的文件有2个,分别是.frm和.ibd文件,其中.ibd文件中包含该表的索引和数据,这一点和MyISAM存储引擎不同,MyISAM存储引擎中,索引和数据分开,所以一个表对应有3个文件。
上面我们说到,.ibd文件中包含表的数据和索引,而.frm
文件中包含表结构,那么使用这两个文件当然可以恢复一张表,至于如何恢复,我们在之前5月23日的文章中有讲过。
在Innodb中,我们可以指定一张表的数据是保存在独立表空间还是系统表空间,这个参数是:innodb_file_per_table
如果我们设置这个参数的值为0,那么一个表将使用系统表空间来保存表的数据,如果设置为1,则使用独立表空间来存储数据。
除此之外,我们可以使用
alter table tbl_name tablespace innodb_file_per_table;
的方法来把系统表空间中的表转移到独立表空间,反之,我们可以使用:
alter table tbl_name tablespace innodb_system
的方法来将独立表空间的表转移到系统表空间。
系统表空间(ibdata1、ibdata2文件)
系统表空间是指data目录下面的ibdata1文件和ibdata2文件,文件个数可以指定,这里的表空间文件默认大小是12M,当然,我们也可以手动设置,配置的方法如下:
# InnoDB Directory Variables
innodb_data_home_dir = /data/mysql_4306/data
innodb_data_file_path = ibdata1:1000M;ibdata2:100M:autoextend
innodb_file_per_table = 1
在配置文件my.cnf里面写上以上参数,注意看,这里我写的是ibdata1是1000M,而ibdata2是100M,这样的设置是完全可行的,可以看到,在ibdata一行最后是autoextend,他的意思是这个文件是可以自动扩展的,所以一般都会比较大,往往是1G更多。还有一点需要注意,就是这个系统表空间只有一份,所有的表共用这一份数据。
关于这个系统表空间,这里有一个小坑,给大家说一下:
如果你的主库上设置的ibdata的模式是一个1000M,一个100M的话,你在搭建从库的时候,从库上需要跟主库保持一致,如果没有保持一致,则在实例启动的时候会有报错,错误日志如下:
190813 18:44:12 [Note] Plugin 'FEDERATED' is disabled.
190813 18:44:12 InnoDB: The InnoDB memory heap is disabled
190813 18:44:12 InnoDB: Mutexes and rw_locks use GCC atomic builtins
190813 18:44:12 InnoDB: Compressed tables use zlib 1.2.3
190813 18:44:12 InnoDB: Using Linux native AIO
190813 18:44:12 InnoDB: Initializing buffer pool, size = 8.0G
190813 18:44:12 InnoDB: Completed initialization of buffer pool
InnoDB: Error: auto-extending data file /data/mysql_4306/data/ibdata1 is of a different size
InnoDB: 64000 pages (rounded down to MB) than specified in the .cnf file:
InnoDB: initial 65536 pages, max 0 (relevant if non-zero) pages!
190813 18:44:12 InnoDB: Could not open or create data files.
190813 18:44:12 InnoDB: If you tried to add new data files, and it failed here,
190813 18:44:12 InnoDB: you should now edit innodb_data_file_path in my.cnf back
190813 18:44:12 InnoDB: to what it was, and remove the new ibdata files InnoDB created
190813 18:44:12 InnoDB: in this failed attempt. InnoDB only wrote those files full of
190813 18:44:12 InnoDB: zeros, but did not yet use them in any way. But be careful: do not
190813 18:44:12 InnoDB: remove old data files which contain your precious data!
190813 18:44:12 [ERROR] Plugin 'InnoDB' init function returned error.
190813 18:44:12 [ERROR] Plugin 'InnoDB' registration as a STORAGE ENGINE failed.
190813 18:44:12 [ERROR] Unknown/unsupported storage engine: INNODB
190813 18:44:12 [ERROR] Aborting
190813 18:44:12 [Note] mysqld: Shutdown complete
这个问题的解决方法是将从库的表空间配置方法和主库中的保持一致,这个问题即可解决。
其他类型的表空间
除了系统表空间和独立表空间,MySQL在逐渐更新迭代的过程中还衍生了通用表空间、临时表空间ibtmp、以及undo表空间等等,这些一般很少用到,这里我们不做过多介绍了。
时间原因,今天就到这里吧。