- 博客(180)
- 收藏
- 关注
原创 第 15 篇 分库分表:什么时候该拆,怎么拆
分库分表是数据库架构里最重的一张牌,一旦打出去,查询跨分片、事务跨分片、JOIN 跨分片的问题会从此如影随形。绝大多数的分库分表做早了,付出了巨大的工程成本,却只是单机 MySQL + 合理索引就能扛住的量。解决的是单行过宽导致的内存压力问题,不解决行数多的问题。真的要拆,分片键的选择决定未来所有跨分片痛点的大小——选能覆盖绝大多数查询、分布均匀、不可变的字段。:按业务模块把不同的表拆到不同的数据库(甚至不同的 MySQL 实例)。解决的是多个业务模块共用一个数据库导致的资源竞争问题。和执行计划都对不上。
2026-08-05 22:42:45
20
原创 第 14 篇 主从复制与读写分离:binlog 格式、主从延迟的成因与应对
主从复制是 MySQL 高可用的基石,但它从来不是"零延迟"的魔法。先说清它的口径:这个值是"SQL Thread 正在回放的那个事件、在主库上的写入时间"与"从库当前时间"之差。主从延迟80%的根因是大事务或从库单线程回放——开启 LOGICAL_CLOCK 并行复制、把大事务拆小,是降延迟最有效的两把刀。:半同步保证的是"从库收到 binlog",不是"从库已回放"——主库宕机时从库可能还没回放完最后几个事务。——主库的所有变更都会写入 binlog,从库把这些日志拉过来回放,从而保持数据一致。
2026-08-05 22:38:42
21
原创 第 13 篇 高频SQL优化:深分页、count(*)、filesort 与 join 算法
优化 SQL 不需要玄学——每一种"慢"背后都有明确的物理原因。BNL 靠给被驱动表的关联字段加索引——四类慢 SQL,四个固定解法,没有玄学。所以 5.7 里真正存在的只有 NLJ(有索引)和 BNL(无索引)两种。):索引虽然有序,但每行都要回表取其他列,随机 IO 的代价常常高于"全表扫描 + 排序",优化器很可能。:本篇 1~4 节的示例都以"表里有百万行"为背景来讲原理,直接在共用的 6 行。你要的是10行,但存储引擎扫了100010行。两次 IO,sort_buffer 小,大表适用。
2026-08-05 22:34:51
16
原创 第 12 篇 慢查询定位全流程:从慢日志到 optimizer_trace
而是"不太慢但执行了10万次"的那条。没有人能靠"调参数"治好慢查询——参数调整只能让快的更快,找不到那几条慢 SQL,系统永远跑不起来。本篇给一套固定的四步流程:从"系统卡了"到"定位到那一条 SQL 的哪一步慢”,全程可操作。上面的例子:表里只有100行,全表扫描 cost=22,索引扫描 cost=108——优化器选全表扫描完全合理。如果你修改了这个值但慢日志里还是看不到预期的 SQL,检查是不是老连接在跑。慢查询日志是定位慢 SQL 的起点,记录执行时间超过阈值的所有 SQL。
2026-08-05 22:30:50
14
原创 第 10 篇 锁的全景图:表锁、行锁、间隙锁与 Next-Key Lock 加锁规则
当某个区间的 Next-Key Lock 被加上,该区间内的间隙会被锁住(阻止 INSERT),对应的行记录也被锁住(阻止 UPDATE/DELETE)。,会一直访问到第一个不满足条件的值,并对该值加 Next-Key Lock(而不是退化为间隙锁)。Next-Key Lock = 记录锁 + 间隙锁,是防止幻读的武器,也是死锁的温床。这是最重要的一句话:InnoDB 的行锁加在索引上,如果查询用不上索引(全表扫描),行锁就退化为"锁住扫描过的所有索引记录",极端情况等于锁全表。标准答案不是 1 行。
2026-08-05 22:16:52
23
原创 第 09 篇 快照读 vs 当前读:为什么 RR 下依然可能出现幻读
同一事务内,两次相同条件的当前读,后一次出现了前一次不存在的行。当前读:幻读讨论的是当前读场景,不是快照读行数变化:是新行的出现(或消失),不是已有行的数据变化(那是不可重复读)问题两次读的变化产生原因不可重复读同一行的字段值不同其他事务 UPDATE/DELETE 了该行幻读同一范围的行数不同其他事务 INSERT 了新行。
2026-08-05 22:13:28
851
原创 第 08 篇 隔离级别与 MVCC:一致性视图究竟在什么时刻生成
同一个事务里执行两次相同的SELECT,中间别人改了数据并提交了。你看到的是旧值——整个事务内数据都没变。这个"看到旧值"的能力,既不是锁,也不是任何黑魔法,而是 undo log 加上一个叫的快照。搞清楚 ReadView 在什么时刻生成、怎么判断哪个版本可见,就搞清楚了 REPEATABLE READ 和 READ COMMITTED 的全部区别。这篇从头推导,不背结论。
2026-08-05 22:09:06
70
原创 第 07 篇 EXPLAIN 逐字段精读 + 联合索引字段顺序怎么定
原理来自第 06 篇场景 8:范围条件之后的列无法参与索引定位。场景t_order表,高频查询是按user_id过滤 +status过滤 +created_at范围查询,最终按created_at应该怎么建索引?-- 错误顺序:范围列(created_at)放中间-- created_at 后 status 用不上,且 ORDER BY created_at 也可能触发 filesort-- 正确顺序:等值列在前,范围列在后-- 先测错误顺序。
2026-08-05 22:06:34
227
原创 第 06 篇 索引为什么突然失效了:8 种真实场景逐一验证
索引失效从来不是 MySQL 的 bug,而是两类原因:要么 SQL 写法破坏了 B+ 树的有序性,要么优化器算出走索引的成本更高,主动放弃。索引失效不是 MySQL 的 bug,绝大多数是"破坏了索引的有序性"(运算、函数、隐式转换、前缀模糊、跨范围列)或"优化器认为不划算"(方案二值得记住:5.7 的虚拟列不占数据空间(VIRTUAL 只在读取时计算),但可以建索引,等价于 8.0 函数索引的效果。的(NULL 值在 B+ 树中被统一排在最前面,能定位),这点和很多"索引失效口诀"里的说法相反。
2026-08-05 22:02:38
21
原创 第 05 篇 聚簇索引与二级索引:回表、覆盖索引与自增主键之争
(36 个 ASCII 字符 + 1 字节长度前缀,utf8mb4 只是把上限抬到 144 字节,不会把已存的短字符串撑大),差距约 4.6 倍。不仅无法从应用层控制插入顺序,也让所有二级索引的叶子节点存储 6 字节行 ID 而非业务主键,语义模糊,排查困难。:每次插入在 B+ 树的随机位置,频繁触发页分裂,分裂后双方各 ≈ 50% 满载,空间利用率差,都存在于某个索引的叶子节点中时(索引列 + 主键列),就无需回表,称为覆盖索引。:从根页出发,按主键逐层向下,到达叶子节点即可取到完整行,
2026-08-05 21:59:52
26
原创 第 04 篇 为什么是 B+ 树:从磁盘 IO 反推数据结构选型
(INSERT 导致):向已满的页插入新记录时,InnoDB 把该页拆成两半,各保留约 50% 的数据,并向父节点插入新的分隔键。:非叶子节点也存数据,导致每个节点能放的键数量少(单页 16KB 被行数据撑满),扇出(fan-out,一个节点的子节点数量)小,树依然太高。自增主键的插入总是追加到最右叶子节点,只有在叶子满时才触发分裂,且分裂后原页仍接近满载,空间利用率高。,每次 IO 读取一个节点。(DELETE 导致):当相邻页的数据量都低于 50% 时,InnoDB 会把它们合并成一页,释放另一页。
2026-08-05 21:57:32
40
原创 第 03 篇 InnoDB 的数据到底存在哪:从表空间到行格式
Page Directory 是一个稀疏索引,每 4~8 条记录设一个槽(Slot),槽内存该组最后一行的地址。但只有理解了存储层,你才能真正看懂 B+ 树的高度、索引大小的计算、间隙锁的加锁范围,以及"为什么 OPTIMIZE TABLE 能让查询变快"。如果值是 NULL,不在行内存储实际数据,只在位图中标记,节省空间。等变长类型,InnoDB 在行头记录各变长列的实际字节数,顺序是逆向的(从后往前)。理解了这个数字,B+ 树的高度、索引的大小、间隙锁的范围都会变得直观。文件为什么一点没变小?
2026-08-05 21:54:46
30
原创 第 02 篇 一条 UPDATE 语句是怎么执行的:redo log、undo log 与两阶段提交
注意这两个数字量纲不同:IOPS 是"每秒多少次独立寻址",吞吐是"每秒多少字节"——顺序写快,本质是省掉了寻道,而不是"IOPS 变高了"。无主键表定位行只能靠全字段比对,前镜像仍要记录整行,MINIMAL 省不下来——这也是"每张表都必须有主键"的又一个理由。这个判定逻辑是 InnoDB 崩溃恢复的核心算法,理解了它,就理解了为什么 MySQL 在意外断电后数据不会乱。日志写入是顺序 IO,速度快;数据页的刷盘可以合并多次修改,变成批量写,均摊了随机 IO 的开销。,undo log 记录的是。
2026-08-05 21:51:19
564
原创 第 01 篇 一条 SELECT 语句是怎么执行的
很多人在面试中被问到"MySQL 的架构"时,只能答出"有存储引擎层",却说不清楚一条查询在 Server 层内部究竟经历了什么。:很多人以为优化器会"自动优化"任何写法,实际上优化器只能在 SQL 语义不变的前提下做有限的变换。语法树构建完成后,进入优化器。优化器是 MySQL 里最"神秘"的组件——它会在多个可选的执行方案里选出"成本最低"的那一个。如果表上有索引,执行器会调用"从索引起点取第一条满足条件的行"接口,减少扫描量。,可以在不断开连接的前提下重置连接状态,释放内存,适合在连接池中定期调用。
2026-08-05 21:45:13
32
原创 深度剖析 MySQL 并发控制:从 MVCC 的“时光机“到InnoDB锁机制的“防御网“
本文深入剖析MySQL InnoDB引擎的并发控制机制,重点解析MVCC和锁机制在高并发环境下的协同工作原理。通过实验案例演示,详细阐释MVCC的"时光机"特性:基于隐藏字段、Undo Log版本链和ReadView实现快照读,使读操作不受写操作阻塞。文章系统性地介绍了ReadView的可见性判定算法,并通过版本链遍历实例展示不同事务状态下的数据可见性。同时指出RC与RR隔离级别的本质区别在于ReadView生成时机的不同。最后通过统一案例环境为后续探讨InnoDB锁机制奠定基础,为开发者构建高并发数据模型
2026-08-03 01:08:06
517
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