重做日志 redo log
重做日志是用来保证事务的持久性的,它体现了 MySQL 中的 WAL 技术,即在持久化数据之前,先保证 redo log 已经写到了磁盘上。重做日志是基于磁盘的数据结构,记录了在某个数据页上做了什么修改,是 InnoDB 引擎特有的日志,在事务提交前重做日志被写入磁盘,当系统崩溃时,就可以根据 redo log 来恢复数据。
WAL:Write-Ahead Logging,先写日志,再写磁盘。当执行一条更新语句时,InnoDB 首先会将更新信息写入重做日志中,然后将重做日志放到重做日志缓冲区(redo log buffer),之后按照一定的频率将 redo log buffer 写入重做日志文件中。
文章图片
重做日志对应的物理文件
默认情况下,在数据库的 data 目录下有两个文件
ib_logfile1
和 ib_logfile2
。重做日志文件以循环写入的方式进行:文章图片
重做日志缓冲区刷新到磁盘
【MySQL 中的重做日志和二进制日志】按照下面三种情况刷新:
对于第二种情况,触发写磁盘的条件由 innodb_flush_log_at_trx_commit 参数控制,表示当提交事务时,处理 redo log 的方式。
- Master Thread 每一秒将重做日志缓冲刷新到重做日志文件;
- 每个事务提交时会将重做日志缓冲刷新到重做日志文件;
- 当重做日志缓冲剩余空间小于 1 / 2 时刷新到重做日志文件;
innodb_flush_log_at_trx_commit
的有效值为 0, 1, 2;默认为 1:- 0:提交事务时并不刷新缓冲区,而是等待主线程每秒的刷新;
- 1:提交事务时将重做日志缓冲区刷新到磁盘;符合事务的 ACID 特性;
- 2:提交事务时将重做日志缓冲区先刷新到文件系统的缓存中,之后每秒将缓存刷新到磁盘中,也就是说重做日志异步写到磁盘;
文章图片
二进制日志 binlog 前面提到的 redo log 是 InnoDB 引擎特有的日志,而 Server 层也有自己的日志,即二进制日志 binlog,binlog 记录了数据库增删改操作的信息,以二进制的格式保存在磁盘中。当提交事务时,一次性将事务中的所有 SQL 语句写入 binlog 中。
binlog 记录的是逻辑操作,可以简单认为就是 SQL 语句,binlog 是通过追加的方式进行写入的,也就是说当 binlog 文件写到一定大小后切换到下一个,不会覆盖之前的文件。
MySQL 通过 sync_binlog 参数来控制服务层什么时候将 binlog 同步到磁盘上,
sync_binlog
的有效值为 0, 1, N,默认为 1:- 0:关闭服务层同步 binlog 到磁盘的功能,binlog 的同步依赖于操作系统的不定时同步,该设置提供了最好的性能,但如果操作系统崩溃,就会导致已提交的事务没有同步到磁盘上;
- 1:每次事务提交都会同步 binlog,该设置是最安全的,但是由于磁盘 IO 频率变高,会影响性能;
- N:每提交 N 个事务才进行一次 binlog 同步,能提高一定的性能;
- 主从复制:从库利用主库的 binlog 进行重播,实现主从同步;
- 恢复:将数据库还原到某一个时间点;
- 引擎将更新记录写入 redo log,并将 redo log 同步到磁盘上,此时事务处于
prepared
状态; - 接着执行器生成事务的 binlog,并将 binlog 写入磁盘,然后调用引擎的提交事务接口,告诉引擎提交更改,引擎就会将之前已经准备好的事务(
prepared
)改成已提交(committed
)状态;
如果事务处于 prepared 状态时,MySQL 崩溃了,会发生什么?
因为事务此时还未提交,所以根据事务的原子性,这个事务会进行回滚,之前的操作都无效。所以两阶段提交保证了日志的一致性,如果两个日志分开写入,那么就有可能产生不一致的问题。
redo log 和 binlog 的区别
- 作用不同:redo log 是 InnoDB 引擎特有的日志,用来保证事务的持久性,是事务层面的;binlog 是 MySQL 服务层实现的,所有引擎都可以使用,起到还原的作用,是数据库层面的;
- 内容不同:redo log 是物理日志,记录的是「在某个数据页上做了什么更改」;binlog 是逻辑日志,记录的是语句的原始逻辑,可以简单理解为记录的是 SQL 语句;
- 写入方式不同:redo log 是循环写入的;binlog 是追加写入,不会覆盖以前的日志;
- 恢复数据的效率不同:基于物理日志的 redo log 恢复数据的效率要比逻辑日志 binlog 高;
- MySQL中的重做日志(redo log),回滚日志(undo log),以及二进制日志(binlog)的简单总结
- MySQL系列之redo log、undo log和binlog详解
- MySQL 45讲
- Fun MySQL fact of the day: everything is two-phase
推荐阅读
- zabbix使用percona插件监控mysql数据库(十九)
- 十二使用percona zabbix mysql-plugin监控mysql数据库
- MySQL基础学习教程,30分钟快速入门mysql数据库
- 为什么MySQL数据库索引选择使用B+树()
- MySQL数据库常见操作命令
- Mysql数据库安装与简介
- MySQL数据库从入门到精通
- Linux/Windows下MySQL数据库的备份与还原(mysqldump)
- MySQL数据库进阶篇