MYSQL--一条SQL更新语句是如何执行的?

输入一条更新语句,例如:update user set c=c+1 where  ID=1

具体执行流程与查询语句类似,详情请点击:https://mp.csdn.net/console/editor/html/105358656

流程走到执行器时,涉及两个重要的日志模块,redo  log(重做日志)  binlog(归档日志)

redo log:

现在有一个酒馆,喝酒的人来酒馆喝酒,因为大家都是熟人,所以可以赊账,现在有一个小黑板,当有顾客赊账或者清账赊账时,老板就把记录记在黑板上,但是黑板终究地方有限,当赊账清账的人变多时,就写不下了,老板肯定还有自己的一个账本用来记录,将黑板上的记录挪到账本上。

所以平常有人赊账清账时,老板有两个选择,要么写到黑板上,之后将记录挪到账本上。要么将记录直接写到账本上,但是账本上有很多记录,老板在登记时可能来不及翻找那么多的记录,所以他一般先写到黑板上,不忙的时候再挪到账本(一般是打烊的时候再挪)。

黑板和账本配合的这个过程就是MYSQL中经常说到的WAL技术,全称是Write-Ahead- Logging,关键点就是先写日志,再写磁盘

redo log就相当于这个黑板,他是InnoDB中独有的。

redo log是固定大小的,他类似于一个圈,和循环队列类似,圈里面设立一个当前记录位置write pos,一个checkpoint是需要清除的位置,当有新纪录时,write pos继续向下走,当需要清除时,checkpoint向下走,write pos与checkpoint中间的部分就是redo log中空余的部分。

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

比如老板有事几天不开门,之后可以通过账本和黑板上的数据明确账目。

binlog:

MYSQL自带的引擎是MYLSAM,他的日志是binlog,但是binlog没有crash-safe功能,只有归档功能。

两种日志有以下区别:

1. redo log是innoDB引擎特有的,binlog是MYSQL的Server层实现的,所有引擎都可以使用。

2. redo log是物理日志,记录的是“在某个数据页上做出什么修改”,binlog是逻辑日志,记录sql语句。

3. redo log是循环写的,空间固定。binlog是可以追加写入的,追加的意思是binlog写到一定大小会切换到下一个,不会覆盖以前的日志。

因此执行器和innoDB执行sql语句的流程如下:

1.执行器先找ID=10这一行,如果内存中有,就返回给执行器,如果没有,就从磁盘读入主存,然后再返回。

2.执行器把c这个变量加上1

3.引擎将这行数据更新到内存中,记录更新到redo log中,redo log此时处于prepare状态,告诉执行器可以提交了。

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

5.提交事务,将redo log改成commit状态,更新完成。

步骤3--5,就是两阶段提交。

怎么让数据库恢复到半月内任意一秒呢?

binlog会记录所有的逻辑操作,会有数据库备份。

如果要找回数据,比如找回今天中午十二点的数据,首先,先找回最近的一次全量备份,如果运气好,可能就是前一天的备份,从这个备份恢复到临时库。然后,从备份的时间点开始,将备份中的binlog依次取出,直到删之前的那个时刻。

发布了307 篇原创文章 · 获赞 9 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/hx1043116928/article/details/105363554