关键词:
预读取、局部性原理、bufferpool、redo log、undo log、随机io、顺序io、刷脏、物理日志、逻辑日志
简介:
更新语句包含插入、删除、修改
流程与查询语句基本一致,都需要经过解释器、优化器的处理,最后交给处理器
区别在于拿到数据之后的处理
执行流程:示例:update user set name = 'penyuyan' where id=1;
事务开始,从bufferpool或磁盘拿到数据页,返回给server层的执行器
server层的执行器修改数据页的这一行数据的值为 penyuyan
记录name=‘qingshan’到undo log
调用存储引擎接口,记录数据页到buffer pool
记录name=‘penyuyan’到redo log,标记状态为prepare
server层写入binlog
commit,提交事务
将redolog中这个事务的标记状态为commit
简图如下:
先记录到内存(buffer pool),再记录日志
redolog分为两个阶段(prepare和commit)
存储引擎和server层记录不同的日志
先记录redolog,再记录binlog
缓冲池 buffer pool:为了提高读写的效率
对于innodb或操作系统来说,数据存储在硬盘上,每次磁盘io相对于内存的操作都很慢;所以都有一个预读取的概念
局部性原理:当磁盘上的一块数据被读取的时候,很可能它附近的位置也会马上被读取到
所以,每次读取数据的时候,会多读取一点,而不是用多少读多少
innodb设定了一个存储引擎预读取的最小单位,叫做页。跟操作系统的页大小4k不同,它默认是16k,是一个逻辑单位
读取数据时,优先从buffer pool中查找,再从磁盘读取
修改数据时,也是先写入到buffer pool,每隔一段时间就一次性把多个修改写入磁盘,这个动作叫做刷脏。
buffer pool的默认大小是128m;查看命令:show variables like "%innodb_buffer_pool%"
redo log:
因为刷脏不是实时的,如果buffer pool里的数据还没有刷入磁盘,数据库宕机或重启,这些数据会丢失
所以innodb把对页面的修改专门写入了一个日志文件:redo log
数据库启动时,会从这个日志文件进行恢复操作,实现crash-safe。事务的持久性就是用它来实现的
redo log 特点:
redo log是innodb的一个特性,支持崩溃恢复
是物理日志,记录的是在某个数据页上做了什么修改
大小是固定的,默认两个文件,每个48m,写满会触发buffer pool到磁盘的同步,腾出空间记录后边的修改
innodb的缓存过期策略:
优化的lru,使用了冷热分离
lfu
undo log:
记录了数据修改前的状态,如果数据异常,可以用undo log回滚
事务回滚时,只是从逻辑上恢复至事务之前的状态,而不是在物理页面上操作时间的,属于逻辑格式的日志
默认在ibdata1文件中
binlog:server层日志,所有存储引擎通用
记录了所有的DDL和DML语句,记录的是操作而不是数据值,属于逻辑日志。比如:给 id=1 这一行的字段count加1
主要用于 主从复制和数据恢复