【innodb阅读笔记】之 表空间文件、重做日志文件
一、表空间文件
innodb 采用将存储的数据按照表空间进行存放的设计。默认情况下会初始化一个大小为10MB,名为ibdata1的文件,该文件就是默认的表空间文件,可以通过参数innodb_data_file_path进行设置,如:
# 基础设置,设置表空间文件大小为 12MB
innodb_data_file_path = ./ibdata1:12M
# 设置两个表空间文件
innodb_data_file_path = ./ibdata1:12M;./ibdata2:12M
# 设置ibdata2 自动扩容
innodb_data_file_path = ./ibdata1:12M;./ibdata2:12M:autoextend
# 设置 ibdata2 自动扩容 并指定扩容大小
innodb_data_file_path = ./ibdata1:12M;./ibdata2:12M:autoextend:max:20M
这里使用ibdata1和ibdata2两个文件来组成表空间,若这两个文件在不同磁盘,磁盘的负载可能均衡,因此提高数据库性能。
设置innodb_data_file_path后,所有的数据都会记录到表空间文件中,这会导致表空间文件过大,所以引入了innodb_file_per_table参数,当开启此参数后(默认是开启的),数据库会为每个表设置一个独立的表空间文件,命名规则为:表名.ibd,通过这样的方式,减少共享表空间的大小。
需要注意的是,独立表空间只存储该表的数据、索引和插入缓存BITMAP等信息。其他数据如:插入缓存,undo log,锁信息等都存储在共享表空间中。
mysql> show variables like 'innodb_file_per_table';
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| innodb_file_per_table | ON |
+-----------------------+-------+
1 row in set, 1 warning (0.00 sec)
二、重做日志文件
再默认情况下,Innodb存储引擎目录下会有 ib_logfile0 和 ib_logfile1 的文件,这些文件就是重做日志文件,当数据库发生错误或者系统宕机,innodb会使用重做日志来恢复数据库的数据,以此来保障数据的完整性。
每个Innodb存储引擎至少有两个重做日志,当文件1写完,切换到文件2,做到循环使用的效果。重做日志文件不能设置的太大,设置太大时,恢复的时候可能需要很长时间,另一面也不能设置的太小,太小会导致一个事务多次切换日志文件,导致频繁的async checkpoint,引起性能的抖动。
# 每个重做日志文件的大小 默认为48MB
mysql> show variables like 'innodb_log_file_size';
+----------------------+----------+
| Variable_name | Value |
+----------------------+----------+
| innodb_log_file_size | 50331648 |
+----------------------+----------+
1 row in set, 1 warning (0.00 sec)
# 一个重做日志组下面有多少个重做日志文件 默认为 2
mysql> show variables like 'innodb_log_files_in_group';
+---------------------------+-------+
| Variable_name | Value |
+---------------------------+-------+
| innodb_log_files_in_group | 2 |
+---------------------------+-------+
1 row in set, 1 warning (0.00 sec)
# 重做日志文件存放的位置默认存放在mysql数据存放位置
mysql> show variables like 'innodb_log_group_home_dir';
+---------------------------+-------+
| Variable_name | Value |
+---------------------------+-------+
| innodb_log_group_home_dir | .\ |
+---------------------------+-------+
1 row in set, 1 warning (0.00 sec)
重做日志缓存往磁盘写入时,是按照512个字节,也就是一个扇区写入的,因此保障写入必定是成功的。所以在写入过程中不需要doublewrite。
重做日志写入的时机有:
1. 主线程每秒会将重做日志写入到磁盘
2. 事务提交时,通过参数 innobd_flush_log_at_trx_commit 来控制,(默认为1)表示当事务提交的时候,将当前事务的重做日志刷新到磁盘,0 表示等待主线程的刷新,2表示将重做日志写入到文件系统中,等待文件系统将数据刷新到磁盘。
mysql> show variables like 'innodb_flush_log_at_trx_commit';
+--------------------------------+-------+
| Variable_name | Value |
+--------------------------------+-------+
| innodb_flush_log_at_trx_commit | 1 |
+--------------------------------+-------+
1 row in set, 1 warning (0.00 sec)