惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

C
Cisco Blogs
Schneier on Security
Schneier on Security
T
Tor Project blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
T
Tenable Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
T
Threat Research - Cisco Blogs
C
CERT Recently Published Vulnerability Notes
Security Latest
Security Latest
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
NISL@THU
NISL@THU
L
Lohrmann on Cybersecurity
Scott Helme
Scott Helme
Webroot Blog
Webroot Blog
Project Zero
Project Zero
Google Online Security Blog
Google Online Security Blog
The Last Watchdog
The Last Watchdog
Spread Privacy
Spread Privacy
Hacker News: Ask HN
Hacker News: Ask HN
PCI Perspectives
PCI Perspectives
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
W
WeLiveSecurity
Attack and Defense Labs
Attack and Defense Labs
D
Darknet – Hacking Tools, Hacker News & Cyber Security
N
News | PayPal Newsroom
Help Net Security
Help Net Security
The Hacker News
The Hacker News
H
Heimdal Security Blog
O
OpenAI News
S
Security @ Cisco Blogs
N
News and Events Feed by Topic
Cyberwarzone
Cyberwarzone
Simon Willison's Weblog
Simon Willison's Weblog
G
GRAHAM CLULEY
www.infosecurity-magazine.com
www.infosecurity-magazine.com
博客园 - 叶小钗
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Hacker News - Newest:
Hacker News - Newest: "LLM"
T
Tailwind CSS Blog
大猫的无限游戏
大猫的无限游戏
A
Arctic Wolf
I
Intezer
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
S
Security Affairs
P
Proofpoint News Feed
S
Secure Thoughts
腾讯CDC
Google DeepMind News
Google DeepMind News
量子位
罗磊的独立博客

博客园 - 纪莫

技术面:如何让你的系统抗住高并发的流量? 技术面:MySQL篇(InnoDB的锁机制) 技术面:MySQL篇(InnoDB事务执行过程、事务隔离级别、事务并发异常) 技术面:如何解决缓存和数据库一致性的问题? 技术面:MySQL篇(为啥会有非关系型数据库?MySQL的数据存储一定在磁盘吗?) 技术面:SpringCloud(SpringCloud有哪些组件,SpringCloud与Dubbo的区别) 技术面:SpringBoot(springboot的类加载和传统的双亲委派有什么区别、如何按顺序实例化Bean) 技术面:SpringBoot(启动流程、如何优雅停机) 技术面:Spring(循环依赖,spring与springboot的区别) 技术面:Spring (事务传播机制、事务失效的原因、BeanFactory和FactoryBean的关系) 阿里一面:类加载的过程是怎么样的? 双亲委派的优点和缺点? 产生fullGC的情况有哪些? spring的动态代理有哪些?区别是什么? 如何排查CPU使用率过高? 技术面:Spring (bean的生命周期、创建方式、注入方式、作用域) 技术面:Java并发(线程同步、死锁、多线程编排) 技术面:Java并发(线程池、ForkJoinPool) 技术面:Java并发(上下文切换、线程安全、并发与并行、守护线程、虚拟线程) DDD领域驱动设计的理解 Kafka如何保证「消息不丢失」,「顺序传输」,「不重复消费」,以及为什么会发生重平衡(reblanace) Kafka为什么吞吐量大,速度快? Elasticsearch写入数据的过程是什么样的?以及是如何快速更新索引数据的?
技术面:MySQL(一条SQL在MySQL的执行过程?、MyISAM和InnoDB的区别?数据库事务机制?)
纪莫 · 2025-11-24 · via 博客园 - 纪莫

MyISAM和InnoDB的区别

  • 事务能力(这是最根本的区别!)
    • InnoDB:支持事务(ACID),就像银行转账,要么全部成功,要么全部失败,保证数据安全
    • MyISAM:不支持事务,就像手写账本,“写错一笔就全盘皆输”
  • 锁机制(并发性能的关键)
    • InnoDB:行级锁,只锁你要操作的行,别人还能同时操作其他行
    • MyISAM:表级锁,你一写,整张表都锁住,别人只能干等
  • 外键支持
    • InnoDB:支持外键,能自动保证关联表数据一致
    • MyISAM:不支持外键,需要靠程序员自己写逻辑
  • 读写性能
    • InnoDB:读写都均衡,适合高并发场景
    • MyISAM:读快写慢,写操作会锁整张表,适合"读多写少"的场景
  • 故障恢复
    • InnoDB:有完善的崩溃恢复机制,不怕突然断电
    • MyISAM:断电后可能要手动修复,就像突然断电的Excel文档
  • 存储方式
    • InnoDB:数据和索引一起存,用.ibd文件
    • MyISAM:数据、索引、表结构分开存,分别是.MYD、.MYI、.frm
  • 适用场景
    • InnoDB:适合高并发读写、需要事务和外键的场景,例如:电商、银行系统。写入性能更稳定(行锁减少锁冲突)。
    • MyISAM:适合读多写少的场景(如报表、日志系统、数据仓库)。
      批量查询速度可能更快(无事务开销,表锁简单)。

总结

