设为首页 收藏本站
查看: 1154|回复: 0

[经验分享] SQL Server里的闩锁耦合(Latch Coupling)

[复制链接]

尚未签到

发表于 2017-7-12 20:21:02 | 显示全部楼层 |阅读模式
  几年前,我写了篇关于闩锁和为什么SQL Server需要它们的文章。在今天的文章里,我想进一步谈下非缓存区闩锁(Non-Buffer Latches),还有在索引查找操作期间,SQL Server如何使用它们。在这里你会学到称为闩锁耦合(Latch Coupling)的概念。

索引查找操作(Index Seek Operations)
  正如你知道的,SQL Server使用扫描(Scan)和查找(Seek)操作在索引(聚集和非聚集索引)里访问数据。这里的查找操作使用B树的导航结构在叶子节点查找特定的记录。下图展示了这个概念。
   DSC0000.png
  在这个例子里,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事件。
   DSC0001.png
  但更有意思的事是SQL Server获得和释放这些闩锁的顺序。一般你期望SQL Server在页上获得闩锁,并最后释放这个闩锁。但事实并非如此!
  我们来详细看下。首先SQL 在索引根页(975号页)上获得了一个共享闩锁。在SQL Server处理那个页后,聚集索引查找操作在接下来的层级里,继续读取请求的页,并在它上面获取闩锁(257号页)。
  注意在索引根页上获得的闩锁还没有释放,它还保持获取!
  当在接下来的索引页上成功获取闩锁后,在索引根页上的闩锁才会释放。这个方法称为闩锁耦合(Latch Coupling)。这个必须的,因为SQL Server在B树结构里,跟随从一个页到另一个页的指针。
  在页处理期间,这个指针必须保持稳定。例如,在此期间不允许被另一个工作者线程(例如分页操作)将此指针无效。因此SQL Server在(单线程)索引查找操作期间,同时把持2个闩锁。下面这个图片很好的演示了这个重要概念。
   DSC0002.gif
  当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/

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-393304-1-1.html 上篇帖子: SQL SERVER大话存储结构(3)_数据行的行结构 下篇帖子: SQL Server-聚焦深入理解死锁以及避免死锁建议(三十三)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表