全网最通透:MySQL 的 redo log 保证数据不丢的原理

总会有面试官问:你知道 MySQL 如何保障数据不丢的吗?实际上这个问题是十分不准确的,MySQL 保障数据不丢的手段可太多了。但通常面试官想听的内容就是 redo log 两段式提交是如何保障数据不丢的。(不过个人感觉这么说还是不太准确)

所谓「redo log」,意即「重做日志」,也就是用来恢复数据用的日志。所谓「两段式提交」,也被称作「两阶段提交」(Two-Phase Commit,简称 2PC)。本文主要讲 MySQL 内部 XA 事务中 redo log 两段式提交的细节。为了让大家饱餐一顿,我会先为大家上亿点点前菜,虽然有点多,但是相信会很开胃。

开胃前菜

你知道什么是存储引擎、随机 IO 和顺序 IO吗?你知道 MySQL 中的缓冲池吗?binlog、redo log 听说过吗?都有什么用?什么?你都不知道?面试结束了。

什么是存储引擎?

存储引擎是 MySQL 中直接与磁盘交互部分。页是存储引擎读写数据的最小单位,一个页里可以有一条或多条表记录。MySQL 中的存储引擎有很多种,比如 InnoDB、MyISAM、Memory 等。其中最常用的是 InnoDB。而 InnoDB 是 MySQL 中唯一能够完整支持事务特性的存储引擎,也是一个高性能的存储引擎。本文要讲的「两段式提交」就发生在 InnoDB 中。

什么是随机 IO 和顺序 IO?

磁盘读写数据的两种方式。随机 IO 需要先找到地址,再读写数据,每次拿到的地址都是随机的。就像送外卖,每一单送的地址都不一样,到处跑,效率极低。而顺序 IO,由于地址是连贯的,找到地址后,一次可以读写许多数据,效率比较高。就像送外卖,所有的单子地址都在一栋楼,一下可以送很多,效率很高。

什么是缓冲池?

关系型数据库的特点就是需要对磁盘中大量的数据进行存取,所以有时候也被叫做基于磁盘的数据库。正是因为数据库需要频繁对磁盘进行 IO 操作,为了改善因为直接读写磁盘导致的 IO 性能问题,所以引入了缓冲池。

缓冲池是一片内存区域,存储引擎在读取数据时,会先将页读取到缓冲池中。下次读取时,先判断是否在缓冲池,如果在,则直接读取,否则从磁盘中读取。在修改数据时,如果缓冲池中不存在所需的数据页,则从磁盘读入缓冲池,否则直接对缓冲池中的数据页进行修改。

这样的好处是,如果我们频繁修改某一个位于磁盘的数据页,我们可以不用每次都去磁盘读写(注意是读和写)该页,而是直接对缓冲池中的内容修改,在一定的时机再把数据刷新到磁盘。这样就会使得对磁盘的多次操作变为一次。即便修改的内容在磁盘中相距较远的不同数据页上,我们也可以将对多次对磁盘的 IO 合并为一次随机 IO。被修改的数据页会与磁盘上的数据产生短暂的不一致,我们称此时缓冲池中的数据页为 脏页 ,将该页刷到磁盘的操作称为 刷脏页 (本句是重点,后面要吃)。这个刷脏页的时机我们看看就好:[^1]

innodb_max_dirty_pages_pct

由于这个刷脏页的过程还是异步的,这样更新操作就不需要等待磁盘的 IO 操作了。因此这些特点极大地提升了 Inno

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值