MySQL 事务 ACID

MySQL 事务 ACID


MySQL 事务的 ACID

一、ACID 是什么

特性 英文 含义
A Atomicity 原子性
C Consistency 一致性
I Isolation 隔离性
D Durability 持久性

二、Redo Log 和 Undo Log

日志 类型 作用
Redo Log 物理日志 保证持久性
Undo Log 逻辑日志 保证原子性 + MVCC

三、Redo Log

核心思想

使用:

  • WAL(Write Ahead Log)

原则:

  • 先写日志
  • 再写磁盘

四、Undo Log

作用:

  • 回滚事务
  • MVCC 多版本控制

Redo Log 刷盘策略


innodb_flush_log_at_trx_commit

配置值 刷盘策略 安全性 性能
1 每次提交立即刷盘 最高 最低
0 每秒刷盘 最低 最高
2 每次提交写 OS Cache 折中 折中

面试回答

  • 1 最安全
  • 0 性能最好
  • 2 是平衡方案

生产环境:

  • 一般使用 1

MySQL 隔离级别


MySQL 四种隔离级别

隔离级别 英文 问题
读未提交 Read Uncommitted 会脏读
读已提交 Read Committed 会不可重复读
可重复读 Repeatable Read 默认级别
串行化 Serializable 性能最差

MySQL 默认隔离级别

text 复制代码
Repeatable Read

即:

  • 可重复读

脏读、不可重复读、幻读


一、脏读

定义:

  • 读到未提交数据

二、不可重复读

定义:

  • 两次查询结果不同

原因:

  • 中间被其他事务修改

三、幻读

定义:

  • 两次查询记录数量不同

原因:

  • 中间有插入/删除

幻读解决方案


InnoDB 如何解决幻读

一、快照读

使用:

  • MVCC

看到:

  • 历史快照

二、当前读

使用:

  • 间隙锁(Gap Lock)

作用:

  • 锁定范围
  • 防止插入

三、总结

InnoDB:

  • MVCC + 间隙锁

解决:

  • 幻读问题

四、补充

串行化级别:

  • 也能解决幻读

缺点:

  • 性能差

MVCC


MVCC 原理

一、核心思想

MVCC:

text 复制代码
Multi-Version Concurrency Control

即:

  • 多版本并发控制

二、Read View 可见性规则

可见

  • 小于最小活跃事务 ID
  • 已提交事务

不可见

  • 活跃事务列表中的事务
  • 大于当前事务 ID

三、简单理解

可见:

  • 当前事务开始前已经提交的数据

不可见:

  • 未提交数据
  • 未来事务数据

悲观锁 vs 乐观锁


一、悲观锁

核心思想

认为:

  • 一定会发生冲突

所以:

  • 先加锁
  • 再操作

典型实现

Java

  • synchronized
  • ReentrantLock

MySQL

sql 复制代码
SELECT ... FOR UPDATE

优缺点

优点

  • 强一致性

缺点

  • 性能差
  • 可能死锁

二、乐观锁

核心思想

认为:

  • 冲突概率低

所以:

  • 不加锁
  • 更新时检查版本

典型实现

  • CAS
  • 版本号机制

优缺点

优点

  • 高并发
  • 无死锁

缺点

  • 冲突多时大量重试

三、选择原则

场景 推荐方案
写多读少 悲观锁
读多写少 乐观锁

实际案例

场景 方案
库存扣减 悲观锁
用户信息更新 乐观锁

GC 问题排查


GC 导致接口超时排查

第一步:确认是否是 GC

观察:

  • 接口超时是否周期性
  • CPU 是否飙升
  • 是否频繁 GC

第二步:查看 GC 情况

命令:

bash 复制代码
jstat -gc

重点:

  • Full GC 次数
  • Full GC 耗时

第三步:分析 GC 日志

排查:

  • 内存不足
  • System.gc()
  • 元空间溢出

第四步:分析内存泄漏

生成 dump:

bash 复制代码
jmap

分析工具:

  • MAT

查看:

  • 哪些对象占用内存最多

第五步:定位代码问题

常见问题:

  • ThreadLocal 未清理
  • 无界缓存
  • 大对象频繁创建

常见优化方案

  • 调整堆内存
  • 优化 GC 参数
  • 修复内存泄漏
  • 提前预热

TCP 三次握手


TCP 三次握手流程

第一次

客户端发送:

text 复制代码
SYN

作用:

  • 请求建立连接
  • 发送初始序列号

第二次

服务端回复:

text 复制代码
SYN + ACK

作用:

  • 确认客户端请求
  • 发送自己的序列号

第三次

客户端发送:

text 复制代码
ACK

作用:

  • 确认收到服务端响应

三次握手作用

