mysql一条更新语句是怎么执行的

北京中科中医院好不好 http://pf.39.net/bdfyy/bdfjc/170317/5252031.html

前言

通过文章的内容,大家已经对mysql的基本架构有了了解,我也和大家简单的聊了下一条查询语句是怎么在mysql中运行的。

今天moon就和大家聊聊一条更新语句在mysql中是怎么走完全程的?

读完今天的文章,你将会:

一条更新语句是怎么执行的?

redolog,binlog日志模块是做什么的?都有哪些作用?

正文

moon文章和大家聊了,一条查询语句执行过程当中要经过的模块,有连接器,查询缓存,分析器,优化器,执行器,存储引擎。

那么一条更新语句走完一整个流程又要经过哪些模块呢?

假设一张表里只有一个主键id和一个int字段c

我们从如下代码开始

updateTsetc=c+1whereID=2;

其实查询语句走的流程,基本上更新语句也会走一遍,但是更新语句还会涉及到另外两个重要的日志模块,redolog,binlog。

redolog(重做日志)

首先要告诉大家,redolog是innodb独有的,关于它具体做了什么,moon先和大家举个例子,不知道大家有没有了解过从前街边卖小吃老板的记账方式。

每来一个人,买一份煎饼,老板都会在自己的账单上记住+15元,假如今天第一份收入15元+15总金额15

然后第二份+15总金额30

第三份+15总金额45

这样看确实没毛病,记得也很清楚,但是老板生意越来越好,而且做生意也越来越复杂,除了卖煎饼,还会卖其他的东西,价格也不同,物种琳琅满目,并且人也越来越多,老板就没办法实时去计算了,于是老板改了一种方式,分了两个账单。

第一个账单每天只记录一次总的信息(账本)

年5月5号收入支出净收入

第二个账单记录每天的细节信息(账单)

年5月5日

+15

+16

+48

-23

...........

这样的话老板在忙的时候就不需要管计算的问题,只需要简单记录下金额就好,省去了低效率的计算过程,留在生意不忙的空闲时间去做。

没错,redolog在mysql的日志系统就是类似于这种账单模式,它是先写日志,再写磁盘,也就是先记账,等不忙的时候再去计算写账本。

具体来说,当有一条记录需要更新的时候,InnoDB引擎就会先把记录写到redolog里面,并内存,这个时候更新就算完成了(其实还没有写入磁盘)。同时,InnoDB引擎会在适当的时候(空闲时间),将这个操作记录更新到磁盘里面。

如果今天账单的记录不多,掌柜可以等打烊后再整理。但如果某天的特别多,账本写满了,又怎么办呢?这个时候掌柜只好放下手中的活儿,把账单中的一部分赊账记录更新到账本中,然后把这些记录从账单上擦掉。

与此类似,InnoDB的redolog是固定大小的,比如可以配置为一组4个文件,每个文件的大小是1GB,那么这个“账单”总共就可以记录4GB的操作。从头开始写,写到末尾就又回到开头循环写,如下面这个图所示。

记录点就是记录你要执行的语句是什么,写点就是执行记录点记录的语句,当记录点追上了写点就会发生"内存抖动",从表面上看就是mysql宕机了一会儿,其实是innodb在执行redolog中记录的内容。

有了redolog,InnoDB就可以保证即使数据库发生异常重启,之前提交的记录都不会丢失,这个能力称为crash-safe。

binlog(归档日志)

我们刚刚说了redolog是innodb独有的,那么我们之前也讲了,mysql其实是分为两块的,一块儿是server层,另一块儿才是存储引擎层,那么server层的日志是什么?其实就是我们接下来要讲的binlog。

其实在最早是只有binlog的,因为在远古时代mysql的存储引擎只有myisam,redolog是在后期innodb出现的时候也跟着一起来的,这两个日志也是有很大区别的。

redolog是InnoDB引擎特有的;binlog是MySQL的Server层实现的,所有引擎都可以使用。

redolog是物理日志,记录的是“在某个数据页上做了什么修改”;binlog是逻辑日志,记录的是这个语句的原始逻辑,比如“给ID=2这一行的c字段加1”。

redolog是循环写的,空间固定会用完;binlog是可以追加写入的。“追加写”是指binlog文件写到一定大小后会切换到下一个,并不会覆盖以前的日志。

我们来看看这条更新语句的执行流程

updateTsetc=c+1whereID=2;

⑴.执行器先找引擎取ID=2这一行。ID是主键,引擎直接用树搜索找到这一行。

如果ID=2这一行所在的数据页本来就在内存中,就直接返回给执行器;

否则,需要先从磁盘读入内存,然后再返回。

⑵.执行器拿到引擎给的行数据,把这个值加上1,比如原来是N,现在就是N+1,得到新的一行数据,再调用引擎接口写入这行新数据。

⑶.引擎将这行新数据更新到内存中,同时将这个更新操作记录到redolog里面,此时redolog处于prepare状态。然后告知执行器执行完成了,随时可以提交事务。

⑷.执行器生成这个操作的binlog,并把binlog写入磁盘。

⑸.执行器调用引擎的提交事务接口,引擎把刚刚写入的redolog改成提交(


转载请注明:http://www.aierlanlan.com/rzdk/4359.html