几年前,我写了篇关于闩锁和为什么SQL Server需要它们的文章。在今天的文章里,我想进一步谈下非缓存区闩锁(Non-Buffer Latches),还有在索引查找操作期间,SQL Server如何使用它们。在这里你会学到称为闩锁耦合(Latch Coupling)的概念。

索引查找操作(Index Seek Operations)

正如你知道的,SQL Server使用扫描(Scan)和查找(Seek)操作在索引(聚集和非聚集索引)里访问数据。这里的查找操作使用B树的导航结构在叶子节点查找特定的记录。下图展示了这个概念。

在这个例子里,SQL Server读取索引根页,在层级下的索引页,最后在叶子级别读取数据页。每次SQL Server在缓存池里访问这个页,这个页需要获得共享闩锁(Shared Latch)。共享闩锁是至关重要的,因为在内存里,它让当下处理的页只读:

  • 每个排它闩锁(Exclusive Latch)和共享闩锁不兼容。

因此请求一个排它闩锁会阻塞,SQL Server会提示你有个PAGELATCH_EX等待类型。

现在我们来看下在查找操作期间,在索引页上,SQL Server如何获取和释放这些闩锁。下列代码展示了对于一个特定的会话ID,可以捕获latch_acquired和latch_released事件的扩展事件会话(根据实际情况修改会话ID)。

CREATE EVENT SESSION LatchTracking ON SERVER
ADD EVENT sqlserver.latch_acquired
(
ACTION
(
sqlserver.database_id,
sqlserver.session_id,
sqlserver.sql_text
)
WHERE
(
[package0].[equal_uint64]([sqlserver].[session_id],(54)) AND [class]=(28))
),
ADD EVENT sqlserver.latch_released
(
ACTION
(
sqlserver.database_id,sqlserver.session_id,sqlserver.sql_text
)
WHERE
(
[package0].[equal_uint64]([sqlserver].[session_id],(54)) AND [class]=(28))
)
ADD TARGET package0.event_file
(
SET filename=N'c:\temp\LatchTracking.xel'
)
WITH
(
MAX_MEMORY = 4096 KB,
EVENT_RETENTION_MODE = ALLOW_SINGLE_EVENT_LOSS,
MAX_DISPATCH_LATENCY = 30 SECONDS,
MAX_EVENT_SIZE = 0 KB,
MEMORY_PARTITION_MODE = NONE,
TRACK_CAUSALITY = OFF,
STARTUP_STATE = OFF
)
GO

注意:在“class”属性上的筛选谓语限制了缓存闩锁。它们的内部ID是28。是的,扩展事件是自表述的……

下一步,我现在用一个表来进行聚集索引查找操作,在那个表上我已经创建了聚集索引,在导航层级里包含三层(包含叶子层)。

闩锁耦合实战(Latch Coupling in Action)

扩展事件会话向你展示了,在聚集索引查找操作期间,对于整个会话需要那个缓存闩锁(只要你修改的会话ID是正确的……)。当你查看输出时,你会看到我们已经捕获了6个事件:3个latch_acquired事件, 和3个latch_released事件。

但更有意思的事是SQL Server获得和释放这些闩锁的顺序。一般你期望SQL Server在页上获得闩锁,并最后释放这个闩锁。但事实并非如此!

我们来详细看下。首先SQL 在索引根页(975号页)上获得了一个共享闩锁。在SQL Server处理那个页后,聚集索引查找操作在接下来的层级里,继续读取请求的页,并在它上面获取闩锁(257号页)。

注意在索引根页上获得的闩锁还没有释放,它还保持获取!

当在接下来的索引页上成功获取闩锁后,在索引根页上的闩锁才会释放。这个方法称为闩锁耦合(Latch Coupling)。这个必须的,因为SQL Server在B树结构里,跟随从一个页到另一个页的指针。

在页处理期间,这个指针必须保持稳定。例如,在此期间不允许被另一个工作者线程(例如分页操作)将此指针无效。因此SQL Server在(单线程)索引查找操作期间,同时把持2个闩锁。下面这个图片很好的演示了这个重要概念。

当SQL Server在下层的页(页号257)上成功获取共享闩锁后,在索引根页(页号975)上的共享闩锁被释放。当SQL Server在中间层处理了这个页后,SQL Server在叶子层级的数据页(页号256)上获得共享闩锁,然后并在上层的页(页号257)上释放共享闩锁。当这个页成功处理后,最后在页号265上的共享闩锁也被释放。

小结

在这篇文章里我向你展示了在索引查找操作中,通过所谓的闩锁耦合概念,SQL Server如何获取和释放闩锁。一个常见的误解,在查找操作期间,SQL Server只在特定的页上获取闩锁。如你在今天的文章所见,这个并不真的正确。

感谢您的关注!

原文链接

http://www.sqlpassion.at/archive/2016/10/24/latch-coupling-in-sql-server/

