SYN 发出去没人理?500ms 的秘密藏在半连接队列里


SYN 发出去没人理?500ms 的秘密藏在半连接队列里 场景:服务连接间歇超时,重启后好转隔天复发 | 路径:告警 → ss -lnt → nstat → tcpdump → sysctl 上篇讲了 conntrack 超时让中间层偷偷断了连接,这篇来看另一个连接不通的常见场景——TCP SYN

两个 INSERT 同时死了,凶手是间隙锁


两个 INSERT 同时死了,凶手是间隙锁 以下分析基于 MySQL 8.0.32。8.0 的 data_locks 表和 5.7 结构不同,见文中标注。 场景:注册接口每秒报 200 次 DeadlockFoundWhenCommitting,两个并发事务插入同一个手机号 路径:错误日志 → SH

MySQL 没锁升级?一条 UPDATE 怎么把 5 万行全锁了


MySQL 没锁升级?一条 UPDATE 怎么把 5 万行全锁了 以下分析基于 MySQL 8.0.32。5.7 的 data_locks 表结构不同,见文

我写了个转账接口,MySQL 把我一个事务杀了——SHOW ENGINE INNODB STATUS 全拆解


我写了个转账接口,MySQL 把我一个事务杀了——SHOW ENGINE INNODB STATUS 全拆解 场景:两个并发转账事务,各更新两条记录,应用突然报 DeadlockFoundWhenCommitting 路径:SHOW ENGINE INNODB STATUS → LATEST DET

翻到 1000 页慢了 200 倍:OFFSET 不是翻页——是扫了再扔


翻到 1000 页慢了 200 倍:OFFSET 不是翻页——是扫了再扔 场景:分页列表翻到第 5000 页时接口从 50ms 飙升到 10 秒,ORDER BY id LIMIT 100000, 20 路径:EXPLAIN → rows=100020 → OFFSET 的执行本质 → 游标/子查询

少了个引号查询慢 80 倍:MySQL 隐式转换让索引废了


少了个引号查询慢 80 倍:MySQL 隐式转换让索引废了 场景:用户查询手机号接口从 100ms 飙升到 8 秒,phone 字段有索引但 EXPLAIN 显示 type=ALL 路径:EXPLAIN → type=ALL 但 key 列空 → SHOW WARNINGS → CAST(phone

两个 JOIN 列都有索引,MySQL 还是跑了 38 秒


两个 JOIN 列都有索引,MySQL 还是跑了 38 秒 场景:订单明细查询从 200ms 飙升到 38 秒,orders(500 万行)JOIN order_items(2000 万行),两个 JOIN 列都有索引 路径:EXPLAIN → 驱动表 rows 异常 → 统计信息过旧 → STRA

ReentrantReadWriteLock 锁降级:面试背答案的人,写不出这种死锁


ReentrantReadWriteLock 锁降级:面试背答案的人,写不出这种死锁 场景:缓存组件使用 ReentrantReadWriteLock 做读写分离,写锁降级读锁时所有线程卡死 路径:现象 → 复现 → 排查路径 → AQS 源码 + CLH 队列 → 代码审查标记 上篇讲了 Reen

无竞争,换锁后 RT 飙了 15 倍——ReentrantLock 的 JIT 内联陷阱


无竞争,换锁后 RT 飙了 15 倍——ReentrantLock 的 JIT 内联陷阱 场景:8 线程业务服务,接口 RT ~50ms,锁竞争几乎为零。因上游超时需加 tryLock(1s) 降级,把 synchronized 换成 ReentrantLock——上线后 RT 飙到 800ms+。

卡死 3 分钟,jstack 查出 4 条线程在跳探戈


卡死 3 分钟,jstack 查出 4 条线程在跳探戈 场景:转账服务两个账号互相转账,同时请求导致全部线程 BLOCKED,服务 hang 死 路径:现象全景 → 现场还原 → 第一板斧(jstack) → 第二板斧(代码审查) → 第三板斧(lock chain) → 排查地图 上篇讲了 Exe