(Mysql)Mysql八股大杂烩

1. 锁机制

1.1 锁的作用

  • 保证数据一致性,防止并发操作导致的数据冲突

  • 控制并发操作顺序

  • 提高性能(合理使用锁比死锁和冲突少)

1.2 锁的分类

按作用对象
类型 作用对象 特点
表锁 整张表 简单、开销低,但并发能力低
行锁 单条记录 并发能力高,但开销大,需要索引支持
按锁类型
类型 描述 SQL 示例
共享锁(S) 允许读,不允许写 SELECT ... LOCK IN SHARE MODE
排他锁(X) 独占读写 UPDATE ... 或 SELECT ... FOR UPDATE
按使用方式
  • 显式锁 :用户手动加锁 (SELECT ... FOR UPDATE)

  • 隐式锁:InnoDB 自动加锁(UPDATE/DELETE 自动加 X 锁)


1.3 InnoDB 行锁机制

锁类型 锁对象 作用 场景
记录锁(Record Lock) 单条索引记录 防止并发修改同一行 UPDATE / SELECT ... FOR UPDATE
间隙锁(Gap Lock) 索引记录间的空隙 防止幻读(插入新行) 范围查询 + 更新
临键锁(Next-Key Lock) 记录 + 前后空隙 防止幻读 + 并发修改 InnoDB 默认 REPEATABLE READ 范围查询

例子:

SELECT * FROM users WHERE id BETWEEN 2 AND 4 FOR UPDATE;
锁住 id=3 记录 + id=2~4 的间隙


1.4 幻读(Phantom Read)

  • 定义:同一事务内相同条件查询两次,第二次出现新增/消失行

  • 出现原因:事务 A 查询条件范围内,事务 B 插入新行

  • 防止方法 :InnoDB 使用 临键锁(记录锁 + 间隙锁)

  • 示例:

-- 事务A SELECT * FROM users WHERE age BETWEEN 20 AND 30 FOR UPDATE; -- 事务B INSERT INTO users(id, age) VALUES(4, 22); -- 阻塞


1.5 事务隔离级别与锁关系

隔离级别 锁行为 可见现象
READ UNCOMMITTED 不加锁 脏读
READ COMMITTED 写加 X 锁,读不加锁 无脏读,可不可重复读
REPEATABLE READ 快照读 + 写加 X 锁 防脏读、不可重复读,幻读通过行锁/间隙锁避免
SERIALIZABLE 读加 S 锁,写加 X 锁 最严格,顺序执行,性能低

1.6 死锁与优化

死锁产生:

  • 两个事务互相等待对方持有的锁

优化技巧:

  1. 统一加锁顺序

  2. 缩短事务执行时间

  3. 使用索引加行锁,避免全表扫描

  4. 使用低隔离级别读(READ COMMITTED)


2. MVCC(多版本并发控制)

2.1 概念

事务读取自己的快照,读不阻塞写,写不阻塞读,提高并发性能

2.2 原理

  • 每行记录有隐藏字段:trx_id、roll_pointer

  • 事务只读取自己快照的版本

  • 写操作生成新版本,旧版本存在 undo log

2.3 支持隔离级别

隔离级别 MVCC 行为
READ COMMITTED 每次查询读取最新提交版本
REPEATABLE READ 事务启动时快照,多次查询读取同一版本
幻读 临键锁防止幻读

2.4 示例

复制代码

-- 事务A START TRANSACTION; SELECT * FROM users WHERE age > 20; -- 事务B UPDATE users SET age = 30 WHERE id = 1; COMMIT; -- 事务A再次查询仍看到旧版本


3. B+ 树与索引

3.1 B+ 树概念

  • 平衡树,所有叶子节点在同一层

  • 内部节点只存索引,叶子节点存数据

  • 叶子节点链表连接,支持范围查询

3.2 MySQL 为什么用 B+ 树

  1. 查找高效:O(log n),树高低,磁盘 I/O 少

  2. 范围查询快:叶子链表顺序扫描

  3. 排序快 :叶子节点有序支持 ORDER BY

  4. 插入删除稳定:节点分裂/合并保持平衡

  5. 磁盘友好:内部节点存索引,可批量读入

3.3 聚簇索引 vs 辅助索引

  • 聚簇索引(Primary Key):叶子节点存完整行

  • 辅助索引(Secondary Key):叶子节点存主键,通过主键查聚簇索引

3.4 深分页问题

  • OFFSET 深分页需要遍历大量叶子节点链表

  • 解决方案:

    1. Keyset 分页(WHERE id > 上一页最后 id)

    2. 分区/分表

    3. 缓存或搜索引擎


4. 总结

知识点 核心理解
锁机制 表锁/行锁、共享锁/排他锁、临键锁防幻读
幻读 范围查询被其他事务插入新行导致结果变化
MVCC 多版本控制,提高并发,读不阻塞写
B+ 树 高效查找、范围查询、排序,叶子节点链表支持顺序扫描
深分页优化 Keyset 分页 + 分区/分表 + 缓存

💡 一句话面试总结:

MySQL 通过 B+ 树索引、MVCC、多种行锁和临键锁,实现高并发、高效查找和范围查询,同时防止脏读、不可重复读和幻读,深分页需要 Keyset 优化。

相关推荐
牧瀬クリスだ2 分钟前
Redis Hash实战:高效存储对象与购物车
java·数据库·redis·算法·哈希算法
A小码哥6 分钟前
【外】水星3号实测 1068 token 每秒靠谱吗
数据库
qq_4523962324 分钟前
第六篇:《SQL 优化的艺术:从慢查询到毫秒级响应》
数据库·sql
ShineWinsu33 分钟前
对于Qt:QWidget通用属性的解析—上
数据库·qt·microsoft·面试·gui·属性·qwidget
程序员塔塔喵36 分钟前
【MySQL篇|第十篇】深分页问题
数据库·oracle·深分页问题
JavaPub-rodert1 小时前
王仕宇分享:把 MySQL 排障做成 AI Agent,慢 SQL、锁等待、连接数和主从异常都能自动查
人工智能·sql·mysql
ClouGence1 小时前
SQL 效率天花板!开源 CloudDM,自带一站式 AI SQL 助手
数据库·sql·开源
qq_452396232 小时前
第七篇:《事务与并发:MVCC、隔离级别与锁机制》
sql
Decay__2 小时前
附-01 · MySQL 压测与容量规划 —— sysbench 基准测试、容量评估与参数基线
运维·数据库·sql·mysql·架构
这个DBA有点耶2 小时前
主从切换报成功,业务却写不进去——数据层脑裂与应用层连接残留的两类假成功
数据库·架构·dba