news 2026/9/6 8:18:03

10-数据库学习笔记(数据结构中的锁机制)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
10-数据库学习笔记(数据结构中的锁机制)

一.索引并发控制整体技术背景

1.技术诞生背景

B + 树、哈希表这些索引结构,默认都是「只有一个人操作」的单线程理想情况—— 就像你独自用自己的办公桌,想怎么翻文件、怎么整理文件夹都随便,不会有人抢、不会有人干扰。但真实的数据库是多核 CPU、多用户同时访问的,必须让很多线程同时读写同一个索引。这么做一是为了榨干多核性能,二是为了 “隐藏磁盘 IO 的等待”—— 磁盘读数据很慢,与其让线程傻等,不如先让别的线程干活。

若缺乏并发控制机制,会出现两类核心正确性问题:

  1. 逻辑正确性异常:读到脏的、半截的数据
  2. 物理结构损坏:直接把索引本身给搞散架

2.并发控制的正确性要求

  1. 逻辑正确性:线程只能读取当前事务/操作可见的合法数据,无脏读、幻读等异常;

  2. 物理正确性:确保数据结构的内部表示始终处于有效状态,如 B + 树节点的指针不被破坏、链表无断链等,这正是 Latch 需要解决的核心问题

二、闩锁(Latch)核心基础体系

1. 闩锁与事务锁的核心区别

(1)技术背景

数据库有两套完全不一样的并发控制机制:事务锁 Lock 面向上层业务事务,闩锁 Latch 面向底层内核数据结构。它们的管控层次、存活周期、使用场景均不相同

(2)核心逻辑对比

锁(Lock)与闩锁(Latch)的对比是数据库内核并发的重点知识,二者关键区别整理如下:

  1. 管控对象:Lock 用于隔离多个并发事务;Latch 用于隔离数据库内部各个工作线程。
  2. 保护对象:Lock 防护磁盘上的业务逻辑数据;Latch 保护驻留内存的索引、缓冲页这类内核数据结构。
  3. 持有周期:Lock 的有效期覆盖完整事务,事务结束才释放;Latch 只在临界代码执行期间持有,操作结束马上释放。
  4. 回滚特性:Lock 可以跟随事务完成回滚;Latch 只负责维护结构完整性,不参与事务回滚。
  5. 死锁处理:Lock 通过死锁检测、超时机制、事务中止来化解死锁;Latch 依靠编码规范从设计上避免死锁发生。
  6. 存储位置:Lock 交由锁管理器集中维护;Latch 直接挂载在受保护的内核结构之上。

(3)优缺点与实际落地表现

优点:双层并发控制机制分工明确。事务锁 Lock 负责保证上层业务事务的逻辑一致性,闩锁 Latch 维护数据库内核底层结构的物理完整性,同时兼顾业务逻辑正确和系统运行稳定。
缺点:闩锁不提供死锁检测能力,只能依靠开发时的编码规范规避死锁问题,开发实现难度大,系统容错能力较弱。

通俗示例:事务锁相当于图书馆的借阅权限管控锁,约束各个读者(对应事务)的借书行为;闩锁则是书架整理时的防护锁,约束管理员(对应工作线程)调整整理书架(索引结构),防止整理操作中途造成书架结构损坏。

2.闩锁工作模式与兼容性

(1)技术背景

多线程访问索引结构分为读、写两类操作,读操作可并发执行,写操作需要独占资源。为最大化并发性能、减少不必要的阻塞,闩锁设计了读写两种工作模式及兼容机制。

(2)核心逻辑

读模式(Read):允许多个线程同时获取读闩锁,支持并发读取,线程之间不会互相阻塞。
写模式(Write):属于独占访问模式。只要已有线程持有读闩锁或者写闩锁,其他线程就不能成功加写闩锁,同一时刻只允许一个线程执行修改操作。
兼容性规则:读‑读可以共存;读‑写相互排斥;写‑写相互排斥。

(3)优缺点

优点:充分释放读并发能力,适配数据库读多写少场景,提高系统吞吐量;锁逻辑简单,执行效率高。
缺点:读锁若长时间不释放,会一直挡住写请求。

3.闩锁设计目标与主流实现方案

(1)技术背景

闩锁是数据库内核高频使用的基础组件,它的内存消耗和执行效率直接约束数据库并发能力,所以闩锁要做到轻量、无冲突时快速运行、去中心化。

(2)核心设计目标

  • 内存开销低:闩锁依附于海量的索引节点,每个闩锁都要尽量少占内存。
  • 无冲突快速路径:没有线程竞争是常态,加锁解锁逻辑必须飞快,不能造成性能瓶颈。
  • 去中心化:闩锁跟着节点走,不需要全局管理器,消除单点瓶颈。

