在今天的文章里,我想谈下SQL Server里锁升级(Lock Escalations)。锁升级是SQL Server使用的优化技术,用来控制在SQL Server锁管理里把持锁的数量。我们首先用SQL Server里所谓的锁层级(Lock Hierarchy )开始,因为那是在像SQL Server的关系数据库里,为什么有锁升级概念存在的原因。

锁层级(Lock Hierarchy )

下图展示了SQL Server使用的锁层级:

从图里可以看到,锁层级开始于数据库层级,向下至行层级。在数据库本身层级,你一直有一个共享锁(Shared Lock (S) )。当你的查询连接到一个数据库(例如USE MyDatabase),共享锁会阻止数据库删除,或者在那个数据库上还原备份。当你进行一个操作时,在数据库层级下,在表上,在页上,在记录上都会有锁。

当你执行一个SELECT语句,在表和页上会有一个意向共享锁(Intent Shared Lock (IS) ),在记录本身上有共享锁(Shared Lock (S) )。当你进行数据修改语句(INSERT,UPDATE,DELETE),在表和页上会有一个意向排它或更新锁( Intent Exclusive or Update Lock (IX or IU) ),在改变的记录上有排它或更新锁(Exclusive or Update Lock (X or U) )。当多个线程尝试在锁层级里并发获取锁时,SQL Server会一直获取从头到脚的锁来阻止所谓的竞争危害。当你对表进行20000条记录的删除操作时,现在想象下这个锁层级会是什么样的?我们来假定记录是400 bytes长,这就意味这在8kb的页里刚好有20条记录:

在数据库上你有1个共享锁(S),在表上有1个意向排它锁(IX),在页上有1000个意向排它锁(IX)(20000条记录散布在1000个页上),最后在记录本身你有20000个排它锁(X)。对于DELETE操作总计你获取了21002个锁。在SQL Server里每个锁需要96 bytes的内存,因此对这个简单的查询需要1.9MB的锁。当你并行执行多个查询时,这个不会无限扩展。因此,SQL Server现在用所谓的锁升级(Lock Escalation)实现。

锁升级(Lock Escalations)

在你的锁层级里一旦有超过5000个锁,SQL Server会升级这么多的精细粒度(fine-granularity)的锁为简单的粗粒度(coarse-granularity)的锁。默认情况下,SQL Server“总是”升级到表层级。这意味着你的锁层级从刚才例子的样子,在锁升级成功执行后,变成如下的样子:

如你所见,在表本身上你只有一个大锁。在DELETE操作的情况下,在表层级你有一个排它锁(X)。这会以负面伤及你数据库的并发。在表层级把持一个排它锁(X)意味者没有其他回话可以访问那个表——每个其它查询会阻塞。当你在可重读隔离级别(Repeatable Read Isolation Level)运行你的SELECT语句,你也在把持你的共享锁(S)直到事务结束,这也就是说只要你读超过5000条记录就会发生锁升级。这里的结果是一个共享锁(S)在表本身!你的表只是暂时只读,因为在表上每个其它数据修改都会阻塞!

这里还有个误解——SQL Server会锁升级从行层级到页层级,最后到表层级。错了!在SQL Server里没有这样的代码路径存在!默认情况下,SQL Server总是会直接升级到表层级。到页层级的升级策略不存在。如果你的表被分区了(只针对企业版本的SQL Server),那样的话,你可以配置升级到分区层级。但这里你必须非常仔细测试你的数据访问模式,因为锁升级到分区层级会引起死锁。因此这个选项默认是没启用的。

自SQL Server 2008开始,你可以控制SQL Server如何进行锁升级——通过ALTER TABLE语句和LOCK_ESCALTATION属性。有3个可用选项:

  • TABLE
  • AUTO
  • DISABLE

按 Ctrl+C 复制代码

按 Ctrl+C 复制代码

默认选项是TABLE,意味着SQL Server总是执行锁升级到表层级——即使这个表已被分区。如果你的表已被分区,你想设置分区层级的锁升级(因为你已经测试了你的数据访问模式,用它你不会引起死锁),那么你可以修改选项为AUTOAUTO意味着你的锁升级会执行到分区层级,如果表被分区的话,否则就到表层级。使用DISABLE选项你可以完全禁用那个表的锁升级。但是禁用锁升级并不是最好的选项,因为SQL Server的锁管理器会消耗大量的内存,如果你对你的查询和索引设计不深思熟虑的话。

5000阈值:

如果没有使用 ALTER TABLE SET LOCK_ESCALATION 选项来禁用表的锁升级并且满足以下任一条件时,则将触发锁升级:
单个 Transact-SQL 语句在单个无分区表或索引上获得至少 5,000 个锁。
单个 Transact-SQL 语句在已分区表的单个分区上获得至少 5,000 个锁,并且 ALTER TABLE SET LOCK_ESCALATION 选项设为 AUTO。
数据库引擎实例中的锁的数量超出了内存或配置阈值。
如果由于锁冲突导致无法升级锁,则数据库引擎每当获取 1,250 个新锁时便会触发锁升级。

 

 

原文:https://www.sqlpassion.at/archive/2014/02/25/lock-escalations/

