3. InnoDB 存储引擎-表结构定义文件、InnoDB存储引擎文件、表空间文件、重做日志文件
3.5 表结构定义文件
MySQL 都有一个以frm为后缀的文件,该文件记录了该表的表结构定义。
frm还用来存放视图的定义,如用户创建了一个v_a 视图,那么对应会产生一个v_a.frm 文件,用来记录视图的定义。该文件是文本文件,可用cat查看。
3.6 InnoDB存储引擎文件
InnoDB文件包括重做文件、表空间文件。
3.6.1 表空间文件
InnoDB采用将存储的数据按表空间进行存放的设计。在默认配置下,会有一个初始大小为10MB,名为ibdata1的文件。该文件就是默认的表空间文件。用户也可以通过多个文件组成一个表空间,同时制定文件的属性。
设置innodb_data_file_path参数后,所有基于innoDB 存储引擎的表的数据都会记录到该共享表空间。若设置了参数 innodb_file_per_table = ON 则用户可以将每个基于INnoDB的表产生一个独立表空间。独立表空间的命名规则为:表名.ibd.
这些单独的表空间文件仅存储该表的数据、索引和插入缓冲bitmap等信息,其余信息还是存放在默认的表空间中。
3.6.2 重做日志文件
默认情况下,在innoDB 存储引擎的数据目录下会有两个名为 ib_logfile0 和 ib_logfile1 的文件。在MySQL 官方手册中称为 InnoDB 存储引擎的日志文件,不过更准确的说是重做日志文件,他们记录了对于 InnoDB 存储引擎的事务日志。
当实例或介质失败时,重做日志文件就能派上用场了。例如,数据库由于在主机掉电导致实例失败,InnoDB会使用重做日志恢复到掉电前的时刻,以次保证数据的完整性。
每个InnoDB存储引擎至少有一个重做日志文件组,每个文件组至少有两个重做日志文件,例如默认的 ib_logfile0和 ib_logfile1。用户可自行设置更多的镜像日志组,将不同的文件组放到不同的磁盘上,提供重做日志的可用性。在日志组中,每个重做日志文件的大小一致,并以循环写入的方式运行。InnoDB会先写重做日志文件1,当达到文件的最后,会切换到重做日志文件2,再当2被写满时,会再切换到文件1.
重做日志文件的大小设置对InnoDB的性能有很大影响。一方面重做日志文件不能设置太大,如果太大,在恢复时可能需要很长时间。另一方面,设置太小,可能导致一个事务需要多次切换重做日志文件。此外,重做日志文件太小会导致频繁的发生 async Checkpoint,导致性能抖动。
重做日志有一个 capacity 变量,该值代表了最后的检查点不能超过这个阈值,如果超过这个阈值,则必须将缓冲池(InnoDB buffer pool)中的脏页列表中的部分脏数据协会磁盘,这时会导致用户线程的阻塞。
之前介绍过,写入重做日志文件的操作不是直接写,而是先写入重做日志缓冲(redo log buffer),然后按照一定的顺序写入日志文件。
上图展示了重做日志的写入过程,从重做日志缓冲往磁盘写入时,是按照 512 个字节,也就是一个扇区的大小进行写入。因为扇区是写入的最小单位,因此可以保证写入必定是成功的,因此重做日志的写入过程不需要有 doublewrite。之前提到过,在主线程中每秒会将重做日志文件缓冲写入磁盘的重做日志文件中,不论事务是否已经提交。