(精选)Mysql执行流程图_JAVA_架构图_系统图_数据库
2024-11-03 14:22:40 139 举报
主要包含Mysql Innodb执行流程,RedoLog和BinLog落盘规则及MVCC中的undo日志版本链详解
作者其他创作
大纲/内容
Buffer Pool缓存池
page cache
即时写入
未提交事务和已提交事务
100
InnoDB存储引擎
BinLog Buffer
BinLog文件
4、写入redo日志
语法词法分析
redoLog Buffer
日志写磁盘流程
InnoDB SQL执行流程
client执行sql(id为1的数据name原值为tx)update t_user set name='Rick' where id = 1;
undo日志文件(InnoDB)name=tx
rick02
8、随机写入磁盘,以Page为单位写入,磁盘数据就变更成Rick
5、准备提交事务,将Redo日志写入磁盘
pagename=tx
后台IO线程
6、准备提交事务,将数据写入Binlog文件
7、写入commit标识到Redo文件,提交完成,保证Redo和Binlog两者一致
参数0
Server层
1
200
参数n
300
执行器
900
undo日志版本链
用户空间
Binlog日志文件(Server层持有)name=Rick
后台线程每秒写入
操作系统决定
Redo日志文件(InnoDB)name=Rick
DB_TRX_ID
物理磁盘
redo log文件
600
管理连接与权限校验
Redo Log Buffer
如果事务提交成功,但是Buffer Pool数据还没有写入磁盘,系统宕机了,可以使用Redo日志里面的数据恢复到Buffer Pool。(顺序写)
max_id = 900
700
400
DB_ROLL_PTR
3、更新内存数据
800
RedoLog 和 BinLog 并不是直接实时写入磁盘,中间还有一个页缓存,用来提升写入读取速度(页缓存是在内核空间,属于特殊的内存空间)
rick04
数据库的增删改查都是直接操作Buffer Pool,一般设置Buffer Pool为机器内存的60%左右
Redo日志是顺序写,循环写,文件大小固定,写满就重头开始写,覆盖原来的内容,断电后可以用来恢复事务数据,但是不可作为整库数据恢复(因为数据被覆盖过)小贴士:每条 redo 记录由“表空间号+数据页号+偏移量+修改数据长度+具体修改的数据”组成BinLog是顺序写,达到限制后,会切换到下一个文件继续写,断电后可作为整库恢复binlog记载的是update/delete/insert这样的SQL语句
即时调用fsync()刷盘
磁盘文件(idb)
1000
未开始事务
执行计划生成与索引选择
连接器
已提交事务
2、写入旧值到undo日志,方便回滚
后台线程每秒调用fsync()刷盘
rick03
内核空间
id
参数2
Binlog是Server层的日志,所有的MySQL存储引擎都支持Binlog。Binlog可以支持主从复制和数据恢复,但是对事务的ACID特性支持比较差。InnoDB存储引擎引入RedoLog和UndoLog事务日志,用于提升事务场景下的数据库性能
500
name
rick01
分析器
如果事务提交失败,需要回滚数据,可以用undo日志里面的数据恢复到Buffer Pool。(随机写)
优化器
n次事务后调用fsync()刷盘
1、加载id=1记录所在的整页数据到Buffer缓存池(如果缓存中有该数据,则这一步不需要)
Binlog主要用来做恢复数据库磁盘里面数据的。(顺序写)
read-view包含如下信息视图数组:[400, 700, 800] min_id:400max_id:900
当前最新记录
调用执行引擎
pagespan style=\
RR级别下:事务开启后,首次查询会生成一致性视图read-view,该视图在事务结束之前都不会变化RC级别下:事务开启后,每次查询都会重新生成新的read-viewread-view视图由查询时所有未提交事务trx_id数组(数组里最小的id为min_id)和已创建的最大事务id(max_id)组成,事务里的任何sql查询结果需要从对应版本链里的最新数据开始逐条跟read-view做比对从而得到最终的快照结果版本链比对规则:1、trx_id<min_id,表示这个trx_id已经提交了,这个数据是可见的2、trx_id>max_id,表示这个trx_id还没有生成(未来生成),这个数据是不可见的3、min_id <= trx_id <= max_id,如果trx_id在视图数组中,表示是未提交的事务,则是不可见的;否则是已经提交的事务,是可见的注:1、begin/start transaction 命令并不是一个事务的起点,执行第一个增删改操作时,才会向mysql申请事务id,mysql内部是严格按照事务的启动顺序来分配事务id2、事务id生成是全局顺序的,但undo日志版本链里面的事务ID并不是顺序的,左图只是方便查看,才将事务id做成顺序的3、删除操作可以认为是特殊update,会将版本链上最新的数据复制一份,然后将trx_id修改成删除操作的trx_id,同时在该条记录的头信息(record header)里的(deleted_flag)标记位写上true,来表示当前记录已经被删除,在查询时按照上面的规则查到对应的记录如果delete_flag标记位为true,意味着记录已被删除,则不返回数据4、事务开启与观察的表的版本链没有关系,比如你观察的是account表的版本链,但是事务开启是因为user表做了更新操作(后面才做account表的更新操作)
InnoDB刷盘策略数据(脏页)刷盘span class=\"hljs- 系统内存不足时,需要将一部分数据页淘汰掉,如果淘汰的是脏页,需要先将脏页同步到磁盘;- MySQL 认为空闲的时间,这种情况没有性能问题;- MySQL 正常关闭之前,会把所有的脏页刷入到磁盘,这种情况也没有性能问题。- redo log 日志满了的情况下,会主动触发脏页刷新到磁盘Redo Log日志InnoDB引擎有一个后台线程,每隔1 秒,就会把 redo log buffer 中的内容写到文件系统缓存(page cache),然后调用 fsync 刷盘。也就是说,一个没有提交事务 redo log 记录,也可能会刷盘。commit刷盘策略由innodb_flush_log_at_trx_commit来控制。0:提交事务时,不进行刷盘操作。提交成功,数据库或者服务器宕机会导致丢失1秒钟的数据1:提交事务时,span style=\
参数1
pagename=tx -> name=Rick
DB_ROW_ID
1100
min_id = 400
0 条评论
下一页