一、同步序列号

保证:

  • 后续数据有序传输

二、防止历史连接

避免:

  • 旧 SYN 导致资源浪费

为什么不能两次握手

问题:

  • 服务端无法确认客户端是否收到 ACK

结果:

  • 可能建立无效连接

TCP 四次挥手


TCP 四次挥手流程

第一次

客户端发送:

text 复制代码
FIN

表示:

  • 不再发送数据

第二次

服务端回复:

text 复制代码
ACK

表示:

  • 收到关闭请求

第三次

服务端发送:

text 复制代码
FIN

表示:

  • 数据发送完成

第四次

客户端回复:

text 复制代码
ACK

然后进入:

text 复制代码
TIME_WAIT

为什么是四次挥手

原因:

  • TCP 是全双工

特点:

  • 两个方向独立关闭

为什么不能三次

因为:

  • 服务端收到 FIN 时
  • 可能还有数据没发送完

所以:

  • ACK 和 FIN 不能合并

TIME_WAIT


TIME_WAIT 作用

一、保证最后 ACK 到达

如果 ACK 丢失:

  • 服务端会重发 FIN

客户端必须还能响应。


二、防止旧报文影响新连接

等待:

text 复制代码
2MSL

保证:

  • 网络中的旧报文全部消失

为什么等待 2MSL

第一原因

确保:

  • 服务端能收到最后 ACK

第二原因

防止:

  • 延迟报文污染新连接

数据量扩大 1000 倍


数据量暴增后的优化

一、数据库

核心方案

  • 分库分表
  • 读写分离

二、拆分方式

垂直拆分

按业务拆:

  • 用户库
  • 订单库

水平拆分

按:

text 复制代码
userId

进行分片。


三、缓存优化

Redis Cluster

作用:

  • 数据分片

多级缓存

架构:

text 复制代码
Caffeine → Redis → MySQL

四、应用层

水平扩容

使用:

  • K8s
  • HPA 自动伸缩

GC 优化

方案:

  • 减少对象创建
  • 提前处理大对象

五、消息队列

优化:

  • 增加分区
  • 增加消费者

避免:

  • 消息积压

六、架构演进步骤

阶段 方案
第一阶段 SQL 优化 + 垂直扩容
第二阶段 读写分离 + 缓存
第三阶段 分库分表
第四阶段 微服务 + 异步化

2 亿数据查询优化


2 亿数据为什么还能查得快

一、核心原因

B+Tree 索引

特点:

  • 高度低
  • 查询磁盘 IO 少

二、InnoDB 理论能力

支持:

text 复制代码
16 亿

级数据。

索引查询:

  • 只需 3~4 次磁盘 IO

三、常见问题

1)深度分页

错误方案:

sql 复制代码
LIMIT 1000000, 20

优化方案

使用:

sql 复制代码
WHERE id > last_id

即:

  • 游标分页

2)回表过多

问题:

  • 先查索引
  • 再查数据页

解决方案

使用:

  • 覆盖索引

3)COUNT 慢

解决:

  • 汇总表
  • 从库统计

4)索引维护成本高

经验:

  • 超过 5000 万建议分表

四、分表建议

推荐数量

text 复制代码
64 ~ 128

张表。


每张表数据量

text 复制代码
150万 ~ 300万

最佳。


五、复杂查询优化

方案:

  • Elasticsearch
  • ClickHouse

六、生产经验

优化后:

  • 简单查询几十毫秒

长期方案:

  • 分表更稳妥
相关推荐
狼爷2 小时前
百万QPS多场次秒杀系统架构全解:解耦设计、防超卖、流量防护体系
后端·架构
ruxingli3 小时前
Golang iota详解
开发语言·后端·golang
前端环境观察室3 小时前
别只看 task success:AI Agent 浏览器自动化真正要补的是环境证据链
前端·后端
浩风祭月3 小时前
把 Docker 镜像从 2GB 瘦身到 180MB,AI 帮我找到了那些看不见的“脂肪”
后端·ai编程
暗冰ཏོ4 小时前
Go 语言从入门到后端项目实战完整指南
开发语言·后端·golang·go·go语言
霸道流氓气质5 小时前
Windows批处理脚本完整指南:可移植的交互式SpringBoot项目管理
windows·spring boot·后端
小杍随笔5 小时前
【Rust 工具链管理完全指南:rustup toolchain 命令实战详解】
开发语言·后端·rust
还是鼠鼠5 小时前
AI掘金头条新闻系统 (Toutiao News)-获取用户信息
后端·python·mysql·fastapi·web
BingoGo5 小时前
免费可商用 PHP 管理后台 CatchAdmin V5.3.1 发布 后台打包直降 5s 内
后端·php