丁奇的MySQL基础课
林晓斌(网名“丁奇”)
前阿里资深技术专家
立即订阅
4 人已学习
课程目录
已完结 6 讲
01 | 基础架构:一条SQL查询语句是如何执行的?
免费
02 | 日志系统:一条SQL更新语句是如何执行的?
03 | 事务隔离:为什么你改了我还看不见?
04 | 深入浅出索引(上)
05 | 深入浅出索引(下)
06 | 全局锁和表锁 :给表加个字段怎么有这么多阻碍?
丁奇的MySQL基础课
登录|注册

02 | 日志系统:一条SQL更新语句是如何执行的?

林晓斌 2019-08-09
前面我们系统了解了一个查询语句的执行流程,并介绍了执行过程中涉及的处理模块。相信你还记得,一条查询语句的执行过程一般是经过连接器、分析器、优化器、执行器等功能模块,最后到达存储引擎。
那么,一条更新语句的执行流程又是怎样的呢?
之前你可能经常听 DBA 同事说,MySQL 可以恢复到半个月内任意一秒的状态,惊叹的同时,你是不是心中也会不免会好奇,这是怎样做到的呢?
我们还是从一个表的一条更新语句说起,下面是这个表的创建语句,这个表有一个主键 ID 和一个整型字段 c:
mysql> create table T(ID int primary key, c int);
如果要将 ID=2 这一行的值加 1,SQL 语句就会这么写:
mysql> update T set c=c+1 where ID=2;
前面我有跟你介绍过 SQL 语句基本的执行链路,这里我再把那张图拿过来,你也可以先简单看看这个图回顾下。首先,可以确定的说,查询语句的那一套流程,更新语句也是同样会走一遍。
MySQL 的逻辑架构图
你执行语句前要先连接数据库,这是连接器的工作。
前面我们说过,在一个表上有更新的时候,跟这个表有关的查询缓存会失效,所以这条语句就会把表 T 上所有缓存结果都清空。这也就是我们一般不建议使用查询缓存的原因。
接下来,分析器会通过词法和语法解析知道这是一条更新语句。优化器决定要使用 ID 这个索引。然后,执行器负责具体执行,找到这一行,然后更新。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《丁奇的MySQL基础课》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(20)

  • 王小李
    如果是在 binlog 写完之后崩溃。什么时候 redo log 会更新到 commit 状态?
    2019-08-12
    9
    13
  • JasonLong
    数据每天变化比较多的时候,选择每天备份,好处就是当数据库需要恢复时,利用binlog回放时间要短。 每天备份对数据库的影响: 占用更多的系统空间,mysqldump备份会把热点数据给刷新掉,增加磁盘的io,对db性能有部分影响
    2019-08-15
    5
  • 左青虫右白鼠
    为什么写redo log速度较快,redo logo不也是写到磁盘上吗?
    2019-08-15
    7
    3
  • 饭团
    我看大家都在说为什么写日志会比直接更新原数据快!我的理解是因为日志是顺序写,而数据是随机写,所以写日志会更快一些!
    不知道对不对!希望老师点评!
    2019-09-18
    2
  • hgf
    为什么redo log可以作为粉板?文中描述,redo log记录的是物理描述,记录的在某个数据上做了某项修改。但是这里的某项数据是逻辑描述还是物理描述?逻辑描述就是某行数据的某列更新为某个值;物理描述,某个内存页的某个地址,更新为某个值。


    如果是后者,即物理描述,那肯定也不会快的吧?相当于已经找到了数据的物理位置,直接更新岂不是更好?
    2019-08-19
    3
    2
  • Geek_b8bf97
    一般考虑备份有几点吧:
    1、数据更新的多少
    2、磁盘的压力
    3、数据库的压力
    4、会不会影响业务
    5、数据库是否有备份的窗口
    因此,一天一备的数据库应该是更新操作比较多,有一定的业务空闲窗口,利用磁盘io的空闲期,并且业务数据比较重要。
    大概想到这几点
    2019-08-18
    2
  • langer
    两段提交的事务是从哪一步开始的?主要是想知道如果把更新之后的行数据(做加1的算术)写入内存后crash了,redo log并没有记录,那这个新数据是会回滚还是留在内存了?我觉得应该回滚了,否则下次要么读数据或者更新这条数据应该会不一致吧
    2019-08-13
    1
    2
  • 左析墨
    问个问题,既然redolog是物理日志,相关到存储引擎,数据库异常要恢复数据,为啥不用redolog而用binlog呢?备份恢复用binlog上的sql语句再全部执行一遍?
    2019-09-28
  • cnzhujie
    如果redo log写入内存成功了,但在写入磁盘前crash了,是不是这部分数据就丢失了?
    2019-09-26
  • vardumpabc
    具体来说,当有一条记录需要更新的时候,InnoDB 引擎就会先把记录写到 redo log(粉板)里面,并更新内存,这个时候更新就算完成了。
    这里的 写到内存不太理解,之前内容没有提到内存,写到内存的是什么内容呢,如果修改一条数据之后,redo log还没更新到磁盘,又是怎样操作的呢
    2019-09-20
  • 三角形小于零
    按照文章所说的账本和粉板都能找到记录,那么crash safe这个能力其实并不是redo log单独赋予的
    2019-09-20
  • _yh葱
    应该是删除,更新,新增操作频密的场景,入抢购,拼团,并发量很高的时候。2个日志主要记录的是数据的变动。
    2019-09-19
  • 有点过分,但是
    我觉得按周备份还是按日备份取决于数据库对外提供服务的高峰,或者用户活跃度情况。
    比如通讯类软件或者视频类,每天基本都会有高峰,对于用户来说近期(甚至昨天)的数据是很重要的,那么可能需要按日备份;
    如果是类似于教育类,用户周一到周五活跃度较低,周末活跃度较高的情况就可以考虑按周备份或者更宽泛的纬度。
    2019-09-19
  • 你头发乱了喔
    为什么第一种情况 恢复之后c会是0呢
    2019-09-18
  • 两阶段提交,数据也可能不一致,比如写binlog成功,commit失败,这怎么解决呢
    2019-09-17
    1
  • Easyman
    有个疑问,对于两段提交日志过程中,有两种情况:
    1. redo log prepare后binlog写之前,服务crush.
    2. binlog写之后redo log commit之前,服务crush.
    这两种情况,会导致主备不一致吗?
    2019-08-20
    2
  • KevinSu
    binlog是因为redolog没引用时才使用,但是现在都有redoog了,redolog完全可以代替binlog,为什么还要给binlog备份呢,是mysql公司忘记删掉binlog了吗
    2019-08-18
    4
  • 墨飞域
    一套系统里往往有多个数据库,其中可能有1-n个是关键节点,而关键节点上,又有某些可能会有单点,即使不是单点,关键节点上也可能会有频繁的更新,对于这些节点的数据库,我认为可以一天一更新
    2019-08-16
  • 谷鱼
    可恢复性,可用性吧。更新语录比较多
    2019-08-15
  • Janet-林
    两阶段提交那里,写入binlog后崩溃了,redo log 那条数据为prepared,mysql异常重启后,会继续向下继续执行commit吗,还是会回滚删除那条redo log prepared 和 binlog的数据呢?
    2019-08-15
    1
收起评论
20
返回
顶部