当前位置: 首页 > article >正文

MySQL高级(二):一条更新语句是如何执行的

执行步骤

1. 解析 SQL 语句

MySQL 首先会解析你输入的 UPDATE 语句。解析器会检查语法是否正确,并将 SQL 语句转化为内部的数据结构(通常是语法树)。

示例 SQL 语句:

UPDATE employees SET salary = 5000 WHERE department = 'Sales';

2. 查询优化

MySQL 会根据查询优化器来决定如何高效执行该更新操作。优化器会生成不同的执行计划并选择最优的执行路径。这一步对于 UPDATE 语句通常意味着决定如何检索要更新的记录,以及使用哪些索引(如果有的话)。

  • 如果 WHERE 子句中有索引,优化器会考虑使用索引来提高查询速度。
  • 如果没有索引,可能会进行全表扫描。

3. 确定要更新的记录

在执行 UPDATE 操作时,MySQL 会根据 WHERE 子句来确定哪些记录需要被更新。在这个过程中,MySQL 会:

  • 使用索引(如果有的话)查找符合条件的记录。
  • 如果没有索引,则会全表扫描,逐行检查。

4. 锁定涉及的行

为了保证数据一致性,MySQL 会在对数据进行更新时使用锁机制,防止其他事务修改同一行数据。这可以是行级锁或表级锁,具体取决于存储引擎(例如 InnoDB)以及事务的隔离级别。

  • InnoDB 存储引擎:通常使用行级锁。
  • MyISAM 存储引擎:使用表级锁。

5. 执行更新

MySQL 会在符合条件的记录上执行更新操作。它会计算新的字段值,并将其写入数据页。这个步骤涉及以下几个方面:

  • 修改数据页:更新操作会修改数据页中的内容。
  • 记录日志:MySQL 会将更新操作记录到事务日志(如 redo logbinlog),以便后续的事务恢复或复制。

6. 提交或回滚事务

如果更新操作是在事务中进行的:

  • 如果事务提交,更新会被永久保存。
  • 如果事务回滚,所有更新会被撤销。

在 InnoDB 存储引擎中,更新操作是通过“日志”的方式确保可恢复性的,即使系统崩溃也可以恢复到一致的状态。

7. 提交更新(对于非事务型存储引擎)

对于非事务型存储引擎(如 MyISAM),MySQL 会立即将更新写入磁盘,不需要提交事务。

redo logbinlog

在 MySQL 中,redo logbinlog 都是用于事务日志记录的重要机制。

redo log

Redo Log(重做日志)是 MySQL InnoDB 存储引擎使用的一种日志类型,它主要用于确保事务的持久性(即 ACID 中的 Durability)和故障恢复。Redo Log 记录了所有对数据库的修改操作,这些修改是为了能够在系统崩溃后,保证数据的一致性和恢复。

特点

  • 事务日志:Redo log 记录的是事务执行过程中对数据页的修改操作,确保即使数据库发生崩溃,也可以通过 redo log 恢复数据。
  • 物理日志:Redo log 记录的是物理层面的变化,即实际的数据修改操作(如页的更新、插入或删除行等),并不像 binlog 记录的是 SQL 语句。
  • 日志缓冲区:InnoDB 会将事务修改的日志先写入到 日志缓冲区(log buffer)中,再定期将这些日志刷写到 redo log 文件
  • 重做:在系统崩溃时,通过 redo log,MySQL 可以重做(redo)未提交的事务,以确保数据不会丢失(即持久性)。
  • 写入顺序:Redo log 是顺序写入的,通常比数据库数据页的更新要快得多。

工作流程

  1. 事务修改数据时,InnoDB 会首先将修改的日志写入 redo log buffer
  2. 每隔一定时间(或者当 buffer 满时),Redo log 会刷新到磁盘的 redo log 文件(通常是 ib_logfile0ib_logfile1)。
  3. 在崩溃恢复时,MySQL 使用 redo log 中的记录来重做所有未完全持久化的数据修改,确保数据一致性。

例子

  • 你执行 UPDATE employees SET salary = 5000 WHERE id = 1;,修改了数据库中的某个数据页。
  • 这个修改操作会先被记录到 redo log 中,而不会立即更新磁盘上的数据页(InnoDB 会将其缓存在内存中)。
  • 如果系统崩溃,在恢复时,InnoDB 会通过 redo log 重做未完成的操作。

binlog

Binlog(二进制日志)是 MySQL 用来记录所有对数据库执行的修改操作的日志,主要用于数据的备份、恢复和主从复制。Binlog 记录的是 逻辑层面的操作(SQL 语句或者事件),而不是直接的物理数据修改。

