这篇笔记主要目的是梳理清楚,一条数据的落地,中间会在哪些组件中有写入
已知的有redo log, undo log, 索引,数据文件,写入的顺序是怎么样,完成到哪个步骤,就可认为事务算是结束了。数据恢复,当数据库意外down机后,重启后怎么恢复数据,有哪些场景会导致数据丢失(恢复不了)
主要是对这篇文章https://www.slideshare.net/MariaDB/m18-deep-dive-innodb-transactions-and-write-paths的翻译整理
A Detailed Look at a Single-ROW AUTOCOMMIT Trasaction:
UPDATE talk SET attendees =25 WHERE conference='M|18' AND name = 'Deep Dive';
Step 1:SQL 层
- 构建语法树
- 检查权限
- 获取MDL(防止有DDL对更改表)并打开表
- 获取索引统计?
- 生成执行计划
Step 2a:通过引擎接口读取数据
- 根据where条件匹配所有rows(根据索引或者遍历主键索引)
- <font color="#0000CD">在第一次读的时候,InnoDB才会开启事务</font>
- 分配一个新的DB_TRX_ID(InnoDB 全局递增)
- 因为这是一个互斥操作,需要获取锁,所以不需要read view。
Step 2b: 过滤行
-
如果WHERE条件只能通过范围扫描或全表扫描,必须要过滤掉不匹配的行
如果能利用索引下推,InnoDB层直接过滤掉不匹配的行
-
否则,逐行返回,MySQL服务层来过滤
索引下推 Index Condition PushDown -ICP
是利用索引优化查询的技术,查询数据的流程,InnoDB层在主键索引中(如果执行机会能走二级索引,会先在二级索引中过滤掉不匹配的主键)找到整行数据,返回给MySQL层,一直循环,直至所有符合条件的行被返回。这时候看执行计划中,显示的是using where.如果where 条件中有索引字段,但是没被计划选择(比如 where a like '%xxx'),则在InnodDB层,现在索引中比对该字段,如果不符合条件,不会再去获取整行,当然也不会返回给MySQL 层了。
-
每返回一行,就开启一个mini-transaction
这里说的每返回的一行,表示InnoDB返回的,即便是这行在MySQL层会过滤掉,也会开启一个mini-transaction吗?
Step 2c: 获取所有匹配行的锁
-
InnoDB will write-lock each index leaf read
Note: InnoDB has no “table row locks”, but “record locks” in each index separately.
-
If using index condition pushdown, non-matching records are not locked.
看不懂。。。。。锁的到底是什么 索引???因为row只能通过主键索引来获取
- 所有可能被修改的记录被锁住?
Step 3a: 记录Undo log
Step 3b: 更新所有匹配的行
Step 4a: 提交
可能的Step 4a: 回滚
Step 4b: 清理
- 当
COMMIT
执行后,释放所有的行锁 - 唤醒其他等待这些锁的事务
- 释放MDL,此时可以执行DDL了
这一套又是好复杂的东西 骑马得看好几天。。。。。。