MySQL执行更新SQL流程

目录

[1 redo log](#1 redo log)

[2 binlog](#2 binlog)

[3 Update执行逻辑](#3 Update执行逻辑)


1 redo log
  • InnoDB引擎特有日志
  • MySQL的WAL(Writing Ahead logging)技术,预写式日志,先写日志再写磁盘
  • 当有一条记录需要更新时,InnoDB引擎就会先把记录写在redo log日志中,然后在后面系统比较空闲的时候,将这个操作记录更新到磁盘里面
  • 记录的是物理日志,在某个数据页上做了什么修改
  • 空间大小固定,循环写入

redo日志相关配置

  • innodb_log_file_size:配置单个redo日志文件大小
  • innodb_log_files_in_group:配置redo日志文件个数
  • innodb_log_buffer_size:redo日志内存缓冲区大小
  • innodb_flush_log_at_trx_commit:redo日志缓冲区数据落盘时机
    • 0:每秒将redo日志缓冲区内容写入到文件系统缓存,再同步到磁盘
    • 1:每次提交时立即将redo日志缓冲区内容写入到文件系统缓存,再同步到磁盘
    • 2:每次提交立即将redo日志缓冲区内容写入到文件系统缓存,不立即同步到磁盘,由操作系统决定何时同步到磁盘
  • write pos是当前记录的位置,一边写一边后移,写到3号文件结尾时,就回到0号文开头
  • checkpoint是当前要同步磁盘的开始位置,边将数据同步到磁盘一边向后移动
  • wirte position和checkpoint之间是空闲位置,可以用来记录更新操作
  • 当wirte position追上checkpoint时,得先推进下checkpoint位置,才能继续写更新记录
  • redo log可以保证在数据库发生异常的情况下重启,之前提交的记录都不会丢失,这个能力称之为crash-safe
2 binlog
  • MySQL Server层的日志,也称为归档日志
  • 所有的存储引擎都可以使用
  • 主要用于归档,是逻辑日志,记录的是SQL语句
  • 追加写入,达到设置阈值时,切换新的binlog文件

binlog日志相关配置

  • server-id:开启binlog时,必须设置的唯一id
  • log-bin:配置binlog文件路径和前缀
  • binlog-format:指定binlog日志的格式
    • ROW:记录每一行的变化,占用空间大,但是记录的数据完整准确
    • STATEMENT:记录执行的SQL语句,sql中包含函数执行时会导致主从数据不一致问题
    • MIXED:根据情况自动选择ROW或者STATEMENT

expire_logs_day:设置binlog日志文件的保留天数,默认0,表示不删除旧的日志文件

max_binlog_size:设置单个binlog日志文件的最大大小,当达到该值时,会生成一个新的日志文件

binlog日志的操作

  • show master status:查看当前的日志文件及位置
  • purge binary logs:手动清理日志文件
    • purge binary logs to 'mysql-bin.0000010':删除到指定文件之前的日志
    • purge binary logs before '2025-03-01 00:00:00':删除到指定日期之前的日志
  • show binary logs:查看binlog日志文件列表
  • show binlog events:查看第一个binlog日志内的事件
  • show binlog events in 'mysql-bin.0000010':查看指定binlog日志文件中的事件

binlog解析的工具

  • mysqlbinlog
  • binlog2sql
3 Update执行逻辑

执行update语句内部流程

  • 执行器向存储引擎获取id=1的这一行,
  • 存储引擎使用索引树进行查找,如果id=1这一行所在的数据页本来就在内存中,就直接返回给执行器,否则先从磁盘读入内存,然后在返回
  • 执行器拿到存储引擎给的数据,将name设置为lose,得到新的一行数据,再调用存储引擎写入这行数据
  • 存储引擎将更新后的数据更新到内存中,同时将更新操作记录到redo log中,此时redo log处于prepare状态,告知执行器执行完了,随时可以提交事务
  • 执行器生成这个操作的binlog,并把binlog写入磁盘
  • 执行器调用存储引擎提交事务的接口,将刚刚写入的redo log改成提交(commit)状态,此时更新完成

执行更新流程图

MySQL两阶段提交

  • prepare阶段
    • 将数据写入redo log
    • 将数据写入binlog
  • commit阶段
    • binlog中提交commit请求
    • 调用innodb引擎发送commit请求

那么MySQL如何识别哪些提交属于一个事务呢?

  • 在redo log和binlog中,都包含xid信息,xid是事务id,在MySQL实例中是全局唯一的。

崩溃恢复如何做呢?

  • redo log中事务是完成的,即已经有了commit标识,则直接提交事务
  • redo log中只有完整的prepare,没有commit标识,此时需要在binlog中查找
    • 如果binlog中已经commit,则提交事务
    • 如果binlog没有commit,则回滚事务
相关推荐
Mr.Daozhi39 分钟前
RAG 进阶实战:跑通 Demo 后我连续翻了 6 次车,逐一修复才真正可用(含 Gradio Web 版)
前端·数据库·langchain·大模型·gradio·rag·科研工具
小程故事多_801 小时前
Claude Code自定义workflow skills用法
数据库·人工智能·智能体
大鹏说大话1 小时前
SQL 排序与分组实战:解决“分组后取最新数据“
android·java·数据库
quan26311 小时前
20260529,日常开发-数据库主从问题
java·mysql·主从·延迟
夏贰四1 小时前
数据建模工具如何筑牢数据根基?数据建模工具怎样落实标准体系?
数据库·数学建模·数据建模工具
程序猿阿伟3 小时前
《一套完整方法论:搞定图形应用的Docker镜像优化》
数据库·docker·容器
二等饼干~za8986683 小时前
geo优化源码开发搭建技术分享
大数据·网络·数据库·人工智能·音视频
数据库小学妹3 小时前
HTAP混合负载架构:如何用一个数据库同时搞定交易和分析
数据库·经验分享·架构·dba
wuxinyan1233 小时前
工业级大模型学习之路029:解决双智能体调用数据库报错问题
数据库·人工智能·python·学习·智能体