谈谈传说中的redo log是什么?有啥用?
白日梦感觉作为研发同学的你可能真的没必要了解摸清楚关于redo log的这些机制。专注于写SQL完全能hold住日常的工作。
但是呢 感觉最好还是要了解一下 因为一般面试官都知道redo log是咋回事 其次是大家茶前饭后唠嗑时也能多少能插几句嘴。
继续我们的MySQL专题。首先回顾一下前面白日梦同你分享过的知识点。
前面我们一起学习了MySQL undo log相关的知识点 看下面这张脑图
磁盘上的数据文件叫表空间文件 表空间有挺多的 比如系统表空间、undo log 表空间、你也可以让create出来的每张table都有自己单独的表空间。总之MySQL会将表空间数据页通过磁盘IO加载进缓存页中。
SQL执行器会执行你发送给MySQL的SQL语句 MySQL为了提高的性能 对于增、删、改这种操作都是在内存中完成的 所谓的内存就是上图中BufferPool。比如上图中的SQL执行器执行了一条update xxx where id 1语句 然后这个id 1数据行所在的数据页就会被你修改成脏数据页。
此外MySQL还有专门的后台线程等其他机制负责将脏数据页刷新同步回磁盘。
你可以结合上图然后想一下 万一脏页还没来得及刷新到磁盘中 MySQL就挂了 怎么办呢
对于业务代码来说 方才执行的事务是OK的 甚至前端都接受到了请求成功的响应。那结果修改的数据没同步回磁盘 MySQL宕机了会不会导致真实数据和逻辑上的数据不一致呢
其实不会的
MySQL使用redo log解决了这个问题 redo故名思义 重做。
当发生事务 增、删、改 时会导致缓存页变成脏页 于此同时MySQL会将事务涉及到的 对 XXX表空间中的XXX数据页XXX偏移量的地方做了XXX更新。
所以MySQL意外宕机重启也没关系。只要在重启时解析redo log中的事务然后重放一遍。将Buffer Pool中的缓存页重做成脏页。后续再在合适的时机将该脏页刷入磁盘即可。
于是对于业务方来说 everything is ok
redo log侧重于重做 redo log中记录的是物理层面的数据页、偏移量。应对的问题是 MySQL异常宕机后 如何将没来得及提交的事物数据重做出来。
而后面文章中和大家分享的bin log中记录了你对XXX表条件为XXX处的数据作了什么修改 这是些都是逻辑上的概念。
首先你得知道 redo并不是一条条直接写入磁盘中去的
在MySQL的设定中 redolog是按块 一块一块的写入到磁盘中去的。
你可以类比一下数据是按页为单位来组织的 就更容易理解为啥redo log 要按照block来组织redo。
本质上就是两个字 优化
log block长成下面这这样 分成Header、Body、Trailer三部分 总共512字节。而且是覆盖写入。
我粗略解读一下这幅脑图。
首先既然MySQL会写redo log 说明你的sql会对缓存页造成修改 也就意味着会走MySQL设定的事物那一套机制。既然是MySQL事物 大概率就是一组增、删、改。如果每个增、删、改都会有一个对应的redo log的话 那也就是说你的事物会产生好多redolog。这些redo会先被持续不断的写入到log block中 同一个事物产生的redo log会被标记为一个redo log group。
了解redo log block之后 白日梦还要跟你介绍一下 redo log buffer。
这个redo log buffer 中会划分出多个rodo log block。redo log buffer 占用一块连续的内存空间 默认大小16MB。且MySQL允许我们通过参数innodb_log_buffer_size动态的调整它。增大它的大小可以让MySQL处理大事物是不必写入磁盘。进而提升写IO性能。
引入rodo log buffer之后 就可以勾勒出这样一副脑图。
如图 产生的redo log 先写入redo log block。然后redo log block其实就在redo log buffer 中。
看到这里不知道你有没有想到这样一个问题 redo log buffer再怎么神奇毕竟也是仅仅在内存中 此时万一MySQL宕机了怎么办 redolog-buffer中的数据丢失了怎么办 毕竟没有写到磁盘上 MySQL重启后100%没办法将其恢复出来。
其实你并不用担心这种情况
因为在MySQL的设定中 当你要Commit事务时 redolog才会持久化进磁盘 既然你没有commit 碰巧MySQL又宕机了。那让MySQL正常重启就好了啊 反正你没有commit MySQL也也没有必要帮你恢复什么。
那 redo log buffer 何时写入磁盘呢
事物提交时把它对应的那些redo log写入到磁盘中去 这个动作可由相关参数控制 下文会说 当redo log buffer 使用量达到了参数innndb_log_buffer_size的一半时 会触发落盘。会有一个后台线程 每隔1秒就会将redo log block刷新到磁盘文件中去。MySQL关闭时也会将其落盘。承接上面描述的场景 事务提交时 率先将redo log持久化进磁盘。
那你如何控制MySQL 让MySQL在Commit事务时率先将redo log持久化呢
MySQL提供了参数innodb_flush_log_at_trx_commit
该参数有几个选项 0、1、2
想要保证ACID四大特性推荐设置为1 表示当你commit时 MySQL必须将rodolog-buffer中的数据刷新进磁盘中。确保只要commit是成功的 磁盘上就得有对应的rodolog日志。这也是最安全的情况。设置为0 每秒写一次日志并将其刷新到磁盘。
设置为2 表示当你commit时 将redolog-buffer中的数据刷新进OS Cache中 然后依托于操作系统每秒刷新一次的机制将数据同步到磁盘中 也存在丢失的风险。
如果启用了二进制日志记录 请设置 sync_binlog 1。
这也是大家常说的双1设置。前者保证redolog的不丢失、后者保证了binlog的不丢失。
关于sync_binlog参数 计划在第X、X、篇文章中分享binlog知识点的时候会再提及 欢迎关注
redo log group说的是 由N个大小相同的redo log组成一个redo log group。N的值默认为2。
你可以像下面这样查看你的MySQL的redo log group情况。
默认单个redo log文件的大小是48MB。你也可以通过上图中的innndb_log_files_size修改它。
日志文件的总大小 innodb_log_file_size* innodb_log_files_in_group 不能超过略小于512GB的最大值。
例如 一对255 GB的日志文件已达到限制 但没有超过该限制。
同样你可以像下面这样查看磁盘上的 redo log 文件。它们的大小和上图中的innodb_log_file_size相同。
innodb将log buffer中的redo log block刷新到上图中的logfile中时 以追加的方式循环写入。也就是首先在ib_logfile0的尾部追加 写满后再写ib_logfile1。当ib_logfile1写满时 情况一部分ib_logfile0接着追加写。
redo log file的大小对innodb性能影响非常大。通常来说要设置的足够大 大到可以让MySQL支持1小时线上高峰流量的接入而不切换。但是设置的过大 数据恢复的时间比较长。设置过小导致循环切换redo log file。
能聊聊 日志刷盘规则之 check point 和 LSN机制吗
参考
https://dev.mysql.com/doc/refman/5.7/en/innodb-redo-log.html
https://dev.mysql.com/doc/refman/5.7/en/replication-solutions-unexpected-replica-halt.html
https://dev.mysql.com/doc/refman/5.7/en/innodb-init-startup-configuration.html
https://dev.mysql.com/doc/refman/5.7/en/innodb-parameters.html#sysvar_innodb_flush_log_at_trx_commit
https://dev.mysql.com/doc/refman/5.7/en/innodb-init-startup-configuration.html
日志:Redo Log 和 Undo Log 本篇文章主要介绍 Redo Log 和 Undo Log: 1. 利用 Redo Log 和 Undo Log 实现本地事务的原子性、持久性 2. Redo Log 的写回策略 3. Redo Log Buffer 的刷盘时机
庖丁解InnoDB之REDO LOG 磁盘数据库为了在保证数据库的原子性(A, Atomic) 和持久性(D, Durability)的同时,还能以灵活的刷盘策略来充分利用磁盘顺序写的性能,会记录REDO和UNDO日志,即ARIES方法。本文将重点介绍REDO LOG的作用,记录的内容,组织结构,写入方式等内容,希望读者能够更全面准确的理解REDO LOG在InnoDB中的位置。本文基于MySQL 8.0代码。
你是不是 redo log 和 binlog 傻傻分不清楚? 阿粉这么贴心,肯定给你讲清楚了~ 在 MySQL 中,特别是存储引擎使用的是 InnoDB 时,那肯定绕不过去两个概念:redo log (重做日志) 和 binlog (二进制日志) 简单点儿说:redo log 是 InnoDB 存储引擎层方面的日志,所以如果你使用的存储引擎不是 InnoDB 的话,那就根本谈不上 redo log
相关文章
- Reading assembly binding log files (Fusion Log)
- (转)主从同步遇到 Got fatal error 1236 from master when reading data from binary log: 'Could not find first log...
- JavaScript - console.log 输出文字加样式(炫酷图案输出)
- 趣味 console.log
- vue报错如log,如果其他项目运行没问题,很有可能是代码错误 加externals报错
- ERROR 1872 (HY000): Slave failed to initialize relay log info structure from the repository
- 《HTML5 Canvas开发详解》——1.6 用Console.log调试
- ROS报错:IOError: [Errno 13] Permission denied: '/home/zn/.ros/log/robotiq2FGripper.log'
- git log 退出之后 log不保留在屏幕上(mac)
- iOS 设备屏幕上实时打印 Log 的小工具
- [Oracle工程师手记]如何获得 RMAN 的 debug log
- [Oracle 工程师手记] 如何构造数据库的 log on trigger
- mysql的binlog和slow_log慢日志
- python 的log功能