<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>锁 on 追风笔记</title><link>https://4f0a9a3b.wangpeng.pages.dev/tags/%E9%94%81/</link><description>Recent content in 锁 on 追风笔记</description><generator>Hugo</generator><language>zh</language><lastBuildDate>Tue, 25 Aug 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://4f0a9a3b.wangpeng.pages.dev/tags/%E9%94%81/index.xml" rel="self" type="application/rss+xml"/><item><title>MySQL 事务与锁机制</title><link>https://4f0a9a3b.wangpeng.pages.dev/tech/mysql/transaction-lock/</link><pubDate>Tue, 25 Aug 2026 00:00:00 +0000</pubDate><guid>https://4f0a9a3b.wangpeng.pages.dev/tech/mysql/transaction-lock/</guid><description>&lt;p&gt;并发场景下，事务与锁共同保证了数据的一致性。InnoDB 通过 MVCC 与锁的协同，在性能与隔离性之间取得平衡。&lt;/p&gt;&#10;&lt;h2 id="acid-与隔离级别"&gt;ACID 与隔离级别&#10;&lt;/h2&gt;&#10;&lt;p&gt;事务的 ACID 由不同机制保障：原子性靠 undo log，持久性靠 redo log，隔离性靠 MVCC 与锁，一致性是最终目标。&lt;/p&gt;&#10;&lt;p&gt;SQL 标准定义四种隔离级别，InnoDB 默认 &lt;code&gt;REPEATABLE READ&lt;/code&gt;：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;READ UNCOMMITTED：可能脏读&lt;/li&gt;&#10;&lt;li&gt;READ COMMITTED：避免脏读，可能不可重复读&lt;/li&gt;&#10;&lt;li&gt;REPEATABLE READ：避免不可重复读（InnoDB 额外避免幻读）&lt;/li&gt;&#10;&lt;li&gt;SERIALIZABLE：完全串行，性能最低&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="mvcc-与日志"&gt;MVCC 与日志&#10;&lt;/h2&gt;&#10;&lt;p&gt;MVCC（多版本并发控制）让读不加锁、读写不阻塞。每行记录隐含 &lt;code&gt;trx_id&lt;/code&gt; 与 &lt;code&gt;roll_pointer&lt;/code&gt;，通过 undo log 构建历史版本，配合 ReadView 判断某版本对当前事务是否可见。&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;undo log&lt;/strong&gt;：记录数据修改前的镜像，用于回滚与构建旧版本。&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;redo log&lt;/strong&gt;：记录物理页修改，保证崩溃后已提交事务不丢失（WAL 机制）。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="行锁间隙锁与-next-key-lock"&gt;行锁、间隙锁与 Next-Key Lock&#10;&lt;/h2&gt;&#10;&lt;p&gt;InnoDB 默认使用行锁，但「锁的是索引记录」而非行本身。在 &lt;code&gt;REPEATABLE READ&lt;/code&gt; 下，为解决幻读引入：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;行锁（Record Lock）&lt;/strong&gt;：锁住具体索引记录。&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;间隙锁（Gap Lock）&lt;/strong&gt;：锁住索引记录之间的间隙，阻止插入。&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Next-Key Lock&lt;/strong&gt;：行锁 + 间隙锁，锁定左开右闭的区间。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;div class="td-code td-code--untitled" id="td-code-634a084d-fence-0" data-td-code data-td-code-auto-id&#10; data-td-language="sql" data-td-line-count="2"&gt;&#10; &lt;div class="td-code__viewport" id="td-code-634a084d-fence-0-viewport" data-td-code-viewport&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- 在 (10, 20] 区间加 Next-Key Lock，阻止其他事务插入 id=15&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;WHERE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;BETWEEN&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AND&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;FOR&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;UPDATE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;h2 id="死锁成因与排查"&gt;死锁成因与排查&#10;&lt;/h2&gt;&#10;&lt;p&gt;死锁通常由两个事务以相反顺序获取锁引起。排查手段：&lt;/p&gt;</description></item></channel></rss>