详解MySQL 重做日志(redo log)与回滚日志(undo logo)
前言:
前面文章讲述了MySQL系统中常见的几种日志,其实还有事务相关日志redolog和undolog没有介绍。相对于其他几种日志而言,redolog和undolog是更加神秘,难以观测的。本篇文章将主要介绍这两类事务日志的作用及运维方法。
1.重做日志(redolog)
我们都知道,事务的四大特性里面有一个是持久性,具体来说就是只要事务提交成功,那么对数据库做的修改就被永久保存下来了,不可能因为任何原因再回到原来的状态。那么MySQL是如何保证一致性的呢?最简单的做法是在每次事务提交的时候,将该事务涉及修改的数据页全部刷新到磁盘中。但是这么做会有严重的性能问题,主要体现在两个方面:
- 因为Innodb是以页为单位进行磁盘交互的,而一个事务很可能只修改一个数据页里面的几个字节,这个时候将完整的数据页刷到磁盘的话,太浪费资源了。
- 一个事务可能涉及修改多个数据页,并且这些数据页在物理上并不连续,使用随机IO写入性能太差。
因此MySQL设计了redolog,具体来说就是只记录事务对数据页做了哪些修改,这样就能完美地解决性能问题了(相对而言文件更小并且是顺序IO)。
redolog包括两部分:一个是内存中的日志缓冲(redologbuffer),另一个是磁盘上的日志文件(redologfile)。MySQL每执行一条DML语句,先将记录写入redologbuffer,后续某个时间点再一次性将多个操作记录写到redologfile。
默认情况下,redolog在磁盘上由名为ib_logfile0和ib_logfile1的两个物理文件展示。redolog相关参数简单介绍如下:
- innodb_log_files_in_group:redolog文件的个数,命名方式如:ib_logfile0,iblogfile1...iblogfilen。默认2个,最大100个。
- innodb_log_file_size:单个redolog文件设置大小,默认值为48M,最大值为512G,注意最大值指的是整个redolog系列文件之和,即(innodb_log_files_in_group*innodb_log_file_size)不能大于最大值512G。
- innodb_log_group_home_dir:指定redolog文件组所在的路径,默认./,表示在数据库的数据目录下。
- innodb_log_buffer_size:redologbuffer大小,默认16M。延迟事务日志写入磁盘,把redolog放到该缓冲区,然后根据innodb_flush_log_at_trx_commit参数的设置,再把日志从buffer中flush到磁盘中。
- innodb_flush_log_at_trx_commit:控制redolog刷新到磁盘的策略,默认为1。值为1,每次commit都会把redolog从redologbuffer写入到system,并fsync刷新到磁盘文件中。值为2,每次事务提交时MySQL会把日志从redologbuffer写入到system,但只写入到filesystembuffer,由系统内部来fsync到磁盘文件。如果数据库实例crash,不会丢失redolog,但是如果服务器crash,由于filesystembuffer还来不及fsync到磁盘文件,所以会丢失这一部分的数据。值为0,表示事务提交时不进行写入redolog操作,这个操作仅在masterthread中完成,而在masterthread中每1秒进行一次重做日志的fsync操作,因此实例crash最多丢失1秒钟内的事务。
更改redolog及其buffer大小是需要重启数据库实例的,建议初始化时做好评估。可以适当加大redolog组数和大小,特别是你的数据库实例更新比较频繁的情况下。但也不推荐redolog设置过大。
2.回滚日志(undolog)
undolog主要用于保证数据的原子性,保存了事务发生之前的数据的一个版本,可以用于回滚。比如一条INSERT语句,对应一条DELETE的undolog,对于每个UPDATE语句,对应一条相反的UPDATE的undolog,这样在发生错误时,就能回滚到事务之前的数据状态。同时,undolog也是MVCC(多版本并发控制)实现的关键。
MySQL5.7版本中,undolog默认存放在共享表空间ibdata中。也可以在初始化时通过配置参数改成独立的文件,简单介绍几个undolog相关参数:
- innodb_max_undo_log_size:控制最大undotablespace文件的大小,当启动了innodb_undo_log_truncate时,undotablespace超过innodb_max_undo_log_size阀值时才会去尝试truncate。该值默认大小为1G,truncate后的大小默认为10M。
- innodb_undo_tablespaces:设置undo独立表空间个数,范围为0-128,5.7版本默认为0,0表示不开启独立undo表空间。该参数只能在最开始初始化MySQL实例的时候指定。
- innodb_undo_directory:设置undo表空间的存放目录,默认数据目录。
- innodb_undo_log_truncate:设置undo表空间是否自动截断回收。该参数生效的前提是,已设置独立表空间且独立表空间个数大于等于2个。
undolog相关参数一般很少改动。MySQL8.0默认启用了独立表空间,可能undolog表空间的大小设置更灵活些。
总结:
本篇文章主要介绍了redolog及undolog的作用和相关参数设置,文章写的比较匆忙,如有错误,可以留言指出。关于这两类日志更深层次的内容,可能笔者功力还不到,未能写到更加透彻。好了,MySQL相关日志的两篇文章已经写完了,希望各位能学到一点知识。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。