维度 MyISAM InnoDB
事务 不支持 支持(ACID、提交/回滚)
锁粒度 表级锁 行级锁(含间隙锁)
外键 不支持 支持
崩溃恢复 仅依赖检查/修复表(REPAIR TABLE) redo/undo 日志自动崩溃恢复
索引类型 非聚簇索引(数据与索引分离) 聚簇索引(主键即数据)
存储文件 .MYD(数据)+.MYI(索引) .ibd(单表空间)或共享表空间
COUNT(*) 内置计数器,瞬间返回(无WHERE条件下) InnoDB 执行 COUNT() 需要扫描可用索引或聚簇索引,数据量越大耗时越长
全文索引 5.6 之前仅 MyISAM 支持原生全文索引 5.6+ 支持,性能更优
压缩表 myisampack 只读压缩 支持行格式压缩(ROW_FORMAT=COMPRESSED)
适用场景 读多写少、无事务、静态报表 高并发读写、需要事务/外键/恢复保障

如何选择

优先InnoDB:现代MySQL的默认引擎,适合99%的场景,尤其是需要事务、并发或数据安全的应用。

例外用MyISAM:仅当系统以读为主、无需事务且追求极简优化时(如静态报表),但已逐渐被InnoDB+缓存或Aria(MariaDB)替代。

MySQL 8.0已标记MyISAM为废弃引擎,仅保留InnoDB作为核心引擎。

MySQL的一条SQL语句的执行过程是怎么样的?

先来看一张总览图
image

主要步骤:客户端发送 SQL → 连接器 → 查询缓存(8.0 已移除)→ 解析器 → 预处理器 → 优化器 → 执行器 → 存储引擎 → 返回结果

使用连接器

通过客户端/服务器通信协议,客户端与 MySQL 建立 TCP 连接。验证用户名、密码、权限。每个连接对应一个线程(MySQL 是线程模型)。

查询缓存(Query Cache)(MySQL 8.0 已移除)

如果开启,会检查是否执行过完全相同的 SQL。
命中则直接返回结果,跳过后续步骤。
但由于命中率低、锁竞争严重,8.0 被废弃(实际在 5.7 起已默认关闭)。

解析器(Parser)

词法分析:将 SQL 字符串拆成 token。
语法分析:构建语法树(AST),检查语法是否正确。比如:select * form userform写错了应该是from)→ 会报错 syntax error

预处理器(Preprocessor)

语义分析:检查表、列是否存在。别名是否合法。展开视图、子查询等。
权限验证:检查用户是否有访问表的权限。

优化器(Optimizer)

这里是核心阶段:决定怎么执行这条 SQL。
主要工作包括:

  • 选择索引(哪个索引最优)。
  • 决定 join 顺序(先查 A 表还是 B 表)。
  • 是否使用覆盖索引、ICP、MRR 等优化。
  • 生成执行计划(Execution Plan)。

你可以用 EXPLAINEXPLAIN FORMAT=JSON 查看优化器的选择。

执行器(Executor)

  • 根据执行计划,调用存储引擎的接口。
  • 逐行读取数据(或通过索引加速)。
  • 执行 WHERE 过滤、排序、聚合、LIMIT 等操作。
  • 对于 UPDATE/DELETE,还会加锁(行锁、间隙锁等)。

存储引擎(如 InnoDB)

这里真正负责数据在磁盘与内存间的读写。
关键操作步骤:

  • 通过 B+ 树索引定位记录。
  • 加载数据页到内存(Buffer Pool)。
  • 加锁(行锁、间隙锁、Next-Key Lock)。
  • undo log(用于事务回滚)。
  • redo log(保证崩溃恢复)。

如果是写操作,还会:

  • 修改内存页 → 标记为脏页。
  • 写入 redo log(WAL 机制)。
  • 后续由后台线程刷盘。

返回结果

  • 对于 SELECT:将结果集封装成协议包返回客户端。
  • 对于 DML:返回影响的行数、自增 ID 等(如INSERT … VALUES …)。

举个例子:

SELECT * FROM user WHERE id = 10

上面这段SQL的执行步骤如下:

  1. 连接器:验证连接和权限。
  2. 解析器:识别出是 SELECT,表是 user,条件是 id = 10。
  3. 预处理器:确认 user 表存在,id 列存在,用户有权限。
  4. 优化器:发现 id 是主键,决定用主键索引,生成执行计划。
  5. 执行器:调用 InnoDB 接口,通过主键索引定位 id=10 的行。
  6. InnoDB:从 Buffer Pool 或磁盘加载数据页,返回行数据。
  7. 执行器:封装结果,返回客户端。

数据库事务机制

数据库的事务机制是数据库管理系统(DBMS)执行过程中的一个逻辑单位,核心目标是通过特定的控制逻辑,确保一组操作要么全部成功执行,要么在发生异常时全部回滚至初始状态,从而维护数据的完整性与业务逻辑的正确性。

事务机制通常遵循ACID原则,这是四个基本特性的缩写:

原子性(Atomicity)

事务中的所有操作要么全部完成,要么全部不完成,不会结束在中间某个点。如果事务中的某个操作失败,整个事务将回滚到执行前的状态,就像这个事务从未执行过一样。

一致性(Consistency)

事务必须保证数据库从一个一致的状态转移到另一个一致的状态。这意味着事务执行的结果必须是数据库完整性约束没有被破坏,所有的规则都必须应用于事务的修改。

隔离性(Isolation)

并发执行的事务之间不会互相影响。一个事务的中间状态对其他事务是不可见的。事务的隔离性防止了多个事务并发执行时由于交叉执行导致数据的不一致。

持久性(Durability)

一旦事务提交,它对数据库的改变就是永久性的,即使系统发生故障,提交的事务结果也不会丢失。