特点

  • 逻辑日志:Binlog 记录的是 SQL 语句(如 INSERTUPDATEDELETE)或者逻辑事件(如表结构变更)执行的结果,而不是物理的页面修改。
  • 主从复制:Binlog 是 MySQL 主从复制的核心,主服务器的所有修改操作(如 INSERTUPDATE 等)会被记录在 binlog 中,然后从服务器会从 binlog 中读取这些事件并执行相应的 SQL 语句来保持数据同步。
  • 持久性和一致性:Binlog 是一个逻辑日志,用来记录数据变更的操作。它也可以用于数据恢复和备份。
  • 不同的格式:Binlog 支持三种格式:
    • STATEMENT:记录 SQL 语句。
    • ROW:记录每一行数据的具体变化。
    • MIXED:混合模式,结合了 STATEMENT 和 ROW 两种模式。

工作流程

  1. 在执行一个更新操作时(例如 UPDATE employees SET salary = 5000 WHERE department = 'Sales';),该 SQL 语句会被记录到 binlog 中。
  2. Binlog 事件会被顺序写入磁盘中的二进制文件,通常是 mysql-bin.000001 这种格式。
  3. 在主从复制中,从服务器会读取 binlog 中的事件,并通过执行这些事件来同步数据。

例子

  • 你执行 INSERT INTO employees (id, name, salary) VALUES (1, 'Alice', 5000);,该语句会被记录到 binlog 中。
  • 主服务器上的所有修改都会写入 binlog,从服务器会读取并执行这些语句,保持与主服务器的数据一致性。

区别

特性Redo LogBinlog
目的用于事务持久化和崩溃恢复用于数据备份、恢复和主从复制
记录内容物理修改操作(数据页变化)逻辑操作(SQL 语句或者事件)
存储位置存储在 InnoDB 存储引擎的 redo log 文件中存储在 MySQL 的 binlog 文件中
更新频率持续且高频的写入,写入日志缓冲区以事件为单位记录,通常是较低频率的写入
恢复方式在崩溃恢复时,重做未提交的事务,保证数据一致性可以用于主从复制,也可用于基于事件的恢复
是否跨服务器复制不参与主从复制,只与本地数据库相关是的,支持主从复制和基于 binlog 的数据恢复

总结

  • Redo Log:是 InnoDB 用来确保事务持久性和恢复操作的一种机制,记录了对数据页的物理修改。它用于系统崩溃后的恢复。
  • Binlog:记录了数据库的逻辑变化(SQL 语句或事件),用于数据的备份、恢复以及主从复制。

两者各自担任不同的角色,Redo Log 主要用于事务的持久性崩溃恢复,而 Binlog 则用于数据复制备份恢复

总结

  1. 解析:解析 SQL 语句。
  2. 优化:选择最佳执行计划。
  3. 查找记录:根据 WHERE 条件查找符合更新条件的记录。
  4. 锁定行:锁定符合条件的记录,防止其他事务并发修改。
  5. 更新数据:执行实际的更新操作,修改数据页,并记录日志。
  6. 事务处理:事务提交或回滚(如果是事务型存储引擎)。

影响性能的因素

  • 索引WHERE 子句中的字段是否有索引。
  • 表的大小:表中数据量越大,更新操作的成本越高,特别是没有合适索引时需要全表扫描。
  • 事务隔离级别:事务的隔离级别(如 READ COMMITTEDSERIALIZABLE)也会影响锁的粒度及更新的性能。
  • 表的存储引擎:不同的存储引擎(InnoDB vs MyISAM)会影响更新的行为,尤其是在事务和锁的处理上。

http://www.kler.cn/a/394181.html

相关文章:

  • react-redux useSelector钩子 学习样例 + 详细解析
  • WebAssembly在现代Web开发中的应用
  • 搭建深度学习开发环境
  • UDP协议和TCP协议之间有什么具体区别?
  • Nuxt 版本 2 和 版本 3 的区别
  • 【算法】——二分查找合集
  • Flutter:input输入框
  • DOCKER 镜像基础命令
  • Windows 云服务器搭建 FTP 服务
  • 深度学习之全连接、局部连接、全卷积与局部卷积
  • 大数据-224 离线数仓 - 数仓 技术选型 版本选型 系统逻辑架构 数据库命名规范
  • CTF攻防世界小白刷题自学笔记13
  • Mybatis中批量插入foreach优化
  • Jmeter基础篇(22)服务器性能监测工具Nmon的使用
  • zookeeper之节点基本操作
  • Spark 读取 HDFS 文件时 RDD 分区数的确定原理与源码分析
  • ubuntu[无桌面]——使用FileZilla连接本地和虚拟机实现文件共享
  • AI数字人短视频生成--核心源头技术开发
  • StarRocks Summit Asia 2024 全部议程公布!
  • [pyspark] pyspark中如何修改列名字
  • 【机器学习】如何配置anaconda环境(无脑版)
  • 前端(2)——快速入门CSS
  • 证明在无三角形且最大度数为d的图中,随机染色下每个顶点的平均可用颜色数至少为d/3
  • 认证鉴权框架SpringSecurity-2--重点组件和过滤器链篇
  • 华为云分布式缓存服务(DCS)专家深度解析Valkey,助力openEuler峰会
  • zabbix搭建钉钉告警流程