首先创建一张表;

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

如果要更新ID=2这行+1;应该这样写

update T set c=c+1 where ID=2;

执行这句操作首先还是要与数据库建立连接这是连接器的工作。
在一个表进行更新操作时,这张表的缓存就会失效。

接下来分析器会对这条跟新语句进行语法和词法分析,如果有问题就会报错提示。然后优化器会决定使用ID的索引情况,最后执行器负责执行,找到这行然后更新。

与查询操作不同的是,更新操作涉及到两个重要的日志模块。redo log(重做日志),bin log(归档日志)。如果接触到MySQL这两个日志是必学的。

redo log

如果每一次的更新操作都需要写进磁盘,然后磁盘也要找到对应的那条记录,然后在更新,这个过程IO成本、查找成本都很高。为了解决这个问题,MySQL的设计者就用了类似于酒店掌柜的黑板记录来提升效率。
WAL技术简称Write-Ahead Logging ,他的关键就是先写日志再写磁盘。写磁盘的时间并不是固定的,他是等到系统比较空闲的时候才写入磁盘。

当一条记录需要更新的时候,InnoDB引擎就会把记录写进redo log里面,并更新内存。这个时候就算更新完成了。同时,InnoDB引擎会在适当的时候将这个操作记录更新到磁盘中。

还有需要注意的是,InnoDB的redo log 是固定大小的,比如以组分为4个文件,每个文件大小是1GB,那么这个日子就可以记录4GB的操作。从头开始写,写到结尾再从头开始写。是一个循环。

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

要理解crash-safe这个概念,可以想象赊账的例子,只要赊账记录在了黑板上或卸载账本上,即使店长忘记了,但也有黑板上或账本上的明确数目。

bin log

上面所说的redo log 是InnoDB引擎独有的日志,而Server层也有自己的日志,称为bin log(归档日志)。

其实bin log日志出现的时间比redo log早,因为最开始MySQL是没有InnoDB存储引擎的,5.5之前是MyISAM。但是MyISAM没有crash-safe的能力,binlog日志只能永固归档。而InnoDB是另一个公司使用的一套日志系统来实现crash-safe能力。

两种日志的区别

  1. redo log 是InnoDB独有的;bing log 是MySQL的Server层实现的,所有引擎都可以使用。
  2. redo log 是物理日志,记录的是在某个数据页改动了哪些;bin log 是逻辑日志,记录的是SQL语句具体操作。
  3. redo log 是循环写的,空间固定会用完;binlog是可以追加写入的。追加写是指binlog文件写到一定大小后会切换到下一个,并不会覆盖以前的日志。

update语句内部流程

  1. 执行器先找到引擎ID=2这行,ID是主键,引擎直接用树搜索找到这一行。如果ID=2这行数据被就在内存中那就不需要再调入内存直接返回给执行器;否则需要先从磁盘读入内存,然后再返回。
  2. 执行器拿到引擎给的行数据,把行值+1,得到新的一行数据,在调用引擎接口写入这行新数据。
  3. 引擎将这行新数据更新到内存中,同时将这个更新操作记录到redo log里面,此时redo log处于prepare状态。然后告知执行器执行完成了,随时可以提交事务。
  4. 执行器生成这个操作的bin log,并把bin log 写入磁盘。
  5. 执行器调用引擎的提交事务接口,引擎把刚刚写入的redo log改成提交状态,更新完成。
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

上图中浅绿色的是在InnoDB引擎中执行的,墨绿色是在Server层完成的。

如果不使用“两阶段提交”,那么数据库的状态就有可能和用它的日志恢复出来的库的状态不一致。

