MYSQL 2:一条更新语句是如何进行的

一. MYSQL的一条更新语句如何进行的?

和查询一样,一开始我们需要通过连接器连接到MYSQL服务器上,然后我们会将我们的语句交给解析器,然后交给执行器。比如我们执行一条这样的语句

update c=c+1 from user_info where id =2

1.执行器会去取id=2 这一行,如果在内存中就直接返回,如果不在就去磁盘中找,找到后返回行数据

2.执行器会为c这一属性加一,然后得到新的一行,我们再更新内存里的数据

3.更新这一行的redo log日志

4.将redo log更改为prepare状态

5.然后我们更新binlog日志并写库

6.提交事务

 MYSQL 2:一条更新语句是如何进行的_第1张图片

二. 储存引擎给我们准备的日志 redo log

redo log存的是表数据,日志是直接将数据库的数据文件保存下来,但是它并不是mysql自带的日志,而是储存引擎带的,但是只要有他就可以safe-cache。

redo log它是循环写的,如下图:

MYSQL 2:一条更新语句是如何进行的_第2张图片

write pos 负责写,check point负责擦, write pos和checkpoint之间的是“粉板”上还空着的部分,可以用来记录新的操作。如果write pos追上checkpoint,表示“粉板”满了,这时候不能再执行新的更新,得停下来先擦掉一些记录,把checkpoint推进一下。

三. MYSQL服务层自带的日志 binlog

这个主要用来主从复制以及其他的mysql中间件的使用,它存的是逻辑日志,所以他是没有办法保证safe-cache的,他只能归档(因此我们不能总指望它来回复数据库的信息,为啥ne?后面会讲到很多因为事务的问题所产生的binlog问题),而且binlog是无限写的,一个文件写不下就写下一个。

四. 为啥日志需要两段式提交

采用反证法:

先写redo log,再写binlog,我们来看看有啥问题,现在假如我们在写redo log的时候,数据库突然宕机了,那么等我们重启的时候,redo log因为已经写入,所以我们可以通过这个redo log来恢复数据库数据,但是此时binlog并没有写入,那么binlog和redo log就不是一样的逻辑了。

先写binlog 再写 redo log,如果在写redo log的时候宕机了,如果在binlog写完之后crash,由于redo log还没写,崩溃恢复以后这个事务无效,所以这一行c的值是0。但是binlog里面已经记录了“把c从0改成1”这个日志。所以,在之后用binlog来恢复的时候就多了一个事务出来,恢复出来的这一行c的值就是1,与原库的值不同。

所以为了防止两个日志不一致,必须两段式提交

你可能感兴趣的:(mysql,数据库)