本文作者粗略总结了三种MySQL日志的一些特点和作用,帮助大家了解MySQL中的那些东西,以及它们背后的原理。MySQL中有七种日志文件,分别是:重做日志(redolog)回滚日志(undolog)二进制日志(binlog)错误日志(errorlog)慢查询日志(slowquerylog)通用查询日志(generallog)Relay日志(中继日志)其中,重做日志和回滚日志与事务操作密切相关,二进制日志也与事务操作相关。这三类日志对于理解MySQL中的事务操作具有重要意义。下面简单总结一下这三个相关的日志。重做日志(redolog)的作用是保证事务的持久性,防止故障时将脏页写入磁盘。当MySQL服务重启时,根据redolog进行redo,从而实现事务持久化的特性。内容物理格式的日志记录物理数据页的修改信息,其重做日志依次写入重做日志文件的物理文件中。当事务启动后产生redolog时,redolog并不是随着事务的commit写入,而是在事务执行过程中写入redolog文件。何时释放当对应事务的脏页写入磁盘时,redolog的使命就完成了,redolog占用的空间可以被重用(覆盖)。对应的物理文件默认情况下,对应的物理文件位于数据库数据目录下的ib_logfile1&ib_logfile2中。innodb_log_group_home_dir指定日志文件组所在的路径。默认是./,表示在数据库的数据目录下。innodb_log_files_in_group指定重做日志文件组中的文件个数,默认为2个。关于大小和文件个数,由以下两个参数配置:innodb_log_file_size重做日志文件的大小。innodb_mirrored_log_groups指定日志镜像文件组的个数,默认为1。还有很重要的一点,redolog是什么时候写入磁盘的?前面说过,磁盘是在事情开始后一步步写的。之所以说重做日志是在事务开始后逐渐写入重做日志文件,不一定要等到事务提交后才写入重做日志缓存。原因是redolog有一个缓冲区Innodb_log_buffer,Innodb_log_buffer默认大小为8M(这里设置16M),Innodb存储引擎先将redolog写入innodb_log_buffer。然后通过以下三种方式将Innodblogbuffer的日志刷新到磁盘:MasterThread每秒执行一次刷新Innodb_log_buffer到redolog文件。当每个事务提交时,重做日志被刷新到重做日志文件。当重做日志缓存变得少于一半空闲时,重做日志缓存被刷新到重做日志文件。由此可见,redolog写入磁盘的方式不止一种,尤其是第一种方式,Innodb_log_buffer写入redolog文件是MasterThread线程的一个定时任务。因此,重做日志写入磁盘并不一定是随着事务的提交而写入重做日志文件,而是随着事务的开始逐渐开始。也引用《MySQL技术内幕 Innodb 存储引擎》(第37页)上的原话:即使一个事务还没有提交,Innodb存储引擎仍然会每秒刷新redologcache到redolog文件。这一点一定要知道,因为它可以很好的说明提交大事务的时间也很短。回滚日志(undolog)功能保存了事务发生前数据的一个版本,可以用于回滚,也可以提供多版本并发控制(MVCC)下的读,即非锁读。content逻辑格式的日志,在执行undo时,只是逻辑上将数据恢复到事务前的状态,而不是对物理页进行操作,这一点与redo日志不同。当当前版本在事务开始前产生时,会产生undolog,undo也会产生redo,保证undolog的可靠性。何时释放事务提交后,undolog并不能立即删除,而是放入待清理的链表中,purge线程判断其他事务是否在undo中使用表中上一个事务的版本信息segment来决定是否可以清理undolog的日志空间。对应的物理文件在MySQL5.6之前,undo表空间位于共享表空间的回滚段。共享表空间的默认名称是ibdata,它位于数据文件目录中。MySQL5.6之后,undo表空间可以作为一个独立的文件进行配置,但是需要提前在配置文件中进行配置。数据库初始化后生效,undolog文件个数不可更改。如果在初始化数据库之前没有进行相关配置,则无法配置为独立的表空间。MySQL5.7之后独立undo表空间的配置参数如下:innodb_undo_directory=/data/undospace/–undo独立表空间的存储目录innodb_undo_logs=128–回滚段为128KBinnodb_undo_tablespaces=4–指定4个undo日志文件,如果undo共享tablespaceused不仅仅存储undo信息,共享表空间默认位于MySQL数据目录下,其属性由参数innodb_data_file_path配置。其他撤销是事务开始前保存的修改数据的一个版本。当undolog产生的时候,也会伴随着类似保护事务持久化机制的redolog的产生。默认情况下,撤消文件保存在共享表空间中,即ibdatafile文件中。当数据库中发生一些大的事务性操作时,会产生大量的undo信息,这些信息都存储在共享表空间中。因此,共享表空间可能会变得非常大。默认情况下,即undolog使用共享表空间时,“扩容”的共享表空间不会也不能自动收缩。因此,MySQL5.7以后的“独立undo表空间”的配置是非常有必要的。二进制日志(binlog)用于复制。主从复制时,从库使用主库上的binlog进行replay,实现主从同步;它用于数据库的时间点恢复。内容逻辑格式的日志可以简单的看成是执行的事务中的SQL语句,但并不像SQL语句那么简单。包括执行的SQL语句的逆向信息(增、删、改),也就是说delete对应delete本身及其逆向insert;update对应update执行前后的版本信息;insert对应的是delete和insert本身的信息。使用MySQLbinlog解析binlog后,有些事情就会明朗起来。所以类似Oracle的闪回功能可以基于binlog来实现,但实际上是依赖于binlog中的日志记录。当一次事务提交发生时,事务中的SQL语句(一个事物可能对应多条SQL语句)一次性以一定的格式记录在binlog中。这里与redolog的明显区别在于,redolog不一定在事务提交时刷入磁盘,而是在事务开始后逐渐写入磁盘。因此,对于事务的提交,即使是比较大的事务,提交(commit)也是非常快的,但是当开启了bin_log后,比较大的事务的提交可能会变慢。这是因为binlog是在事务提交的时候写一次的,可以通过测试验证。什么时候释放binlog默认保留时间由参数expire_logs_days配置,也就是说对于不活跃的日志文件,在生成时间超过expire_logs_days配置的天数后会被自动删除。对应物理文件配置文件的路径为log_bin_basename。binlog日志文件根据指定的大小。当日志文件达到指定的最大大小时,它将被滚动并生成一个新的日志文件。对于每一个binlog日志文件,通过一个统一的索引文件来组织。其他二进制日志的功能之一就是恢复数据库,这和redolog很像,很多人混淆了,但是两者有本质区别:功能不同:redolog是为了保证事务的持久化,这处于事务级别;binlog作为恢复功能,是数据库级别的(当然也可以精确到事务级别)。虽然两者都有恢复的意思,但对数据的保护程度不同。内容不同:redolog是物理日志,是数据页被修改后的物理记录,而binlog是逻辑日志,可以简单的看成是SQL语句。另外,这两个日志产生的时间、可以释放的时间、可以释放的清理机制是完全不同的。恢复数据的效率取决于物理日志的redolog。恢复数据的效率高于语句逻辑日志的binlog。对于事务提交,redolog和binlog的写入顺序必须严格一致,才能保证主从复制时的主从一致性(当然也包括使用binlog进行时间点恢复的情况)。MySQL通过两阶段提交过程完成事务的一致性,即redolog和binlog的一致性。理论上先写redolog,再写binlog。真的完成了。综上所述,在MySQL中,以上三种日志,每一种都可以细化到足以写一章。这里粗略总结一下三种日志的一些特点和作用,以帮助理解MySQL里面的东西和背后的东西。原则。
