数据库基础1:语句执行步骤

一条SQL语句执行步骤

来源于MySQL实战

mysql> select * from T where ID=10;
MySQL逻辑架构图

查询语句执行分析

  • MySQL分为Server层和存储引擎层

  • 连接器:
    负责跟客户端建立链接、获取权限、维持和管理连接

    1. 如果用户名或密码不对,你就会收到一个"Access denied for user"的错误,然后客户端程序结束执行。
    2. 如果用户名密码认证通过,连接器会到权限表里面查出你拥有的权限。之后,这个连接里面的权限判断逻辑,都将依赖于此时读到的权限。
  • 查询缓存:
    MySQL拿到一个查询请求后,会先到查询缓存内看看,之前是否执行过这条语句。之前的语句及其结果以key-value对的形式缓存在内存中。
    大多数情况下不建议使用查询缓存,因为查询缓存失效非常频繁。只要表中有数据更新,则这个表上的所有查询缓存都会被清空。
    静态表适合查询缓存。

  • 分析器:
    如果没有命中查询缓存,则开始真正执行语句。
    分析器先进行词法分析,主要识别sql语句中各个字符串代表的含义。然后进行语法分析,根据语法规则判断输入语句是否满足MySql语法。

  • 优化器:
    在表里有多个索引时,决定用哪个索引。或者多表关联(join)时,决定各个表的连接顺序。

  • 执行器:
    MySql通过分析器知道了要做什么,通过优化器知道了该怎么做,下一步就进入执行器开始执行语句。
    1.先判断对表T有没有执行权限;
    2.如果有权限,则根据表中引擎定义,使用引擎提供的相关接口。

更新语句执行分析

  1. 首先可以确认的是查询语句的那一套流程,更新语句也是同样走一遍。与查询流程不一样的是,更新流程还涉及两个重要的日志模块。也就是下面要分析的两个主角:redo log(重做日志)、binlog(归档日志)
  2. 为什么会有两份日志呢?因为最开始并没有InnoDB引擎,数据库自带的引擎是MyISAM,这个引擎并没有crash-safe能力,所有后续的InnoDB使用了另外一套日志
  3. 两种日志存在三点不同。
    1.redo log属于引擎日志,binlog属于服务层日志;
    2.redo log是物理日志,记录的是“在某个数据页上做了什么修改”;binlog是逻辑日志,记录的是这个语句的原始逻辑,比如"给ID=2这一行的c字段加1";
    3.redo 是循环写,binlog可以追加写;
  • redo log(引擎层日志)
    1. 如果每次更新操作,数据库都需要查询磁盘,然后找到对应的记录,再更新记录,整个过程IO成本、查找成本很高。基于以上情况,MySql先顺序落盘,然后等空闲时在更新数据。MySql的WAL(Write-Ahead Logging)技术,关键点就是先写日志(循序写盘),再写磁盘。
    2. 数据库中InnoDB的redo log是固定大小的,在循环使用时,需要保证被擦掉的数据已经更新到磁盘中。有了redo log,InnoDB就可以保证数据库发生异常重启,之前提交的记录都不会丢失,这就是crash-safe
  • binlog(Server层日志)
mysql> update T set c=c+1 where ID=2;
  1. 执行器先找引擎取ID=2这一行。引擎判断这一行所在数据页是否在内存中,是则直接返回,否则先从磁盘读入内存,然后再返回;
  2. 执行器拿到行数据后,更新行数据,并调用引擎接口写入数据;
  3. 引擎更新内存中数据页,并将更新操作记录到redo log里面,此时redo log处于prepare状态。告之执行器执行完成了,可以随时提交事务。
  4. 执行器生成该操作的binlog,并把binlog写入磁盘;
    5.执行器调用引擎的提交事务接口,引擎把刚刚写入的redo log改成提交(commit)状态,更新完成。

以下是相关执行流程图:

update语句执行流程

⚠️大家可能注意到,最后三步看上去有点“绕”,将redo log的写入拆分成两个步骤:prepare和commit,这就是“两阶段提交

怎样让数据库恢复到半月内任意一秒的状态?
仍然用前面的 update 语句来做例子。
假设当前 ID=2 的行,字段 c 的值是 0,再假设执行 update 语句过程中在写完第一个日志后,第二个日志还没有写完期间发生了 crash,会出现什么情况呢?

先写 redo log 后写 binlog。假设在 redo log 写完,binlog 还没有写完的时候,MySQL 进程异常重启。由于我们前面说过的,redo log 写完之后,系统即使崩溃,仍然能够把数据恢复回来,所以恢复后这一行 c 的值是 1。但是由于 binlog 没写完就 crash 了,这时候 binlog 里面就没有记录这个语句。因此,之后备份日志的时候,存起来的 binlog 里面就没有这条语句。然后你会发现,如果需要用这个 binlog 来恢复临时库的话,由于这个语句的 binlog 丢失,这个临时库就会少了这一次更新,恢复出来的这一行 c 的值就是 0,与原库的值不同。

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

MySQL 使用两阶段提交主要解决 binlog 和 redo log 的数据一致性的问题。
崩溃恢复规则
redo log 和 binlog 有一个共同的数据字段,叫 XID。崩溃恢复的时候,会按顺序扫描 redo log:

如果碰到既有 prepare、又有 commit 的 redo log,就直接提交;
如果碰到只有 parepare、而没有 commit 的 redo log,就拿着 XID 去 binlog 找对应的事务。
binlog无记录,回滚事务
binlog有记录,提交事务。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 161,513评论 4 369
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,312评论 1 305
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 111,124评论 0 254
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,529评论 0 217
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,937评论 3 295
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,913评论 1 224
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,084评论 2 317
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,816评论 0 205
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,593评论 1 249
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,788评论 2 253
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,267评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,601评论 3 261
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,265评论 3 241
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,158评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,953评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,066评论 2 285
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,852评论 2 277