BlogBlog
首页
  • Vue
  • TypeScript
  • React
  • Angular
  • Node.js
  • 小程序
  • Flutter
  • 数据产品
  • 大数据

    • Hadoop
    • Hive
    • Spark
  • MySQL
  • Redis
  • Java
  • Python
  • Golang
GitHub
首页
  • Vue
  • TypeScript
  • React
  • Angular
  • Node.js
  • 小程序
  • Flutter
  • 数据产品
  • 大数据

    • Hadoop
    • Hive
    • Spark
  • MySQL
  • Redis
  • Java
  • Python
  • Golang
GitHub

01-02 | SQL语句如何执行

01 | 基础架构:一条SQL查询语句是如何执行的?

  • 连接和验证权限
  • 查询缓存
  • 分析器, 词法和语法解析
  • 优化器,选择执行计划
  • 执行器, 生成执行计划
  • 查询, 存储引擎处理查询
  • 结果集, 返回给客户端

优化器:

  • 索引选择:选择最优的索引
  • 统计信息:统计表中数据的统计信息,包括索引的选择
  • 代价估算:估算查询的代价,包括IO、CPU、内存等资源的消耗
  • 多表关联查询,join,决定哪个表可以先访问
  • 基于CBO优化
  • 索引下推
  • 映射剪辑
  • 条件推导
  • 子查询优化
  • 视图优化
  • 等等

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

redo log

MySQL WAL 技术,先写日志,再写磁盘。保证掉电重启,数据不丢失(crash-safe)。

redo log 是 InnoDB 引擎特有的日志。

当记录更新时,Innodb 先记录 redo log 再更新内存,这时更新就算完成。引擎往往会在系统空闲时刷盘。

redo log 是实现了类似环形缓冲区,一个指针 write pos 是当前记录的位置,另一个指针 checkpoint 是当前要擦除的位置,

write pos 和checkpoint 之间是空闲部分。如果 write pos 快追上 checkpoint 时,代表缓冲区快满了,需要暂停刷盘

innodb_flush_log_at_trx_commit参数:

  • 0:log buffer将每秒一次地写入log file中,并且log file的flush(刷到磁盘)操作同时进行。该模式下在事务提交的时候,不会主动触发写入磁盘的操作。
  • 1:每次事务提交时MySQL都会把log buffer的数据写入log file,并且flush(刷到磁盘)中去,该模式为系统默认。
  • 2:每次事务提交时MySQL都会把log buffer的数据写入log file,但是flush(刷到磁盘)操作并不会同时进行。该模式下,MySQL会每秒执行一次 flush(刷到磁盘)操作。

binlog

Server层日志。binlog 日志只能用于归档,没有crash-safe能力。

三个用途:

  • 恢复:利用binlog日志恢复数据库数据
  • 复制:主从同步
  • 审计:通过二进制日志中的信息来进行审计,判断是否有对数据库进行注入攻击
format	定义	优点	缺点
statement	记录的是修改SQL语句	日志文件小,节约IO,提高性能	准确性差,对一些系统函数不能准确复制或不能复制,如now()、uuid()等
row(推荐)	记录的是每行实际数据的变更,记两条,更新前和更新后	准确性强,能准确复制数据的变更	日志文件大,较大的网络IO和磁盘IO
mixed	statement和row模式的混合	准确性强,文件大小适中	有可能发生主从不一致问题


sync_binlog参数:
0:当事务提交后,Mysql仅仅是将binlog_cache中的数据写入Binlog文件,但不执行fsync之类的磁盘 同步指令通知文件系统将缓存刷新到磁盘,而让Filesystem自行决定什么时候来做同步,这个是性能最好的。
n:在进行n次事务提交以后,Mysql将执行一次fsync之类的磁盘同步指令,同志文件系统将Binlog文件缓存刷新到磁盘

不同点:

redo log 是物理日志,记录的是“在某个数据页上做了什么修改”;binlog 是逻辑日志,记录的是这个语句的原始逻辑,比如“给 ID=2 这一行的 c 字段加 1 ”。 redo log 是循环写的,空间固定会用完;binlog 是可以追加写入的。binlog 文件到一定大小,会切换到下一个文件。

undo log

InnoDB 引擎支持事务的原子性和一致性,通过 undo log 来实现。

undo log 是 InnoDB 引擎特有的日志。 undo log 主要用于实现事务的回滚操作,当事务执行过程中,如果出现错误或者需要回滚,InnoDB 引擎会通过 undo log 来实现事务的回滚。

undo log 记录的是数据修改前的状态,当需要回滚时,通过 undo log 可以将数据恢复到修改前的状态。

undo log 的数据结构是一颗 B+ 树,每个节点对应一个事务,记录了这个事务对这个节点的修改。

undo log 的插入和删除操作都需要写 redo log,保证数据一致性。

undo log 的大小是可以配置的,默认大小是 1MB。

undo log 作用

  • 事务回滚:当事务执行过程中,如果出现错误或者需要回滚,InnoDB 引擎会通过 undo log 来实现事务的回滚。
  • 多版本并发控制:InnoDB 引擎支持多版本并发控制,通过 undo log 可以实现旧版本数据可见性。
最近更新:: 2025/5/4 09:43
Contributors: alice