<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>MySQL on GYM</title><link>https://oooooomy.cloud/tags/mysql/</link><description>Recent content in MySQL on GYM</description><generator>Hugo</generator><language>en-us</language><copyright>© ccdgr</copyright><lastBuildDate>Sat, 15 Mar 2025 10:30:00 +0800</lastBuildDate><atom:link href="https://oooooomy.cloud/tags/mysql/index.xml" rel="self" type="application/rss+xml"/><item><title>校车预定平台演进：从 MySQL 裸写到 Redis + RabbitMQ 高并发架构</title><link>https://oooooomy.cloud/posts/go/shuttle/</link><pubDate>Sat, 15 Mar 2025 10:30:00 +0800</pubDate><guid>https://oooooomy.cloud/posts/go/shuttle/</guid><description>&lt;blockquote&gt;
&lt;p&gt;做这个项目的初衷不是&amp;quot;写一个能用的系统&amp;quot;，而是搞清楚一件事：中间件到底在解决什么问题？每一个组件引入之前，先把不引入的代价量化出来。所以才有了一版一版的刻意劣化测试。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="项目背景"&gt;项目背景&lt;/h2&gt;
&lt;p&gt;独立开发的西工大校车预定平台，技术栈 Go + Gin + Gorm + MySQL，后来逐步引入 Redis、RabbitMQ。核心业务是座位预约、库存扣减与订单管理。&lt;/p&gt;
&lt;p&gt;面向的并发场景：热门班次开放预约的瞬间，几千人同时抢几十个座位。&lt;/p&gt;
&lt;p&gt;我的思路是：&lt;strong&gt;先写一个&amp;quot;能跑但没做任何优化&amp;quot;的版本，压测，找到瓶颈，加一个组件，再压测，直到瓶颈消失。&lt;/strong&gt; 每一步都带数据。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="前置准备基准环境与测试工具"&gt;前置准备：基准环境与测试工具&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;硬件：Apple M4
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;MySQL：Docker 1核1G，单实例
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Redis：Docker 单实例
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;JMeter：threads=2000, ramp-up=1s, loop=1
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;网络延迟模拟：tc qdisc add dev lo0 root netem delay 5ms
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;测试接口：&lt;code&gt;POST /api/order&lt;/code&gt;，包含查库存、扣库存、插入订单三步操作。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="为什么需要模拟网络延迟"&gt;为什么需要模拟网络延迟&lt;/h2&gt;
&lt;p&gt;第一个压测在本地回环上跑，MySQL 1核1G，2000 并发，结果 TPS 400+，0 错误。&lt;/p&gt;
&lt;p&gt;但这是假象。&lt;strong&gt;生产环境中应用服务器到数据库服务器至少 2-5ms 的网络 RTT。&lt;/strong&gt; 本地走 &lt;code&gt;localhost&lt;/code&gt; 延迟为 0，意味着每个 SQL 操作节省了 5-10ms。一个请求有 3 次 SQL（查库存 + 更新 + 插入），本地比生产少了至少 15ms 的等待。2000 并发时，15ms × 2000 ÷ 1s ≈ 30 个并发一直在&amp;quot;多出来&amp;quot;的等待里打转。&lt;/p&gt;</description></item><item><title>MySQL InnoDB 核心机制：MVCC、索引、事务、锁与 SQL 优化</title><link>https://oooooomy.cloud/posts/mysql/innodb/</link><pubDate>Fri, 27 Dec 2024 15:30:00 +0800</pubDate><guid>https://oooooomy.cloud/posts/mysql/innodb/</guid><description>&lt;blockquote&gt;
&lt;p&gt;面试必问，生产必用。把 InnoDB 的几个核心机制串起来理一遍。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="innodb-架构概览"&gt;InnoDB 架构概览&lt;/h2&gt;
&lt;p&gt;InnoDB 是 MySQL 默认存储引擎，核心特性：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;B+Tree 索引&lt;/strong&gt; — 主键索引（聚簇） + 二级索引&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MVCC&lt;/strong&gt; — 多版本并发控制，读不阻塞写&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;行级锁&lt;/strong&gt; — Record Lock / Gap Lock / Next-Key Lock&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;事务&lt;/strong&gt; — ACID，通过 undo log + redo log 保证&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Buffer Pool&lt;/strong&gt; — 内存缓冲池，缓存数据页和索引页&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;┌─────────────────────────────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ 客户端连接 │
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;└─────────────────┬───────────────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ▼
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;┌─────────────────────────────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ MySQL Server 层 │
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ 连接器 → 分析器 → 优化器 → 执行器 │
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;└─────────────────┬───────────────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ▼
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;┌─────────────────────────────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ InnoDB 存储引擎 │
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ ┌──────────┐ ┌──────────┐ │
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ │Buffer Pool│ │ Redo Log│ │
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ └──────────┘ └──────────┘ │
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ ┌──────────┐ ┌──────────┐ │
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ │ Undo Log │ │ 锁管理 │ │
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ └──────────┘ └──────────┘ │
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;└─────────────────────────────────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="btree-索引"&gt;B+Tree 索引&lt;/h2&gt;
&lt;h3 id="为什么是-btree"&gt;为什么是 B+Tree&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;数据结构&lt;/th&gt;
					&lt;th&gt;特点&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;二叉搜索树&lt;/td&gt;
					&lt;td&gt;可能退化成链表，高度太高&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;红黑树&lt;/td&gt;
					&lt;td&gt;二叉，高度依然大，IO 次数多&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;B-Tree&lt;/td&gt;
					&lt;td&gt;多路平衡，非叶子节点也存数据&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;B+Tree&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;数据只存叶子节点，叶子形成有序链表&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;B+Tree 的优势：&lt;/p&gt;</description></item></channel></rss>