SQL Server里的闩锁耦合(Latch Coupling)的更多相关文章

  1. SQL Server里的闩锁介绍

    在今天的文章里我想谈下SQL Server使用的更高级的,轻量级的同步对象:闩锁(Latch).闩锁是SQL Server存储引擎使用轻量级同步对象,用来保护多线程访问内存内结构.文章的第1部分我会介 ...

  2. SQL Server里的自旋锁介绍

    在上一篇文章里我讨论了SQL Server里的闩锁.在文章的最后我给你简单介绍了下自旋锁(Spinlock).基于那个基础,今天我会继续讨论SQL Server中的自旋锁,还有给你展示下如何对它们进行 ...

  3. 在SQL Server里为什么我们需要更新锁

    今天我想讲解一个特别的问题,在我每次讲解SQL Server里的锁和阻塞(Locking & Blocking)都会碰到的问题:在SQL Server里,为什么我们需要更新锁?在我们讲解具体需 ...

  4. SQL Server里的文件和文件组

    在今天的文章里,我想谈下SQL Server里非常重要的话题:SQL Server如何处理文件的文件组.当你用CREATE DATABASE命令创建一个简单的数据库时,SQL Server为你创建2个 ...

  5. sql server 里的文件和文件组使用

    转自:https://www.cnblogs.com/woodytu/p/5821827.html 参考:https://www.sqlskills.com/blogs/paul/files-and- ...

  6. 在SQL Server里我们为什么需要意向锁(Intent Locks)?

    在1年前,我写了篇在SQL Server里为什么我们需要更新锁.今天我想继续这个讨论,谈下SQL Server里的意向锁,还有为什么需要它们. SQL Server里的锁层级 当我讨论SQL Serv ...

  7. SQL Server里等待统计(Wait Statistics)介绍

    在今天的文章里我想详细谈下SQL Server里的统计等待(Wait Statistics),还有她们如何帮助你立即为什么你的SQL Server当前很慢.一提到性能调优,对我来说统计等待是SQL S ...

  8. 在SQL Server里如何处理死锁

    在今天的文章里,我想谈下SQL Server里如何处理死锁.当2个查询彼此等待时会发生死锁,没有一个查询可以继续它们的操作.首先我想给你大致讲下SQL Server如何处理死锁.最后我会展示下SQL ...

  9. SQL Server里如何处理死锁

    在今天的文章里,我想谈下SQL Server里如何处理死锁.当2个查询彼此等待时会发生死锁,没有一个查询可以继续它们的操作.首先我想给你大致讲下SQL Server如何处理死锁.最后我会展示下SQL ...

随机推荐

  1. IPC操作时IPC_CREAT和IPC_EXCL选项的说明

    IPC(包括消息队列,共享内存,信号量)的xxxget()创建操作时,可以指定IPC_CREAT和IPC_EXCL选项.以共享内存为例:当只有IPC_CREAT选项打开时,不管是否已存在该块共享内存, ...

  2. adb devices出现no permissions

    在做Android开发的时候,有些设备插入USB调试线,无法调试,出现以下错误: joey 09:58 $ adb devices List of devices attached 20080411 ...

  3. ie8 jquery parents() 获取多个的问题

    今天开发的时候碰到了一个奇怪的问题 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3 ...

  4. 分布式数据库中的Paxos 算法

    分布式数据库中的Paxos 算法 http://baike.baidu.com/link?url=ChmfvtXRZQl7X1VmRU6ypsmZ4b4MbQX1pelw_VenRLnFpq7rMvY ...

  5. NEsper Nuget包

    Esper是专门进行复杂事件处理(CEP)的流处理平台,Java版本为Esper,.Net版本为NEsper.Esper & NEsper可以方便开发者快速开发部署处理大容量消息和事件的应用系 ...

  6. 利用gulp搭建本地服务器,并能模拟ajax

    工作中可能会用到的小工具,在此记录一下.可以实现的功能有: 本地http服务器 页面实时刷新 可以模拟ajax请求 第一步,新建package.json文件.用到了gulp.gulp-webserve ...

  7. 基于Quick-cocos2d-x的资源更新方案 一

    图片来自网络 思绪何来 昨天写了一篇关于更新方案的理论 游戏开发:通过路径搜索优先级来进行补丁升级(从端游到手游) 今天继续细化一下 由于新项目采用的是Quick-cocos2d-x,那我就直接给出我 ...

  8. 久违的问候-----eclipse中搭建maven项目2016年

    好久没有写过博客了,可是一直向别人推荐自己的博客,深感惭愧!今天再次在寒冷之夜继续code,config,write. 接下来,我们就来谈下eclipse中搭建maven web工程的步骤!虽然就是一 ...

  9. Worktile协同特色之二:任务看板管理

    什么是看板 看板是一种使用可视化管理的方式,跟踪任务在整个价值流中流经的不同阶段,通常我们会用带贴纸的白板,或是电子卡片墙.具备如下几个特征:1. 流程可视化 把工作拆分成小块,一张卡片写一件任务,再 ...

  10. 混合 Data Warehouse 和 Big Data 倉庫的新架構

    (讀書筆記)許多公司,儘管想導入 Big Data,仍必須繼續用 Data Warehouse 來管理結構化的營運數據.系統記錄.而 Big Data 的出現,為 Data Warehouse 提供了 ...