保持迭代器处于一致状态

Mar*_*rka 5 sql-server-2008 sql-server sql-server-2008-r2

我正在阅读这篇文章以了解 Sql Server 中的事情是如何完成的:http : //rusanu.com/2013/08/01/understanding-how-sql-server-executes-a-query/

如果我理解正确,数据将根据需要发送给客户端。在我们将下一批数据提取到客户端之前,查询的执行被暂停。如果我们进行范围扫描,则有关最后返回行的元数据将存储在某处。如果在此期间页面拆分并且最后返回的行在新页面上,会发生什么情况?这可能吗?这个操作符/迭代器(例如聚集索引扫描)是否一直保持在页面上的闩锁?这将是非常低效的,所以 Sql Server 必须有其他方法来保持同步吗?

我的问题是 - 存储了哪些元数据以及 Sql Server 如何保持同步?

Pau*_*ite 8

没有 SQL Server 不持有闩锁。存储引擎使用“cookie”跟踪当前索引扫描位置。如果自获取 cookie 以来另一个进程在同一页面上获取闩锁(其类型意味着页面可能已更改),则该 cookie 将重新生效。

如果cookie(扫描位置)不再有效,则遍历b-tree结构(使用cookie中存储的key+uniquifier信息)重新获取正确的位置,并更新cookie。

如果感兴趣,这里是验证保存的位置时的堆栈捕获:

堆栈跟踪

由于并发不兼容闩锁,cookie 验证失败后的另一个。引擎正在使用查找重新定位扫描位置以找到正确的新位置:

堆栈跟踪

有与 cookie 活动相关的性能计数器,例如Scan Point Revalidations/secUsed page/leaf page cookie

没有公开文档准确描述这一切是如何工作的。以上细节基于观察结果,随后在与 Paul Randal 和 Bob Ward 的对话中得到证实。