注册 登录
  • 进入"运维那点事"后,希望您第一件事就是阅读“关于”栏目,仔细阅读“关于Ctrl+c问题”,不希望误会!

MySQL InnoDB表空间文件

MySQL InnoDB 彭东稳 7100次浏览 已收录 0个评论

表结构定义文件

因为MySQL插件式存储引擎的体系结构的关系,MySQL数据的存储是根据表进行的,每个表都会有与之对应的文件。但不论表采用何种存储引擎,MySQL都有一个似.frm为后缀名的文件,这个文件记录了该表的表结构定义。同时frm还用来存放视图的定义,如果创建一个view视图那么就会产生一个view.frm的文件。

表空间文件

InnoDB采用将存储的数据按表空间进行存放的设计,默认配置下MySQL5.5会有一个初始大小为10MB,名为ibdata1的文件;在MySQL5.6该大小为12MB。该文件就是默认的表空间文件,可以通过参数innodb_data_file_path对其进行设置,可以选择通过多个文件组成一个表空间。格式如下:

这里将/data1/ibdata1/data2/ibdata2两个文件用来组成表空间。若这两个文件位于不同的磁盘上,磁盘的负载可能被平均,因此可以提高数据库的整体性能。同时两个文件的文件名后都跟了属性,表示文件ibdata1的大小为2000MB,文件ibdata2的大小为2000MB,如果用完了这2000MB,该文件可以自动增长(autoextend

其实这种将所有的数据都存放在一个表空间文件中管理起来非常的不方便而且还不支持高级功能。所以建议每个表存储为一个独立的表空间,其实现方式为,使用服务器变量innodb_file_per_table = 1即可(MySQL5.6默认已经开启每表表文件),其独立表空间的命名规则是“表名.ibd”。需要注意的是,这些独立的表空间文件仅仅存储该表的数据、索引和插入缓冲BITMAP等信息,其余信息还是存放在默认的表空间中。

还有一个db.opt的文件是用来保存当前这个数据库的默认字符集和排序规则,如果不指定MySQL的默认是字符集是latin1

重做日志文件(redo

默认情况下,在InnoDB存储引擎的数据目录下会有两个名为ib_logfile0ib_logfile1的文件。官方称为InnoDB存储引擎的事务日志文件,不过也可以称为重做日志文件(redo log file)。重做日志文件对于InnoDB存储引擎至关重要,它们记录了对于InnoDB存储引擎的事务日志。当实例或介质失败时,重做日志文件就能派上用场。例如,数据库由于所在主机掉电导致实例失败,InnoDB存储引擎会使用重做日志文件恢复到掉电前的时刻,以此来保证数据的完整性。

每个InnoDB存储引擎至少有1个重做日志文件组,每个文件组下至少有2个重做日志文件,如默认的ib_logfile0ib_logfile1。为了得到更高的可靠性,用户可以设置多个镜像日志组(mirrored log groups),将不同的文件组放在不同的磁盘上,以此提高重做日志的高可用性。在日志组中每个重做日志文件的大小一致,并以循环写入的方式运行。InnoDB存储引擎先写重做日志文件1,当达到文件的最后时,会切换至重做日志文件2,再当重做日志文件2也被写满时,会再切换到重做日志文件1中。

对于重做日志来说,也同样有着许多能够影响重做日志的参数。下面一一介绍一下这些参数各自的作用。

InnoDB重做日志变量

变量含义解释:

innodb_log_file_size={108576 .. 4294967295}

#指定每个重做日志文件的大小,默认值是5MB。在InnoDB1.2x版本之前文件总的大小不得大于等于4GB,而1.2.x版本将该限制扩大为了512GB。重做日志的大小设置对于InnoDB存储引擎的性能有着非常大的影响。较为明智的取值范围是从1MB到缓存池体积的1/n,其中n表示日志组中日志文件的个数。日志文件越大,在缓存池中需要执行的检查点刷写操作就越少,这意味着所需的I/O操作也就越少,然而这也会导致较慢的故障恢复速度。(MySQL5.5使用的是InnoDB1.1MySQL5.6使用的是InnoDB1.2

innodb_log_buffer_size={262144 .. 4294967295}

#设定InnoDB用于辅助完成日志文件写操作的日志缓冲区大小,单位是字节,默认为8MB。较大的事务可以借助于更大的日志缓冲区来避免在事务完成之前将日志缓冲区的数据写入日志文件,以减少I/O操作进而提升系统性能。但默认情况下每一秒钟就会将重做日志缓冲刷新到日志文件,无论事务是否已提交。因此我们只需要保证每秒产生的事务量在这个缓冲大小之内即可。作用范围为全局级别,可用于选项文件,属非动态变量。

innodb_log_files_in_group={2 .. 100}

#设定日志组中日志文件的个数,InnoDB以循环的方式使用这些日志文件。默认值为2。作用范围为全局级别,可用于选项文件,属非动态变量。

Innodb_log_mirrored_log_groups=1

#指定了日志镜像文件组的数据,默认为1,表示只有一个日志文件组,没有镜像。若磁盘本身已经做了高可用的方案,如磁盘阵列,那么可以不用开启重做日志镜像的功能。

Innodb_log_group_home_dir=./

#设定InnoDB重做日志文件的存储目录。在缺省使用InnoDB日志相关的所有变量时,其默认会在数据目录中创建两个大小为50MB的名为ib_logfile0ib_logfile1的日志文件。作用范围为全局级别,可用于选项文件,属非动态变量

innodb_flush_log_at_timeout = 1

这个参数的意思是刷新日志的时间,每隔几秒冲洗一下日志,默认的冲洗频率为1秒。

innodb_flush_log_at_trx_commit={0|1|2}

这也是一个影响写磁盘的参数,设定InnoDB同步日志缓冲区(log buffer)数据至日志文件中的方式,以及刷写日志文件至磁盘的方式。其可接受的值中,“0”表示将日志缓冲区每秒一次地写入日志文件,并同时将日志文件刷写至磁盘中,但事务提交时不会采取任何动作;“1”是默认值,表示在有事务提交时将日志缓冲区写入日志文件,并同时将日志文件刷写至磁盘;“2”表示每事务提交或每秒一次将日志缓冲区写入日志文件,但不会同时执行日志文件的刷写操作。当然,由于操作系统进程调度的原因,每秒一次的日志写入或刷写操作并不能得到100%的保证。

完全兼容ACID的场景需要将此变量值设置为1,由于要执行每事务的日志刷写操作,其会阻止I/O调用,直到写操作完成,故其会显著降低InnoDB每秒钟可以提交的事务数。设置为“2”可获得比“1”更好的性能,而且仅在操作系统崩溃时才会丢失最后一秒钟的数据,因此数据安全性也有着不错的表现。设置为“0”则有可能会导致事务最后一秒钟的数据丢失,于是整个事务的数据安全性将无法保证,但其通常有着最好的性能。为了在最大程序上保证复制的InnoDB事务持久性和一致性,应该设置变量innodb_flush_log_at_trx_commit=1以及设置变量sync_binlog=1

然而需要注意的是,有些磁盘自身也有缓存,这可能会给事务操作带来额外的潜在风险。可以使用hdparm工具或供应商的自有工具等禁用磁盘自身的缓存。当然,高性能事务的最佳配置是把此变量的值设置为1,并且将日志文件放在有备用电池的写入缓存的RAID上。作用范围为全局,可用于选项文件,属动态变量。

innodb_support_xa={TRUE|FLASE}

事务在存储引擎内部被赋予了ACID属性,分布式(XA)事务是一种高层次的事务,它利用“准备”然后“提交”(prepare-then-commit)两段式的方式将ACID属性扩展到存储引擎外部,甚至是数据库外部。然而,“准备”阶段会导致额外的磁盘刷写操作。XA需要事务协调员,它会通知所有的参与者准备提交事务(阶段1)。当协调员从所有参与者那里收到“就绪”信息时,它会指示所有参与者进行真正的“提交”操作。

此变量正是用于定义InnoDB是否支持两段式提交的分布式事务,默认为启用。事实上,所有启用了二进制日志的并支持多个线程同时向二进制日志写入数据的MySQL服务器都需要启用分布式事务,否则,多个线程对二进制日志的写入操作可能会以与原始次序不同的方式完成,这将会在基于二进制日志的恢复操作中或者是从服务器上创建出不同原始数据的结果。因此,除了仅有一个线程可以改变数据以外的其它应用场景都不应该禁用此功能。而在仅有一个线程可以修改数据的应用中,禁用此功能是安全的并可以提升InnoDB表的性能。作用范围为全局和会话级别,可用于选项文件,属动态变量

innodb_locks_unsafe_for_binlog=OFF

设定InnnoDB是否在搜索和索引扫描中使用间隙锁(gap locking)InnoDB使用行级锁(row-level locking),通常情况下,InnoDB在搜索或扫描索引的行锁机制中使用“下一键锁定(next-key locking)”算法来锁定某索引记录及其前部的间隙(gap),以阻塞其它用户紧跟在该索引记录之前插入其它索引记录。站在这个角度来说,行级锁也叫索引记录锁(index-record lock)

默认情况下,此变量的值为OFF,意为禁止使用非安全锁,也即启用间隙锁功能。将其设定为ON表示禁止锁定索引记录前的间隙,也即禁用间隙锁,InnoDB仅使用索引记录锁(index-record lock)进行索引搜索或扫描,不过,这并不禁止InnoDB在执行外键约束检查或重复键检查时使用间隙锁。

启用innodb_locks_unsafe_for_binlog的效果类似于将MySQL的事务隔离级别设定为READ-COMMITTED,但二者并不完全等同:innodb_locks_unsafe_for_binlog是全局级别的设定且只能在服务启动时设定,而事务隔离级别可全局设定并由会话级别继承,然而会话级别也以按需在运行时对其进行调整。类似READ-COMMITTED事务隔离级别,启用innodb_locks_unsafe_for_binlog也会带来“幻影问题(phantom problem)”,但除此之外,它还能带来如下特性:

(1)UPDATEDELETE语句来说,InnoDB仅锁定需要更新或删除的行,对不能够被WHERE条件匹配的行施加的锁会在条件检查后予以释放。这可以有效地降低死锁出现的概率;

(2)执行UPDATE语句时,如果某行已经被其它语句锁定,InnoDB会启动一个“半一致性(semi-consistent)”读操作从MySQL最近一次提交版本中获得此行,并以之判定其是否能够并当前UPDATEWHERE条件所匹配。如果能够匹配,MySQL会再次对其进行锁定,而如果仍有其它锁存在,则需要先等待它们退出

innodb_online_alter_log_max_size = 134217728

指定InnoDB表在线DDL操作期间使用的临时日志文件大小的上限。有一个这样的日志文件,每个索引被创建或修改。此日志文件存储数据的插入、更新或删除表中的DDL操作期间。临时日志文件扩展时所需的innodb_sort_buffer_size值,达到指定的最大innodb_online_alter_log_max_size。如果任何临时日志文件超过大小上限,ALTER TABLE操作失败,所有未提交的并发DML操作回滚。因此,一个大值这个选项允许更多的DML到在线DDL操作期间发生,但也造成了较长时期在DDL操作结束时,表被应用的数据从日志。

innodb_log_compressed_pages = ON

这个变量在MySQL5.6.11加入的新特性,指定是否要压缩数据页然后存储在InnoDB的重做日志中。

innodb_undo_logs = 128

定义了一些UNDO日志(否则称为回滚段)进行数据修改事务产生撤销记录InnoDB使用。默认128个,每个撤销日志最多可容纳1024个事务最多。


如果您觉得本站对你有帮助,那么可以支付宝扫码捐助以帮助本站更好地发展,在此谢过。
喜欢 (2)or分享 (0)
关于作者:

您必须 登录 才能发表评论!