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

建表语句如下:

create table T(ID int primary key, c int);

更新的sql语句执行流程与查询的sql语句执行流程基本相同。
上一章说过,在一个表更新的时候,跟这个表有关的查询缓存就会失效,所以这条语句就会把表T上面所有的缓存结果清空,这就是为什么不推荐使用查询缓存的原因。
接下来。分析器会通过词法解析和语法解析来知道这是一条更新语句。优化器决定要使用ID这个索引。然后执行器负责具体执行,找到这一行,然后更新。
相比较于查询寻流程,更新流程多了两个重要的日志模块,redo log(重做日志)和binlog(归档日志)。

重要的日志模块redo log

更新的步骤如下:
先从磁盘中读取记录到内存,然后更新内存中的数据,再回写到磁盘,下次再更新就从磁盘继续查找。
如此会产生大量的IO操作,不仅仅会产生IO开销,也会产生大量的查找成本。
此时产生了MYSQL的WAL技术。也就是Write-Ahead Logging,它的关键点就是先写日志,再写磁盘。
此时一条记录需要更新的的时候。InnoDB引擎会将记录先写如redo log里面,并更新内存,这个时候更新操作就算完成了,同时在适当的时候InnoDBDB会将这个操作记录更新到磁盘里面,往往是在系统比较空闲的时候。
InnoDB的redo log是固定大小的,比如可以配置一组4个文件,每个文件的大小事1G,那么总共就可以记录4G的操作,从头开始写,写到末尾又回到开头重写,如下:


image.png

write pos是当前记录的位置,一边写一边往后移动,写到第三号文件末尾后就重写回到0号文件的开头,checkpoint是当然要擦除的位置,也是往后推移并且循环的,擦除记录前要把记录更新到数据库文件。
write pos和checkpoint质检室空着的部分,也已用来记录新的操作,如果weite pos=checkpoint的时候,表示redo log满了,无法再执行新的更新,得把一些记录清除(写入到磁盘),才能继续执行新的更新,即将checkpoint向前推进
有了redo log的另一个优势是,当mysql突然发生宕机,那么写入在内存中的数据来不及更新到磁盘的时候,即使mysql重启,之前提交的记录都不会丢失,这个能力被称为crash-safe。

重要的日志模块:binlog

上一章已经说明了mysql可以分为两大块,一块是Server层另一块是引擎层。前面的redo log是innodb存储引擎独有的日志,而server层也有自己的日志,称为binlog(归档日志)
最开始mysql存储引擎并没有InnoDB,那时候mysql的自带引擎是MyISAM,但是MyISAM并没有crash-safe能力,binlog日志只能用于归档(记录的是逻辑日志,如给id为2的c字段加1)
redo log和binlog有以下三种不同点:

  1. redo log是innoDB引擎独有的;binlog是mysql的Server层实现的,所有的引擎都可以使用
  2. redo log是物理日志,记录的是“在某个数据也上修改了什么”;binlog是逻辑日志,记录的是这个语句的原始逻辑,比如“”给id=2的这一行c字段加1“”。
  3. redo log是循环写入的,内存空间有限,而binlog是可以追加写入的,文件达到一定大小之后会切换到另一个,并不会覆盖以前的日志。
    再看执行器和InnoDB引擎在执行update语句时的内部流程
  4. 执行器先通过引擎找到id =2这一行,ID是主键,因此执行使用树搜索找到这一行,如果ID=2这一行所在的数据页本来就在内存中,就直接返回给执行器,否则需要先从磁盘读入内存,再返回
  5. 执行器拿到引擎给的行数据,把回这个值加上1,得到一航信的数据,再调用引擎接口写入这一行数据。
  6. 引擎将这行数据更新到内存中,同时将这更新操作写入到redo log里面,此时redo log处于prepare状态,然后告知执行器执行完了,随时可以提交事务。
  7. 执行器生成这个操作的binlog,并把binlog写入到磁盘。
  8. 执行器调用引擎的提交事务接口,引擎把刚刚写入的redo log改成commit状态,更新完成


    image.png

    最后三步将redo log的写入拆成了两个步骤,prepare和commit,这就是两段提交

两阶段提交

为什么必须有两阶段提交?就是为了让两份日志之间的逻辑一直,从而可以是的数据库恢复到半月内任意一秒的状态,那么要怎样才能做到。
binlog会记录所有的binlog,那么如果要做到恢复到半个月内的任意一秒的状态,那么久意味着,保存了这半个月的binlog,同时系统会定期做整库备份

当需要恢复数据库的时候,首先要找到最近的一次全量备份。然后从备份的时间点开始,将被纷纷的Binlog依次取出来,重放到需要恢复的时刻

那么为什么需要两阶段提交?使用反证法来说明

  1. 先写redo log后写binlog,在binlog还没写的时候发生了crash,这个时候binlog里面没有记录这些语句。在redo log里面写完之后,后面即使发生系统崩溃,仍然能够把数据恢复过来,所以恢复之后这一行的数据是1,但是binLog里面没有记录这一次的更新语句,所以如果需要使用binlog恢复原数据库的值就是0,与原数据库值不同
  2. 先写binlog在写redolog,在binlog写入了更新语句,在redo log里将状态编程commit状态之前发生了crash,此时就算使用binlog将数据值恢复过来,由于在redo log里面记录的状态是repapare,那么这个事务无效,因此本次更新语句无效,恢复出来的数据值仍然是0,与原数据库值不同
    因此,如果不使用两阶段提交,那么数据库的状态就有可能和用它日志恢复出来的状态不一致。
    补充:
    redo log记录的是数据页做了什么改动
    binlog有两种模式,statement格式的话是记录sql语句,row格式会记录行的内容,记两条,更新前和更新后都有
    MySQL server 层和InnoDB层都保存了表结构
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,324评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,356评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,328评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,147评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,160评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,115评论 1 296
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,025评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,867评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,307评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,528评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,688评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,409评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,001评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,657评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,811评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,685评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,573评论 2 353

推荐阅读更多精彩内容