本文 的 原文 地址
尼恩说在前面:
在40岁老架构师 尼恩的读者交流群(50+)中,最近有小伙伴拿到了一线互联网企业如得物、阿里、滴滴、极兔、有赞、shein 希音、shopee、百度、网易的面试资格,遇到很多很重要的面试题:
MySQL崩溃,重启后发现有些已经提交的事务对数据的修改丢失了? 你分析一下 是什么原因。
什么情况导致了“事务已经提交,数据却丢失”呢?
前几天 小伙伴面试 美团,遇到了这个问题。但是由于 没有回答好,导致面试挂了。
小伙伴面试完了之后,来求助尼恩。那么,遇到 这个问题,该如何才能回答得很漂亮,才能 让面试官刮目相看、口水直流。
所以,尼恩给大家做一下系统化、体系化的梳理,使得大家内力猛增,可以充分展示一下大家雄厚的 “技术肌肉”,让面试官爱到 “不能自已、口水直流”,然后实现”offer直提”。
当然,这道面试题,以及参考答案,也会收入咱们的 《尼恩Java面试宝典》V145版本PDF集群,供后面的小伙伴参考,提升大家的 3高 架构、设计、开发水平。
最新《尼恩 架构笔记》《尼恩高并发三部曲》《尼恩Java面试宝典》的PDF,请关注本公众号【技术自由圈】获取,后台回复:领电子书
原始的 面试问题
下面是小伙伴面试遇到的问题:
MySQL崩溃,重启后发现有些已经提交的事务对数据的修改丢失了,不是说事务能保证ACID一致性么,什么情况导致了“事务已经提交,数据却丢失”呢?
事务提交,数据为什么会丢失?
大家知道, 在 mysql 三大日志中,通过 redo log 保证ACID了 持久性。
MySQL三大日志 详细内容,参考 尼恩团队的文章: 美团面试:binlog、redolog、undo log底层原理是啥?分别实现ACID哪个特性?(尼恩图解,史上最全)
mysql崩溃恢复时,使用的是redo log 恢复 。
但是redo log日志有一个内存优化机制,根据参数,可能每隔1S从 log buffer 写入 os cache,然后刷盘,
这时如果崩溃,redo log日志在缓存中,有可能丢失1S的数据。
为什么要有redo log ?
事务提交后,必须将事务对数据页的修改刷(fsync)到磁盘上,才能保证事务的ACID特性。
这个刷盘,是一个随机写,随机写性能较低,如果每次事务提交都刷盘,会极大影响数据库的性能。
随机写性能差,有什么优化方法呢?
架构设计中有两个常见的优化方法:
- 先写日志(Write-Ahead Logging 预写日志),将随机写优化为顺序写;
- 将每次写优化为批量写;
这两个优化,mysql都用上了。
先说第一个优化,将对数据的修改先顺序写到日志里,这个日志就是redo log。
假如某一时刻,数据库崩溃,还没来得及将数据页刷盘,数据库重启时,会重做redo log里的内容,以保证已提交事务对数据的影响被刷到磁盘上。
一句话,redo log是为了保证已提交事务的ACID的一致性,同时能够提高数据库性能的技术。
既然redo log能保证事务的ACID的一致性,那为什么还会出现,“事务提交了,数据库崩溃,丢数据”的问题呢?继续看redo log刷盘实现细节。
redo log是怎么刷盘的?

通过上面的示意图,简单说明下redo log的三层架构:
(1) 粉色,是InnoDB的一项很重要的内存结构(In-Memory Structure),日志缓冲区(Log Buffer),这一层,是MySQL应用程序用户态;
(2) 黄色,是操作系统的缓冲区(OS cache),这一层,是OS内核态;
(3) 蓝色,是落盘的日志文件;
redo log最终落盘的步骤如何?
**第一步:**事务提交的时候,会写入Log Buffer,这里调用的是MySQL自己的函数WriteRedoLog;
**第二步:**只有当MySQL发起系统调用写文件write时,Log Buffer里的数据,才会写到OS cache。
注意,MySQL系统调用完write之后,就认为文件已经写完,如果不flush,什么时候落盘,是操作系统决定的;
比如:有时候打日志,明明printf了,tail -f却看不到,就是这个原因,操作系统还没有刷盘。
**第三歩:**由操作系统(当然,MySQL也可以主动flush)将OS cache里的数据,最终fsync到磁盘上;
思考下面问题?
(1)操作系统为什么要缓冲数据到OS cache里,而不直接刷盘呢?
这里就是将“每次写”优化为“批量写”,以提高操作系统性能。
(2)数据库为什么要缓冲数据到Log Buffer里,而不是直接write呢?
这也是“每次写”优化为“批量写”思路的体现,以提高数据库性能。
这个优化思路,非常常见,高并发的MQ落盘,高并发的业务数据落盘,都可以使用。

最低0.47元/天 解锁文章
3280

被折叠的 条评论
为什么被折叠?