SqlServer Lock_Escalation的更多相关文章

  1. SQL Server 扩展事件(Extented Events)从入门到进阶(1)——从SQL Trace到Extented Events

    由于工作需要,决定深入研究SQL Server的扩展事件(Extended Events/xEvents),经过资料搜索,发现国外大牛的系列文章,作为“学习”阶段,我先翻译这系列文章,后续在工作中的心 ...

  2. [网站性能3]SqlServer中Profiler的使用

    原文链接:http://www.cnblogs.com/caishuhua226/p/3838060.html   http://www.cnblogs.com/lyhabc/articles/294 ...

  3. SQLServer之锁简介

    锁定义(Definition) 锁定是 DBMS 将访问限制为多用户环境中的行的过程. 以独占方式锁定行或列,不允许其他用户访问锁定的数据,直到锁被释放. 这可确保两个用户不能同时更新行中的同一列. ...

  4. SQLServer 服务器架构迁移

    原文:SQLServer 服务器架构迁移 最近服务器架构迁移,将原来的服务器架构迁移到新的服务器,新的服务器在硬件方面比之前更好!原来服务器使用双向同步,并且为水平划分到多个数据库服务器.迁移过程中, ...

  5. 01.SQLServer性能优化之----强大的文件组----分盘存储

    汇总篇:http://www.cnblogs.com/dunitian/p/4822808.html#tsql 文章内容皆自己的理解,如有不足之处欢迎指正~谢谢 前天有学弟问逆天:“逆天,有没有一种方 ...

  6. 03.SQLServer性能优化之---存储优化系列

    汇总篇:http://www.cnblogs.com/dunitian/p/4822808.html#tsql 概  述:http://www.cnblogs.com/dunitian/p/60413 ...

  7. SQLSERVER将一个文件组的数据移动到另一个文件组

    SQLSERVER将一个文件组的数据移动到另一个文件组 有经验的大侠可以直接忽视这篇文章~ 这个问题有经验的人都知道怎麽做,因为我们公司的数据量不大没有这个需求,也不知道怎麽做实验 今天求助了QQ群里 ...

  8. SQLSERVER走起微信公众帐号已经开通搜狗微信搜索

    SQLSERVER走起微信公众帐号已经开通搜狗微信搜索 请打开下面链接 http://weixin.sogou.com/gzh?openid=oIWsFt-hiIb_oYqQHaBMoNwRB2wM ...

  9. SQLSERVER走起 APP隆重推出

    SQLSERVER走起 APP隆重推出 为方便大家查看本微信公众以前推送的文章,QQ群里面的某位SQLSERVER重度爱好者开发了<SQLSERVER走起>的APP 以供大家一起交流 网页 ...

随机推荐

  1. POST和GET有什么区别?

    1. GET主要用于从服务器查询数据,POST用于向服务器提交数据 2. GET通过URL传递数据,POST通过http请求体传递数据 3. GET传输数据量有限制,不能大于2kb,POST传递的数据 ...

  2. OBS源码解析(3)OBSApp类介绍

    OBSApp类有以下功能: 1.负责配置文件管理 2.版本信息管理 3.主界面OBSBasic对象管理 4.obs模块初始化 class OBSApp : public QApplication { ...

  3. vue.js之生命周期,防止闪烁,计算属性的使用,vue实例简单方法和循环重复数据

    摘要:今天是比较糟糕的一天没怎么学习,原因是学校的wifi连不上了~~.今天学习一下vue的生命周期,如何防止闪烁(也就是用户看得到花括号),计算属性的使用,vue实例简单方法,以及当有重复数据时如何 ...

  4. 走进Linux01-磁盘分区与文件夹结构

    近期学习Linux,首先安装系统,遇到了磁盘分区.之前仅仅知道Linux分区是从/(根文件夹)開始的,至于磁盘格式,多块盘怎样挂载全然不了解,系统的查询了一下Linux磁盘分区和文件夹结构,整理一下. ...

  5. Android应用开发allowBackup敏感信息泄露的一点反思

    1 背景 [工匠若水 http://blog.csdn.net/yanbober 转载烦请注明出处.尊重劳动成果] 事实上这篇文章可能有些小题大作,但回过头想想还是非常有必要的,有点阴沟里翻船的感觉. ...

  6. PushMeBaby 使用

    github 下载地址 https://github.com/stefanhafeneger/PushMeBaby 1.执行假设报错,那么导入CoreServices.framawork 替换这句 # ...

  7. Linux多线程实践(三)线程的基本属性设置API

    POSIX 线程库定义了线程属性对象 pthread_attr_t ,它封装了线程的创建者能够訪问和改动的线程属性.主要包含例如以下属性: 1. 作用域(scope) 2. 栈尺寸(stack siz ...

  8. [源码]解析 SynchronousQueue 上界,下界.. 数据保存和数据传递. 堵塞队列. 有无频繁await?

     简析SynchronousQueue.LinkedBlockingQueue(两个locker,更快),ArrayBlockingQueue(一个locker,读写都竞争)     三者都是bloc ...

  9. python 金融网贷数据,pandas进行数据分析并可视化系列 (词频统计,基本操作)

    需求: 某某金融大亨想涉足金融网贷,想给网贷平台取一个名字,那么取什么名字,名字里面包含哪些关键字,在行业内的曝光率会相比较高一些呢? 可以理解为: 你负责某某网贷平台的网络推广工作,如何进一步优化各 ...

  10. Fiddler使用总结一(使用Fiddler捕获手机所有http/https通信)

    与后端数据通信是前端日常开发的重要一环,在与后端接口联调的时候往往需要通过查看后端返回的数据进行调试.如果在PC端,Chrome自带的DevTools就已经足够用了,Network面板可以记录所有网络 ...