MySQL数据库运维——性能优化进阶2️⃣

三.锁机制深度解析

锁类型:共享锁(S)、排他锁(X)、意向锁(IS/IX)、间隙锁(Gap Lock)、临键锁(Next-Key Lock)

死锁产生条件:互斥、持有等待、不可剥夺、循环等待

接下来我们看看InnoDB锁的层次结构

锁的粒度层次

复制代码
1. 表级锁(Table Lock)

- 意向共享锁 IS

- 意向排他锁 IX

- 自增锁 AUTO-INC

2. 行级锁(Record Lock)

- 共享锁 S(SELECT ... LOCK IN SHARE MODE)

- 排他锁 X(UPDATE/DELETE/INSERT)

3. 间隙锁(Gap Lock)

- 锁定索引记录之间的"间隙"

- 防止幻读(Phantom Read)

4. 临键锁(Next-Key Lock)

- Record Lock + Gap Lock 的组合

- 默认在 RR 隔离级别使用

意向锁------用于解决表锁和行锁当然冲突

复制代码
问题场景:

事务 A 想对某行加 X 锁

事务 B 想对整个表加 X 锁(如 DROP TABLE)

如何快速判断是否有冲突?

                          ↓

解决方案:意向锁(Intention Lock)

事务 A 加行锁前,先对表加 IX 锁

事务 B 检查表级锁时,看到 IX 就知道了

"表中有行被锁定了",没有必要遍历所有行

锁兼容性矩阵

Gap Lock 与Next-Key Lock 的精确理解

这样我们就保证了数据的完整性,不让随意修改

接下来我们来分析分析一下Gap Lock的作用,我们通过对比有无Gap Lock来理解

这个就和我们提高隔离级别一样的,加上Gap Lock之后,我们就可以锁住这个数据之间的空隙,不让其他用户的修改我们的表,让我们在二次查询时候以为数据库有报错问题,也就是所谓的幻读

死锁的四个必要条件与检测

在InnoDB里面死锁检测机制:

1.它会使用wait-for graph(等待图)去检测循环

2.检测到死锁之后,会选择Undo量最小的事务作为牺牲品回滚(撤回之前操作)

3.innodb_deadlock_detect:是否开启死锁检测(高并发时关闭可能更好)

4.innodb_lock_wait_timeout:锁等待超时时间

现在我们开始实战一下死锁

建表

事务A,等待事务B

好的,我们发现了一个报错

没错,这就是说遇到了死锁

嗯,不错,全部对上了

四.连接池优化

什么,有没有听说过数据库连接是昂贵资源,其实我之前也不知道,在对比之下会有这么的资源消耗

创建一次数据库连接的代价

  1. TCP 三次握手

  2. MySQL 认证(密码校验、权限验证)

  3. 分配线程/内存资源

  4. 初始化会话状态(变量、字符集等)

总耗时:~ 几十到几百毫秒

对比:SQL 执行可能只需 1ms

MySQL的线程模型

MySQL 经典线程模型(One-Thread-Per-Connection)

sql 复制代码
连接 1 ──→ 线程 1 ──→ 执行 SQL

连接 2 ──→ 线程 2 ──→ 执行 SQL

连接 3 ──→ 线程 3 ──→ 执行 SQL

...

问题:1000 连接 → 1000 线程 → 大量上下文切换

C10K 问题

MySQL 企业版/Percona/MariaDB 的线程池:

sql 复制代码
连接 1 ──┐

连接 2 ──┼──→ 线程池 ──→ 工作线程

连接 3 ──┘ (少量线程)

...

线程池将 SQL 任务分发给有限的工作线程

减少线程切换开销,提高并发能力

我们从就可以发现经典模型它的漏洞是很多的,它是一个一个的连接执行(单一)

而线程池则是将它所有的连接集合在一个线程池里面,直接形成一个工作链(线程),既高效又成本低

连接池的核心设计原理

连接池大小的黄金法则

连接数计算公式(来自 PostgreSQL 作者)

sql 复制代码
连接数 = (核心数 × 2) + 有效磁盘数

例如:8 核 CPU + 1 块 SSD

连接数 = 8 × 2 + 1 = 17

注意:这是数据库端的总连接数上限

如果多个应用服务端连接同一数据库,那么这就需要分摊

这样一看,难道我们的连接数是越大越好么,我们看看下面的案例

sql 复制代码
连接数 = 200 的情况:

CPU 时间片轮转:

每个线程运行 5ms → 切换 → 下一个线程

200 个线程,一轮切换耗时 ~ 10ms

实际 SQL 执行 1ms,但等待 CPU 时间 9ms

CPU 大量时间花在上下文切换上

结果:吞吐量下降,延迟上升,CPU 飙高

这也没有越好,反倒比起前面的还逊色了,所以我们还是需要适当的值即可

连接池参数调优原理

这只是连接池的理论知识,后面我搭建实操项目,实操演练再说

查看连接状态

查看状态及详情

看看有没有连接错误过

非常好,0失误

sql 复制代码
-- 查看当前连接状态

SHOW STATUS LIKE 'Threads_%';

SHOW STATUS LIKE 'Connections';

SHOW STATUS LIKE 'Max_used_connections';

-- 查看当前连接详情

SHOW PROCESSLIST;

SELECT * FROM performance_schema.threads;


-- 计算连接池建议大小(参考公式)

-- 连接数 ≈ (核心数 * 2) + 有效磁盘数

-- 例如 8 核 SSD:8*2+1 = 17 左右

-- 查看连接错误

SHOW STATUS LIKE 'Aborted_%';

哎,学好累,还有好多要学......

目录

三.锁机制深度解析

接下来我们看看InnoDB锁的层次结构

意向锁------用于解决表锁和行锁当然冲突

锁兼容性矩阵

[Gap Lock 与Next-Key Lock 的精确理解](#Gap Lock 与Next-Key Lock 的精确理解)

[接下来我们来分析分析一下Gap Lock的作用,我们通过对比有无Gap Lock来理解](#接下来我们来分析分析一下Gap Lock的作用,我们通过对比有无Gap Lock来理解)

死锁的四个必要条件与检测

在InnoDB里面死锁检测机制:

四.连接池优化

什么,有没有听说过数据库连接是昂贵资源,其实我之前也不知道,在对比之下会有这么的资源消耗

MySQL的线程模型

连接池的核心设计原理

连接池大小的黄金法则

连接池参数调优原理


相关推荐
白露与泡影1 小时前
深入理解MySQL事务隔离级别:MVCC机制与Next-Key Lock如何解决幻读问题?
数据库·mysql
深圳恒讯1 小时前
非洲服务器延迟高吗?实测数据与场景化解读
运维·服务器·前端
志栋智能1 小时前
超自动化安全的实施路径:从单点场景到体系化建设
运维·网络·安全·自动化
嵌入式-老费1 小时前
esp32开发与应用(esp32-s3的usb转串口功能)
linux·运维·服务器
吴声子夜歌1 小时前
SQL经典实例——概述
数据库·sql
布朗克1681 小时前
40 Redis与微服务入门
java·数据库·redis·微服务
无人生还别怕1 小时前
搭建jenkins服务并接入openldap认证
运维·jenkins
hai3152475431 小时前
九章编程法 · 字典引擎【0/1拓扑步进 · 矩阵压缩·终极封版】
人工智能·数学建模·性能优化·动态规划·代码复审·傅立叶分析·极限编程