From 5f1ab4fc7d0efeab22d63c7b70ab6ccd60a44fc3 Mon Sep 17 00:00:00 2001 From: CyC2018 Date: Mon, 2 Nov 2026 01:31:14 +0800 Subject: [PATCH] =?UTF-8?q?Update=20=E5=AD=A6=E4=B9=A0=E8=B7=AF=E7=BA=BF?= =?UTF-8?q?=20-=20=E9=9D=A2=E8=AF=95=E5=86=B2=E5=88=BA.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 同步笔记的更新,调整部分参考要点。 --- notes/学习路线 - 面试冲刺.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/notes/学习路线 - 面试冲刺.md b/notes/学习路线 - 面试冲刺.md index bb023d31..94ba7eba 100644 --- a/notes/学习路线 - 面试冲刺.md +++ b/notes/学习路线 - 面试冲刺.md @@ -128,7 +128,7 @@ 1. CAS 有内存地址 V、预期旧值 A、新值 B 三个操作数,只有 V 等于 A 时才写入 B,由处理器指令保证原子性(x86 上是带 lock 前缀的 cmpxchg);ABA 指值从 A 变成 B 又变回 A,CAS 误以为没变,对无锁栈这类结构有害;用 AtomicStampedReference 给引用加版本号,每次修改加 1。 2. 无锁(Mark Word 末尾 01);轻量级锁(00):线程用 CAS 把 Mark Word 换成指向栈中 Lock Record 的指针,重入只多放一个 Lock Record;重量级锁(10):其它线程 CAS 失败时膨胀为 ObjectMonitor,先自适应自旋,仍抢不到再阻塞;JDK 15 起默认禁用偏向锁,空闲的 ObjectMonitor 会被回收,对象恢复为无锁。 -3. ThreadLocalMap 的 Entry 对 key(ThreadLocal)是弱引用、对 value 是强引用;ThreadLocal 没有其它强引用时 key 被回收变为 null,value 仍被线程的 Map 引用,之后这个线程调用 set()、remove() 或没有直接命中的 get() 时可能顺带清理,线程池中的线程一直存活又没有触发清理时,value 就一直留着;用完在 finally 中调用 remove(),也能避免线程复用时读到上一个请求的值。 +3. ThreadLocalMap 的 Entry 对 key(ThreadLocal)是弱引用、对 value 是强引用;ThreadLocal 没有其它强引用时 key 被回收变为 null,value 仍被线程的 Map 引用,之后这个线程的 get()、set() 在查找途中遇到它,或者新增条目、remove() 删除已有条目时才可能顺带清理,线程池中的线程一直存活又没有触发清理时,value 就一直留着;用完在 finally 中调用 remove(),也能避免线程复用时读到上一个请求的值。 @@ -205,7 +205,7 @@ 1. 未提交读:三种都可能发生;提交读:解决脏读;可重复读:再解决不可重复读,按 SQL 标准仍可能幻读,InnoDB 用 MVCC 和 Next-Key Locks 在很大程度上避免;可串行化:三种都解决,并发度最低。 2. 修改时旧版本写入 Undo Log,经回滚指针连成版本链;ReadView 记录创建时未提交的事务列表、其中最小的 TRX_ID_MIN 和下一个要分配的 TRX_ID_MAX;版本的 TRX_ID 是自己的或小于 MIN 时可见,大于等于 MAX 或仍在列表中时不可见,就沿版本链找上一个版本;提交读每次快照读都新建 ReadView,可重复读在第一次快照读时创建、整个事务复用。 -3. 快照读(普通 SELECT)用 MVCC,复用的 ReadView 看不到其它事务新插入的行;当前读(FOR UPDATE、UPDATE、DELETE)加 Next-Key Lock,即记录锁加前面的间隙锁,其它事务无法往间隙中插入;非唯一索引的等值查询还要锁到下一条记录之间的间隙,唯一索引等值命中已有记录时只锁这一条;同一个事务中快照读和当前读混用时仍会出现幻读。 +3. 快照读(普通 SELECT)用 MVCC,复用的 ReadView 看不到其它事务新插入的行;当前读(FOR UPDATE、UPDATE、DELETE)加 Next-Key Lock,即记录锁加前面的间隙锁,其它事务无法往间隙中插入;非唯一索引的等值查询还要锁到下一条记录之间的间隙,唯一索引等值命中已有记录时只锁这一条;同一个事务中快照读和当前读混用时仍可能出现幻读。 @@ -228,7 +228,7 @@
参考要点 -1. 找:开启慢查询日志(long_query_time 线上调到 1 秒或更低),对比 Rows_examined 与 Rows_sent,用 mysqldumpslow 或 sys.statement_analysis 按语句归类;析:用 Explain、EXPLAIN ANALYZE 看是否索引失效、回表过多、filesort、连接列无索引,Lock_time 大时查锁冲突和长事务;改:例如建覆盖索引后从 237 ms 降到 20 ms,再核对执行计划并评估对写入的影响。 +1. 找:开启慢查询日志(long_query_time 线上常调到 1 秒左右,更小的值只短时间使用),对比 Rows_examined 与 Rows_sent,用 mysqldumpslow 或 sys.statement_analysis 按语句归类;析:用 Explain、EXPLAIN ANALYZE 看是否索引失效、回表过多、filesort、连接列无索引,Lock_time 大时查锁冲突和长事务;改:例如建覆盖索引后从 237 ms 降到 20 ms,再核对执行计划并评估对写入的影响。 2. undo log 由 InnoDB 写,记录旧版本,用于回滚和 MVCC;redo log 由 InnoDB 写,记录对数据页的修改,循环写,用于崩溃恢复;binlog 由 Server 层写,记录行修改或语句,追加写,用于主从复制和按时间点恢复;两阶段提交先写 redo log 进入 prepare,再写 binlog,最后 commit,崩溃后 prepare 的事务在 binlog 中有 Xid 就提交、否则回滚,保证主库数据与 binlog 一致,从库才不会不一致。 3. 跨分片的事务要用分布式事务,跨库连接拆成单表查询后在应用中合并,或用广播表、相同的分片规则避免跨库,自增主键要改用雪花算法等分布式 ID;不带分片键的查询要查所有分片,可用基因法、映射表或按另一维度再存一份;跨分片排序分页时每个分片都要返回前 N 页的数据,改用游标分页;扩容时用双写或订阅 binlog 迁移数据。