持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第8天,点击查看活动详情
mysql语句在存储引擎中执行流程
假设sql语句: update user set username = 'lisi' where id = '10';
-
当sql语句执行到存储引擎中时,存储引擎中会存在一个数据库缓冲池 Buffer Pool,存储引擎首先检测 id = '10' 的那笔数据是否存在于缓冲池中;若存在就直接进行下一步;若不存在,则存储引擎首先会将这笔数据从磁盘上加载到数据库缓冲池里去。
-
当待操作的那笔数据存在于数据缓冲池中之后,存储引擎会将操作写入 undo log 日志文件中,以后若出现数据丢失,可以通过此日志文件进行数据的事务回滚,恢复数据
-
然后在数据库中缓冲池中,存储引擎开始对这笔数据 (存在数据库换冲池的数据,不是磁盘上的数据) 进行更新 update 操作;存储引擎中存在 redo log buffer 缓冲池;数据操作完成之后,存储引擎会写入日志到 redo log buffer中,后续 redo log buffer 会直接写 redo log 日志文件到磁盘中去; 但是此处就会有一个问题,假如此时电脑宕机了,那么 redo log buffer 缓冲池的数据会全部丢失掉,那么更新操作就无效了;此处就涉及到 redo log buffer 中的一个刷新策略,此策略的值是可配置的,值为 0 1 2
- 当刷新策略的值为0的时候,表示
- 当刷新策略的值为1的时候,表示redo log会立即写入到磁盘中去,这个也是一般最推荐的,因为当电脑宕机的时候,缓存数据都丢失了,那么这个时候数据库就可以立即读取 redo log日志文件,对操作的数据进行恢复(恢复到数据修改后的状态),这种情况才是最符合日常事务的处理
- 当刷新策略的值为2的时候,表示 redo log 日志不会直接写入到磁盘文件中,而是会暂时写入 cache 缓存中去,等过一段时间,再从 cache 中写入到磁盘;这样操作也是有风险的,万一此时redo log 日志只是在 cache 中存在,电脑宕机,那么数据也会丢失,无法恢复。因此刷新配置策略设置为1最好
-
写入 redo log文件的同时,也会写入 binlog日志,同理 binlog 日志 sync_binlog参数 可以配置刷盘策略,值为0 和 1
- 值为0的时候,binlog是先写入到 os cache 缓冲中,在从 os cache写入到磁盘文件中,同理,若电脑宕机,则无法恢复对数据的操作
- 值为1的时候,binlog是直接写入到磁盘文件中的,一般设置为1
-
写完 binlog 日志文件之后,会返回 binlog日志的文件名和文件所在的位置给 redo log,与此同时也会返一个 commit 标记给 redo log日志,表示事物已经提交完成了
-
此时,buffer pool缓冲池中数据已经被修改为 lisi ,但是磁盘中数据依旧没有修改,还是原数据。此时,会由系统的 IO 线程在未来某个时间点会在后台去执行,刷新修改磁盘中数据。当前也不用担心此时电脑宕机了,因为日志文件已经保存在磁盘中了,就算电脑宕机了,系统也可以根据 redo log日志文件和 binlog 日志文件去进行数据的恢复
注意
- 为什么日志既要写入到 redo log文件中去,还要写入到 binlog日志文件,只写一个不可以吗?
- 数据库为什么不直接修改磁盘上的数据?