14|数据库事务:事务提交了,你的数据就一定不会丢吗?
该思维导图由 AI 生成,仅供参考
前置知识
undo log
- 深入了解
- 翻译
- 解释
- 总结
本文深入探讨了数据库事务的实现机制,着重介绍了undo log和redo log的作用和机制。undo log记录了事务执行过程中被修改的数据,用于事务回滚时恢复数据库到原始状态;而redo log则记录了数据库的更改操作,以便在数据库发生崩溃或其他问题时进行重做。文章还介绍了InnoDB引擎如何综合利用undo log和redo log来实现事务,并详细描述了事务执行过程中的重要子流程。此外,还介绍了binlog的作用和与redo log的关系,以及事务的ACID特性。对于面试准备,文章提供了基本思路和亮点方案,帮助读者准备数据库事务相关的面试问题。整体而言,本文内容涵盖了数据库事务的核心概念和实现细节,适合读者快速了解数据库事务的重要概念和实现原理。文章还提到了中间件的写入语义和在分布式环境下的写入语义,以及调整刷盘时机的技巧,为读者提供了实用的技术知识和面试准备建议。
《后端工程师的高阶面经》,新⼈⾸单¥59
全部留言(18)
- 最新
- 精选
- sheep"等到事务结束之后,就把 buffer pool 的数据刷新到磁盘里面" 这里buffer pool刷盘一般是由于redo log 日志满了、Buffer Pool 空间不足或者MySQL空闲时候,才进行的刷盘吧。事务提交的其中一个操作是,由于innodb_flush_log_at_trx_commit=1,此时事务提交之后,需要将redo log进行刷盘
作者回复: 是的,我在这个上下文里面只是想表达这里还有一个刷盘的动作。后续的内容也是讨论了刷盘的具体参数问题。
2023-10-11归属地:广东3 - Geek_be29f8每次提交的时候刷新到磁盘上,也就是最安全的选项,InnoDB 的默认值。 是redolog刷新到磁盘这个行为成功,事务才会返回成功吗,因此宕机也不丢失数据? 如果是异步操作,redolog没真正刷盘成功,事务返回成功了的话,看起来还是会丢失数据呀
作者回复: 对的,所以以前就很喜欢问这种刁钻的问题,什么我提交了就一定不会丢失之类的在实践中没啥意义的问题。
2024-01-08归属地:北京1 - sheep"在聊到隔离性和隔离级别的时候我说到一个个人观点,即未提交读和已提交读,不能看作完全实现了隔离性,你怎么看待这两者?" 这个得从隔离级别的含义说起,"隔离其他事务的干扰,也就是不同事务之间不会相互影响",未提交隔离级别下的修改,事务之间都是可见的;读提交隔离级别下的修改,一个事务提交之后,对另外一个事务就是可见的了。因此,这两个隔离级别下,很明显不满足事务的隔离性
作者回复: 赞!哈哈哈,这就是一个辩经问题,我也比较赞同你的观点。
2023-10-12归属地:广东1 - 文敦复“即便是在 SSD 上,顺序写也能比随机写速度快上一个数量级。” 这里想说的是机械硬盘HDD?
作者回复: 是的,HDD。
2023-10-20归属地:四川 - 隰有荷老师,我看文中说到 "redo log 本身也是先写进 redo log buffer,后面再刷新到操作系统的 page cache,或者一步到位刷新到磁盘。" 请问在什么情况下可以从 redo log buffer 一步刷到位的刷到磁盘?
作者回复: 一步到位的意思,并不是说绕过了 page cache,而是说刷新到 page cache 之后立刻又刷新到磁盘。倒是不能直接绕开 page cache。
2023-10-16归属地:广东 - 隰有荷老师,关于undo log中的最后一个图中,数据的隐藏字段ROLL_PTR的指向是不是当前数据行的undo log的信息?您图中所述的第一个是指最新的一个undo log 还是最旧的一个undo log?
作者回复: 是指向当前行的,应该是最新的。
2023-10-12归属地:广东 - Geek_7b73be老师想问一下 之所以以 binlog 为判断标准,是因为在两阶段提交里面,两个参与方 binlog 和 redo log 中,binlog 已经提交成功了,那么 redo log 自然可以认为也提交成功了 redo log的Commit不是在binlog的后边吗 为什么binlog提交成功了就可以认为redo log也提交成功了?
作者回复: 核心就是你得有一个标准,要么用 binlog,要么用 redolog。但是你考虑到,MySQL 的引擎,不是所有的都有 redolog,因此考虑不同引擎,并且考虑语义的话,还是只能以 binlog 为准。 binlog 标记提交了,redolog 就要利用已有的信息修复数据。
2023-09-25归属地:上海2 - 爱吃锅巴的沐泡磁盘中的redo log文件和真实库表数据文件idb可不是一个文件,redo log是为了故障恢复用的,里面记录的是内存页的修改物理内容,比如修改了第5号表空间中页号为100的页上偏移量20字节的位置上由3改为1 这样一句话,redolog从log Buffer中刷盘是顺序刷盘的,只是记录日志,并不会修改真实库表文件idb的。库表数据修改了是在内存Buffer pool中记录的,会有IO线程定期刷盘Buffer pool到库表idb文件中的,这个刷盘是随机IO的。
作者回复: 是的,只有真实修改那一步是随机,毕竟你数据放哪里这是一个难以转成顺序写的事情。只是说你不修改配置的话,在提交的时候不一定触发了刷盘,那么你就相当于只是顺序写了 log,所以性能比较好。
2023-08-24归属地:北京 - tyro老师我有两个疑问: Q1:redo log可能是在事务执行过程中(也就是事务提交之前)就已经被后台线程持久化硬盘了,但可能这个事务此时还没有执行完,Mysql就崩溃了。重启恢复的时候回放redo log,是能读到这个事务前半段的redo log的,这个时候数据应该回滚吧。那Mysql是怎么判断redo log中这些日志,哪些要回滚哪些要提交呢? Q2:在两阶段提交中,是需要用XID来关联redo log和bin log的吧。这样才能在故障恢复的时候识别出redo log存在的记录在bin log中是否页存在。那这个XID是在什么时候生成的呢,又是在什么时候写入redo log和bin log中的呢。是在事务开启时就生成好了,并在两种log写入的过程中一直伴随着log到buffer、到硬盘的吗?还是在事务提交阶段才开启内部事务,并生成的XID呢?如果是后者,那又回到了Q1,redo log在事务提交之前可能已经持久化到硬盘,这个时候是没有XID的,怎么和bin log关联呢? 求老师解惑,谢谢🙏
作者回复: 1. 看 redo log 中有没有 commit 这一条 log,严格来说应该是看和 redo log 配对的那个 bin log 里面有没有 commit 这一条,如果是 row,就会有一个 XID 的 event。 2. 这个地方我给你看一段它 binlog_recover 的原文注释: After a crash, storage engines may contain transactions that are prepared but not committed (in theory any engine, in practice InnoDB). This function uses the binary log as the source of truth to determine which of these transactions should be committed and which should be rolled back. The function collects the XIDs of all transactions that are completely written to the binary log into a hash, and passes this hash to the storage engines through the ha_recover function in the handler interface. This tells the storage engines to commit all prepared transactions that are in the set, and to roll back all prepared transactions that are not in the set.
2023-08-23归属地:广东 - Geek_9af983XID你没说呀,很重要
作者回复: 你说的是 binlog 里面的 XID 吗?貌似不讲它也不影响理解这篇文章。
2023-07-30归属地:北京