持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第 12 天,点击查看活动详情
哈喽,大家好,我是二毛。
上篇文章,我们一起了解了 undoLog 的概念,以及作用。那么在今天的这篇文章里,我将介绍下 redoLog 的相关知识。
什么是 redoLog
我们先来看下,redoLog 在 BufferPool 中的大概位置。
可见,redo log 包括两部分:
- 一个是内存中的日志缓冲( redo log buffer )
- 另一个是磁盘上的日志文件( redo log )
mysql 执行一条 sql 时,都会先在 RedoLog Buffer 中写入一条数据,后续再将这些数据在某个时机以某种策略进行落盘。
这种先写日志,后落盘持久化的技术其实也叫做 WAL 技术。
redoLog的作用
可能会有小伙伴问,为什么不直接把数据落入磁盘,还要引入 redoLog 这种东西呢?这不是把事情搞得更复杂了?况且,redoLog也是需要落盘的,反正都得落盘,不如直接把 redoLog 去掉!
其实并不然,所谓存在即合理。
主要的一个原因是提升写入性能。虽然引入 redoLog 是复杂了,但对于性能的提升却是非常高的。复杂了,想办法解决就是。
事务有个特性叫持久性,意思就是:只要事务提交成功,那么对数据库做的修改就被永久保存下来了。
那么 mysql 是如何保证的呢?最简单的做法是在每次事务提交的时候,将该事务涉及修改的数据页全部刷新到磁盘中。
但是这么做会有严重的性能问题,主要体现在两个方面:
- 因为 Innodb 是以 页 为单位进行磁盘交互的,这个时候将完整的数据页刷到磁盘的话,太浪费资源了!因为一个事务很可能只修改一个数据页里面的几个字节。
- 随机IO写入性能太差。因为一个事务可能涉及修改多个数据页,并且这些数据页在物理上并不连续,就会导致随机IO。
因此 mysql 设计了 redo log, 具体来说就是只记录事务对数据页做了哪些修改 ,这样就能完美地解决性能问题了,因为相对而言文件更小并且是顺序IO。
只要有 redoLog,那么就能把 BufferPool 中的进行重放恢复,相当于把 BufferPool 中的数据进行了日志备份一样,因此哪怕断电了, BufferPool 中的数据丢失,也能通过 redoLog 进行恢复过来。
同时,只要 redoLog 还能记录 BufferPool 里的数据,那么 BufferPool 中的脏页就可以不用那么快进行落盘,一定程度上缓解了脏页落盘的压力。
有了 redoLog,是否一定不会丢失数据?
答案是否定的,是有可能丢失数据的。
这个就得看 redoLog buffer 会在什么时候落盘到 redoLog。
官方为了能够更加适配我们各种各样的应用场景,提供了三种配置,可通过参数 nnodb_flush_log_at_trx_commit 进行设置,如图:
对应的写入示意图:
最后
今天这篇文章主要介绍了 redolog 的相关知识点,希望对大家有帮助。
我是二毛,我们下期再见~