InnoDB存储引擎文件
表空间文件
与InnoDb存储引擎密切相关的文件包括重做日志文件和表空间文件,首先来说说我对表空间文件的理解。表空间文件是用来存储表信息和表数据的,它默认的大小是10MB,名称为ibdata1,如下面代码的第10行所示(代码可以左滑):
[root@localhost data]# ll
总用量 176208
-rw-r-----. 1 mysql mysql 56 8月 21 22:46 auto.cnf
drwxr-x---. 2 mysql mysql 4096 8月 21 22:45 backup_full
drwxr-x---. 2 mysql mysql 4096 8月 21 22:45 backup_increment
drwxr-x---. 2 mysql mysql 4096 11月 23 15:41 db
drwxr-x---. 2 mysql mysql 4096 9月 27 11:02 DBAs
drwxr-x---. 2 mysql mysql 4096 8月 21 22:45 employees
-rw-r-----. 1 mysql mysql 2710 11月 23 17:31 ib_buffer_pool
-rw-r-----. 1 mysql mysql 79691776 11月 23 17:31 ibdata1
-rw-r-----. 1 mysql mysql 50331648 11月 23 17:31 ib_logfile0
-rw-r-----. 1 mysql mysql 50331648 8月 21 22:45 ib_logfile1
drwxr-x---. 2 mysql mysql 4096 8月 21 22:45 mysql
-rw-r-----. 1 mysql mysql 1279 11月 16 20:36 mysql-bin.000021
-rw-r-----. 1 mysql mysql 438 11月 21 22:27 mysql-bin.000022
-rw-r-----. 1 mysql mysql 598 11月 23 17:31 mysql-bin.000023
-rw-r-----. 1 mysql mysql 57 11月 23 09:48 mysql-bin.index
drwxr-x---. 2 mysql mysql 4096 8月 21 22:45 performance_schema
drwxr-x---. 2 mysql mysql 4096 8月 21 22:45 query_rewrite
drwxr-x---. 2 mysql mysql 12288 8月 21 22:45 sys
-rw-r-----. 1 mysql mysql 21 8月 21 22:45 xtrabackup_binlog_pos_innodb
-rw-r-----. 1 mysql mysql 606 8月 21 22:45 xtrabackup_info
用户可以通过innodb_data_file_path对其进行设置,格式如下:
mysql> show variables like 'innodb_data_file_path';
+-----------------------+------------------------+
| Variable_name | Value |
+-----------------------+------------------------+
| innodb_data_file_path | ibdata1:12M:autoextend |
+-----------------------+------------------------+
row in set (. sec)
当然,也可以在配置文件中对这个数值进行修改,例如下面的方法:
[mysqld]
innodb_data_file_path=/db/ibdata1:M;/dr2/db/ibdata2:M:autoextend
上面配置文件中的写法/db/ibdata1和/dr2/db/ibdata2两个文件用来组成表空间,我们可以将这两个文件位于不同的磁盘上,这样磁盘的负载可能被平均,从而提高数据库的性能。最后面的autoextend表示了这个文件可以自动增长。
设置innodb_data_file_path这个参数之后,所有InnoDB引擎表的数据都会记录到该共享表空间中,如果设置了参数innodb_file_per_table,则用户可以将每个基于InnoDB存储引擎的表产生一个独立的表空间,InnoDB默认的命名方法为:表名称.ibd,像下面这样
[root@tk-dba-mysql-194 data]# cd testing/
[root@tk-dba-mysql-194 testing]# ll
total
-rw-r----- mysql mysql Oct admin_authors.frm
-rw-r----- mysql mysql Nov : admin_authors.ibd
-rw-r----- mysql mysql Oct admin_groups.frm
-rw-r----- mysql mysql Sep : admin_groups.ibd
-rw-r----- mysql mysql Oct : admin_logs.frm
-rw-r----- mysql mysql Dec : admin_logs.ibd
-rw-r----- mysql mysql Oct admin_modules.frm
-rw-r----- mysql mysql Nov : admin_modules.ibd
-rw-r----- mysql mysql Oct admin_users.frm
-rw-r----- mysql mysql Nov : admin_users.ibd
查看它的InnoDB_per_table状态:
mysql ::>>show variables like 'innodb_file_per_table';
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| innodb_file_per_table | ON |
+-----------------------+-------+
row in set (0.01 sec)
我们可以发现它是开启的,需要注意的是,这些单独的表空间文件仅仅存储该表的数据、索引和插入缓冲bitmap等信息,其余信息还是存放在默认的表空间当中的,InnoDB存储引擎对于文件的存储方式可以用下面的图来表示:
重做日志文件
在默认情况下,InnoDB存储引擎的根目录下面会有两个名为ib_logfile0和ib_logfile1的文件,这两个文件被称之为重做日志文件,也叫redo log file。它们的作用是当实例意外失败时,如数据库所在的主机断电导致实例失败,这个时候,重做日志文件就会派上用场,InnoDB存储引擎会利用这个文件来恢复到断电之前的状态,从而保证数据的完整性。
重做日志一般是通过组的方式存在的,也就是说,一般有至少2个重做日志文件,为了安全起见,有时候会将重做日志放在不同的磁盘上,从而提高日志的高可用性能。日志组的文件大小一致,通常会循环使用,其中一个写满的时候,会自动切换到另外一个,使用方式大概如图:
重做日志文件的大小一般使用innodb_log_file_size来查看,重做日志的文件组的数量一般通过innodb_log_files_in_group来查看,而重做日志的目录通过innodb_log_group_home_dir参数查看,这里我们使用如下方法来显示这3个参数:
mysql> show variables like 'innodb%log%';
+----------------------------------+------------+
| Variable_name | Value |
+----------------------------------+------------+
| innodb_api_enable_binlog | OFF |
| innodb_flush_log_at_timeout | |
| innodb_flush_log_at_trx_commit | |
| innodb_locks_unsafe_for_binlog | OFF |
| innodb_log_buffer_size | |
| innodb_log_checksums | ON |
| innodb_log_compressed_pages | ON |
| innodb_log_file_size | |
| innodb_log_files_in_group | |
| innodb_log_group_home_dir | ./ |
| innodb_log_write_ahead_size | |
| innodb_max_undo_log_size | |
| innodb_online_alter_log_max_size | |
| innodb_undo_log_truncate | OFF |
| innodb_undo_logs | |
+----------------------------------+------------+
rows in set (0.00 sec)
同样是记录事务日志,那么重做日志redo log和二进制日志binlog有什么区别?
其实它们的区别主要包含下面几个:
1.binlog会记录所有与MySQL有关的日志记录,包含InnoDB,MyIsam等其他存储引擎的记录,而redo log只记录InnoDB存储引擎的事务日志。
2.记录的内容不同,binlog记录的是有关事务的具体操作内容,而redo log记录的是关于每个page的更改情况
3.写入时间不同,binlog文件在事务提交之前进行提交,只写磁盘一次,而redo log在事务进行的过程中,不断的被写入。
需要注意的是,写入redo log的操作不是直接写,而是先要通过一个重做日志缓冲redo log buffer,然后按照一定的条件顺序的写入日志文件,这些条件在后面会讲到。其写入过程可以形象的描述如下图:
从重做日志缓冲往磁盘写入时,是按照512字节的大小进行写入的,因为512是磁盘扇区写入的最小单位,必定是可以写入成功的,因此在redo log写入的过程中,不需要有doublewrite。
现在我们来说说前面讲到的重做日志缓冲的写盘条件,主要有以下几条:
1.主线程每秒会将重做日志缓冲写入磁盘的重做日志文件中,它不考虑事务是否提交;
2.在执行事务提交的过程中,通过innodb_flush_log_at_trx_commit参数控制是否将重做日志缓冲中的数据写入到重做日志中,这个参数的有效值是0,1,2,0表示不写入,1和2表示写入,1和2的区别是1是在执行commit时将重做日志缓冲同步写入磁盘,2表示异步写入,即写到文件系统的缓存中,不一定落盘。这个值一般设定为1,从而保证事务ACID中的持久性
3.当重做日志缓冲池剩余空间小于1/2时,重做日志缓冲会刷新到重做日志文件。