一条update语句的执行全过程
如果是从java服务器段开始执行,则还需要加上以上过程
从java的线程中通过tcp/ip协议将需要传递的数据报信息(arp),然后网络层->数据链路层->物理层找到对应的交换机。交换机找到对应的路由器,通过DNS域名服务器,找到对应的域名解析,然后通过交换机传到mysql服务器上,通过(RARP)操作得到对应的数据报,然后对其数据报进行解析操作
mysql首先会对客户端的命令进行对应的连接处理,查询是否有权限进行操作对应的数据库,然后判断语句是否要开启mysql事务,查询缓存(此时的缓存非常苛刻,苛刻的原因在于缓存是通过hash表以K,V的方式进行存储的,所以当SQL上有任何字符的不同,都会导致不会命中缓存)然后进行SQL解析(生成简单的语法树,进行判断是否存在SQL语法错误),SQL优化(sql优化也是通过语法树,然后进行对应的更精简的语法树进行查询优化),然后给执行器进行执行分析,以什么的方式走什么样的索引。然后mysql服务器会将执行计划交给innodb执行引擎进行执行操作,innodb根据执行引擎给出的执行方案,
数据存在缓冲区中
先去查询数据,首先也是通过Hash去查询对应的数据索引页,存在则直接对索引加入 index s latch,然后对路径上的节点(索引目录页)加上page s latch,然后找到对应的叶子节点页,通过二分查找法,查找出对应的page x latch,如果没有分页则会释放所有的index s latch和page s latch 和 x latch ,然后对数据索引进行加锁操作,
数据不存在缓冲区
先去查询数据,首先也是通过Hash去查询对应的数据索引页,不存在则会将所对应的页,先加入Free list链表等待加入到对应的LRU链表中的冷链部分,然后对其进行操作处理,同样的加锁操作
然后还会对表加入对应的metadata s lock 。主要是解决和保证DDL和DML之间的操作一致性问题
然后表加入Ix lock 意向锁进行操作 然后加入对应的行级锁(事务id, 索引信息等);
先写undo log 再写 redo log undo log日志保证一致性问题,redo log 保证持久性问题
执行更新前会给undo log先记录一下原来的信息,防止需要进行对应的数据回滚操作,undo log日志中记录的是<T,X,V>三元组,t为事务id,x为元素,v为值,然后将对应的roll pointer指针指向undo log中的记录,然后修改对应的缓冲页中的数据,若是数据大小未发生改变,则触发的是就地更新,然后对redo log进行操作,往redo log中进行添加<T,X,U>u为修改之后的值,然后组成对应的mtr,redo log的回滚是以一组mtr为基本单位来进行回滚的。
然后这里开启mysql中的分布式事务
1,innodb刷redo log到磁盘中修改事务状态为trx_prepated,如果prepare阶段失败就会进行回滚,prepare阶段成功之后就会进行commit阶段
2,commit阶段 mysql服务器写入bin log文件 此时将事务状态修改为trx_not_started状态,此时commit服务就算提交完成
脏页输入磁盘
这里存在的是doublewrite过程,首先会将脏页都复制到doublewrite buffer中,恢复的时候先用doublewritebufer中的页进行恢复,如果不行则用redo log恢复此时也会进行undo log的刷盘,此时为MYSQl线程中的master线程和clear线程进行处理的