共计 2112 个字符,预计需要花费 6 分钟才能阅读完成。
1. 背景
MySQL 实现事务、解体复原、集群的主从复制,底层都离不开日志,所以日志是 MySQL 的精髓所在。只有理解 MySQL 日志,才算是彻底搞懂 MySQL。
明天一灯就带你深入浅出的学习 MySQL 的三大日志零碎,Redo Log(重做日志)、Undo Log(复原日志)、Bin Log(备份日志)。
2. Redo Log(重做日志)
2.1 Redo Log 的内容与作用
Redo Log 记录的是物理日志,也就是磁盘数据页的批改。
作用: 用来保障服务解体后,仍能把事务中变更的数据长久化到磁盘上。
MySQL 事务中持久性就是应用 Redo Log 实现的。
2.2 什么时候写入 Redo Log?
- 从磁盘加载数据到内存
- 在内存中批改数据
- 把新数据写到 Redo Log Buffer 中
- 把 Redo Log Buffer 中数据长久化到 Redo Log 文件中
- 把 Redo Log 文件中数据长久化到数据库磁盘中
你可能会问,为什么须要写 Redo Log Buffer 和Redo Log FIle?间接长久化到磁盘不好吗?
间接写磁盘会有产生重大的性能问题:
- InnoDB 在磁盘中存储的根本单元是页,可能本次批改只变更一页中几个字节,然而须要刷新整页的数据,就很浪费资源。
- 一个事务可能批改了多页中的数据,页之间又是不间断的,就会产生随机 IO,性能更差。
这种计划叫做 WAL(Write-Ahead Logging),预写日志,就是先写日志,再写磁盘。
2.3 Redo Log 刷盘规定
写入 Redo Log Buffer 之后,并不会立刻长久化到 Redo Log FIle,须要期待操作系统调用 fsync() 操作,才会刷到磁盘上。
具体什么时候能够把 Redo Log Buffer 刷到 Redo Log FIle 中,能够通过 innodb_flush_log_at_trx_commit 参数配置决定。
参数值 | 含意 |
---|---|
0(提早写) | 提交事务后,不会立刻刷到 OS Buffer 中,而是等一秒后刷新到 OS Buffer 并调用 fsync()写入Redo Log FIle,可能会失落一秒钟的数据。 |
1(实时写 | 每次提交事务,都会刷新到 OS Buffer 并调用 fsync()写到Redo Log FIle,性能较差 |
2(提早刷新) | 每次提交事务只刷新到 OS Buffer,一秒后再调用 fsync()写入Redo Log FIle。 |
InnoDB 的 Redo Log File 是固定大小的。能够配置为每组 4 个文件,每个文件的大小是 1GB,那么 Redo Log File 能够记录 4GB 的操作。
采纳循环写入笼罩的形式,write pos 记录开始写的地位,向后挪动。checkpoint 记录将要擦除的地位,也是向后挪动。write pos 到 checkpoint 之间的地位,是可写区域,checkpoint 到 write pos 之间的地位是已写区域。
3. Undo Log(回滚日志)
3.1 Undo Log 的内容与作用
Undo Log 记录的是逻辑日志,也就是 SQL 语句。
比方:当咱们执行一条 insert 语句时,Undo Log 就记录一条相同的 delete 语句。
作用:
- 回滚事务时,复原到批改前的数据。
- 实现 MVCC(多版本并发管制,Multi-Version Concurrency Control)。
MySQL 事务中原子性就是应用 Undo Log 实现的。
3.2 Undo Log 如何回滚到上一个版本
实现形式通过两个暗藏列 trx_id(最近一次提交事务的 ID)和 roll_pointer(上个版本的地址),建设一个版本链。并在事务中读取的时候生成一个 ReadView(读视图),在 Read Committed 隔离级别下,每次读取都会生成一个读视图,而在 Repeatable Read 隔离级别下,只会在第一次读取时生成一个读视图。
4. Bin Log(备份日志)
4.1 Bin Log 的内容与作用
Bin Log记录的是逻辑日志,即原始的 SQL 语句,是 MySQL 自带的。
作用: 数据备份和主从同步。
Bin Log共有三种日志格局,能够 binlog_format 配置参数指定。
参数值 | 含意 |
---|---|
Statement | 记录原始 SQL 语句,会导致更新工夫与原库不统一。<br/> 比方 update_time=now() |
Row | 记录每行数据的变动,保障了数据与原库统一,毛病是数据量较大。 |
Mixed | Statement 和 Row 的混合模式,默认采纳 Statement 模式,波及日期、函数相干的时候采纳 Row 模式,既缩小了数据量,又保障了数据一致性。 |
4.2 什么时候写入 Bin Log?
Bin Log采纳追加写入的模式,并不会笼罩原有日志,所以能够用来复原到之前某个时刻的数据。
Bin Log也是采纳 WAL 模式,先写日志,再写磁盘。
至于什么时候刷新到磁盘,能够 sync_binlog 配置参数指定。
参数值 | 含意 |
---|---|
0(提早写) | 每次提交事务都不会刷盘,由零碎本人决定什么时候刷盘,可能会失落数据。 |
1(实时写) | 每次提交事务,都会刷盘,性能较差。 |
N(提早写) | 提交 N 个事务后,才会刷盘。 |
退出写 Bin Log 之后的事务流程:
这就是二阶段提交的概念,先写处于 prepare 状态的 Redo Log,事务提交后,再写处于 commit 状态的 Redo Log。
知识点总结:
文章继续更新,能够微信搜一搜「一灯架构」第一工夫浏览更多技术干货。