(3)主流实现方案

  • 测试并设置自旋闩锁(TAS):基于CPU原子指令实现,加解锁仅需单指令,无冲突效率极高;但不支持缓存友好、高并发下自旋浪费CPU,无法扩容。
  • 阻塞式OS互斥锁:基于系统futex实现,使用简单;但每次加解锁约25ns,并发扩展性差,高竞争下线程阻塞开销大。
  • 读写闩锁:支持并发读,通过读写队列避免饥饿;可基于自旋锁二次封装,但需要维护队列状态,存在少量开销。

(4)优缺点总结

自旋锁适合低竞争、短临界区场景;OS互斥锁适合高竞争、长临界区场景;自适应闩锁综合性能最优,是现代数据库内核主流选型。

三.哈希表索引并发控制机制

1.技术背景

哈希表的访问模式天生利于并发优化:线程访问哈希表只做单向寻址,每次仅访问一个槽位或一页,没有跨页的复杂遍历。因此哈希表并发不容易出现死锁,开发难度比 B + 树小很多。不过全局锁会严重压制并发性能,于是出现了多种粒度的闩锁实现方案。

2.三类核心实现方式

(1)全局闩锁方案

整表共用一把锁。实现最简单,并发性能最差,内存开销极小;仅适用于小表、原型验证场景。

(2)页/块级闩锁方案

按数据页独立加锁。粒度适中,不同页可并行操作,贴合磁盘 IO 特性;是磁盘哈希索引最常用的折中方案。

(3)槽位级闩锁方案

每个哈希槽独立加锁。并发性能最强、锁竞争最小;但实现复杂、锁本身内存开销大;适用于内存哈希、高并发场景。

四.B+树索引并发控制核心协议

1.技术背景

B + 树作为数据库的核心索引结构,复杂度远高于哈希表。线程访问 B + 树需要自顶向下逐层遍历节点,且写入操作会触发节点分裂、合并与数据迁移等结构性变更,存在遍历操作与结构修改之间的并发冲突。若不加以管控,会出现遍历中途节点被拆分、数据丢失、树结构损坏等严重问题,因此需要设计专属的 B + 树并发闩锁协议。

需要解决两类核心问题:

  • 多线程同时修改同一节点
  • 线程遍历树时其他线程修改节点结构

2.闩锁耦合协议

这是 B + 树并发控制的核心协议,通过「边加锁边解锁」兼顾结构安全与并发性能,核心三点:

  1. 加锁规则:严格自上而下、先父后子加锁,所有线程遵循统一加锁顺序,从根源避免死锁。
  2. 安全节点判定:插入场景下节点未满、删除场景下节点数据过半即为安全;安全节点操作后不会触发分裂 / 合并,不会牵连上层节点。
  3. 释锁规则:获取子节点锁并确认其安全后,立即释放所有祖先节点的锁,大幅缩短锁持有时间,提升整体并发度。

3.悲观耦合协议缺陷与优化方案

悲观协议 = 默认写操作一定会触发结构变动,全程加写锁
乐观优化 = 默认大概率不会触发结构变动,先读锁遍历,不行再回退

(1)缺陷背景

传统悲观耦合协议存在两个核心问题:

  1. 根节点成为全局瓶颈:每次更新都从根节点开始加写锁,而根节点全局唯一,高并发下所有写操作都争抢这一把锁,直接卡死整体并发上限。
  2. 策略过度保守:实际业务中绝大多数 B + 树修改只改动叶子节点的数据,根本不会触发节点分裂、合并,完全不需要锁住上层节点。悲观策略全程持写锁,白白浪费了大量并发能力。

(2)乐观闩锁优化算法

核心逻辑:基于绝大多数修改不会引发结构变动的统计规律做乐观假设,先用低成本的读锁遍历到叶子节点,再升级写锁修改;只有真的触发结构变化时,才回退走完整的悲观写锁流程。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/6 8:16:31

边缘芯片如何驱动AI计算规模化落地:架构选型与工程实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/6 8:15:24

从偶然成功到可复用资产:异环经验沉淀的工程实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/6 8:14:27

快速学习Python的技巧

1. 一页纸核心语法(必会) # 变量与类型 x 10 # int name "Alice" # str pi 3.14 # float is_ok True # bool items [1, 2, 3] # list info {"a": 1} # dict nums (1, …

作者头像 李华
网站建设 2026/9/6 8:09:02

合成数据驱动泰文OCR:数据生成、增广与训练实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/6 8:07:07

191、大模型推理优化:vLLM与TensorRT-LLM在机器人服务化部署

191、大模型推理优化:vLLM与TensorRT-LLM在机器人服务化部署 深夜两点十七分,机房里只剩下服务器风扇的嗡鸣。我盯着终端里那行反复出现的 CUDA out of memory,感觉自己像个对着漏水水管的管道工——明明知道问题在哪,就是堵不住。这是给某工厂做的机械臂分拣系统,视觉语…

作者头像 李华