MySQL45讲:一条update语句是怎样执行的的更多相关文章

  1. 如何将多条update语句合并为一条

    需求: 如何将多条update语句合并为一条update语句:如,update table1 set col='2012' where id='2014001'      update table1  ...

  2. Sql Server执行一条Update语句很慢,插入数据失败

    今天同事要我修改服务器数据库里面的2条数据,查看服务器上的SQL Server数据库的时候,发现这几天数据没有添加成功,然后发现磁盘很快就满了,执行Update语句时,执行半天都提示还在执行,查询语句 ...

  3. 完蛋,公司被一条 update 语句干趴了!

    大家好,我是小林. 昨晚在群划水的时候,看到有位读者说了这么一件事. 在这里插入图片描述 大概就是,在线上执行一条 update 语句修改数据库数据的时候,where 条件没有带上索引,导致业务直接崩 ...

  4. 一条update语句到底加了多少锁?带你深入理解底层原理

    迎面走来了你的面试官,身穿格子衫,挺着啤酒肚,发际线严重后移的中年男子. 手拿泡着枸杞的保温杯,胳膊夹着MacBook,MacBook上还贴着公司标语:"我爱加班". 面试开始,直 ...

  5. MySQL:一条更新语句是如何执行的

    目录 引言 更新流程图 更新流程说明 第一步:更新数据 数据页内存 Change Buffer 第二步:缓存日志内容 redo log buffer binlog cache 第三步:日志写入磁盘 两 ...

  6. 一条 SQL 语句是如何执行的

    一条 SQL 语句是如何执行的 SQL查询语句 select * from user where ID=10; MySQL 的基本架构可以分为 Server 层和存储引擎两部分.Server 层又包含 ...

  7. 一条SQL语句是如何执行的?--Mysql45讲笔记记录 打卡day1

    写在前面的话:回想以前上班的时候,空闲时间还是挺多的,但是都荒废了.如今找工作着实费劲了.但是这段时间在极客时间买了mysql45讲,就好像发现了新大陆一样,这是我认真做笔记的第一天,说实话第一讲我已 ...

  8. sql执行万条update语句优化

    几个月没有更新笔记了,最近遇到一个坑爹的问题,顺道记录一下.. 需求是这样的:一次性修改上万条数据库. 项目是用MVC+linq的. 本来想着用 直接where() 1 var latentCusto ...

  9. 用一条UPDATE语句交换两列的值

    在SQL UPDATE语句中,"="右侧的值在整个UPDATE语句中都是一致的,所有更新同时发生!因此以下语句将在没有临时变量的情况下交换两列的值: UPDATE table SE ...

随机推荐

  1. 安卓11配置谷歌FCM推送报错

    2020-12-11 11:57:50.872 15404-15464/com.sp.notify E/FirebaseInstanceId: Failed to get FIS auth token ...

  2. tomcat-1-介绍篇

    java语言分为三个体系: javase javaee,是javase的基础 一般就是指jdk javaee java的企业版本 其实是一套规范,就是用java语言做企业开发(目前看来就是开发一些动态 ...

  3. STL——容器(Map & multimap)的查找

    map.find(key);   //查找键key是否存在,若存在,返回该键的元素的迭代器:若不存在,返回map.end(); map.count(key);   //返回容器中键值为key的对组个数 ...

  4. STL——容器(Map & multimap)的删除

    Map & multimap 的删除 map.clear();           //删除所有元素 map.erase(pos);      //删除pos迭代器所指的元素,返回下一个元素的 ...

  5. Docker部署FastDFS(附示例代码)

    1. FastDFS简介   FastDFS是一个开源的分布式文件系统,它对文件进行管理,功能包括:文件存储.文件同步.文件访问(文件上传.文件下载)等,解决了大容量存储和负载均衡的问题.特别适合以文 ...

  6. win10平衡模式、高性能模式和卓越模式三种电池模式的区别

    win10在1803版本后,有了很多隐藏的功能.电池模式中的"卓越模式"就是其中之一. 互相比较一下: 节能模式:顾名思义是最省电的,此模式下会禁用一些系统特效,且CPU运行频率是 ...

  7. springMVC基础讲解

    一.初识三层架构: 在讲解springMVC之前,先来了解一下什么是三层架构.我们的开发架构一般都是基于两种形式,一种是C/S架构(客户端/服务器),另一种是B/S架构(浏览器服务器).在javaEE ...

  8. 【Git】命令思维导图

    Git命令思维导图

  9. Arduino PROGMEM 从程序空间读取float值的方法

    方法: 使用avr-libc提供的宏定义: #define pgm_read_float_near(address_short) __LPM_float((uint16_t)(address_shor ...

  10. Autofac的基本使用---1、前言

    Autofac的基本使用---目录 代码地址 https://github.com/catbiscuit/AutofacStudy 参考网上的大神,原博文地址 https://www.cnblogs. ...