在SQL Serve里停用行和页层级锁

本文涉及的产品
云数据库 RDS SQL Server,独享型 2核4GB
简介: 原文:在SQL Serve里停用行和页层级锁今天我想谈下SQL Server里另一个非常有趣的话题:在SQL Server里停用行和页层级锁。在SQL Server里,每次你重建一个索引,你可以使用ALLOW_ROW_LOCKS 和ALLOW_PAGE_LOCKS选项来指定,SQLServer在用读写访问你的数据时,应该获得行和页锁。
原文: 在SQL Serve里停用行和页层级锁

今天我想谈下SQL Server里另一个非常有趣的话题:在SQL Server里停用行和页层级锁。在SQL Server里,每次你重建一个索引,你可以使用ALLOW_ROW_LOCKSALLOW_PAGE_LOCKS选项来指定,SQLServer在用读写访问你的数据时,应该获得行和页锁。我们从内部看下,当我们停用这些锁时会发生什么。

停用行层级锁

让我们在一个聚集索引上运行一个简单的REBUILD操作,这里我们停用行层级锁:

-- Disable row level locks
ALTER INDEX idx_ci ON Foo REBUILD
WITH (ALLOW_ROW_LOCKS = OFF)
GO

如你从锁层级里知道的,SQL Server从表层级、页层级和行级别获取锁。现在让我们在一个显式事务里运行一个SELECT语句,并且我们用HOLDLOCK查询提示来把持共享锁直到事务结束。

-- SQL Server acquires in Repeatable Read a Shared Lock on the Page Level,
-- because Shared Row Locks are not possible anymore.
BEGIN TRANSACTION

SELECT * FROM Foo WITH (HOLDLOCK)
WHERE ID = 5000

SELECT * FROM sys.dm_tran_locks
WHERE request_session_id = @@SPID

ROLLBACK
GO

在这个事务期间,当你查看锁管理器时,你可以看到SQL Server只在表层级获得IS所,在页层级获得共享锁,没有行级别的锁!

这些获得的锁现在没有约束,因为通常SQL Server在页层级获得IS锁,在行本身获得共享锁。当你通过一个事务修改你的数据,这个概念同样适用。

-- SQL Server acquires for an UPDATE statement an Exclusive Lock on the Page Level,
-- because Exclusive Row Locks are not possible anymore.
BEGIN TRANSACTION

UPDATE Foo
SET Col2 = REPLICATE('y', 100)
WHERE ID = 5000

SELECT * FROM sys.dm_tran_locks
WHERE request_session_id = @@SPID

ROLLBACK
GO

在这个情况下,最后你还是在页层级有排它锁,而不是IX锁。

停用页层级锁

接下来让我们停用页层级锁:

-- Disable Page level locks
ALTER INDEX idx_ci ON Foo REBUILD
WITH (ALLOW_PAGE_LOCKS = OFF)
GO

首先我想向你展示下索引重组操作取决于页层级锁,因此这个重组操作会失败:

The index “idx_ci” on table “Foo” cannot be reorganized because page level locking is disabled.

现在让用重新运行我们的SELECT语句,但这次使用HOLDLOCK查询提示:

-- There is no IS lock on the Page anymore.
BEGIN TRANSACTION

SELECT * FROM Foo WITH (HOLDLOCK)
WHERE ID = 5000

SELECT * FROM sys.dm_tran_locks
WHERE request_session_id = @@SPID

ROLLBACK
GO

当你再次查看锁管理器,你会看到在页层级IS锁消失了。我们只有在表层级IS锁,在行层级有共享锁。

让我们再来修改一条记录:

-- There is no IX lock on the Page anymore.
BEGIN TRANSACTION

UPDATE Foo
SET Col2 = REPLICATE('y', 100)
WHERE ID = 5000

SELECT * FROM sys.dm_tran_locks
WHERE request_session_id = @@SPID

ROLLBACK
GO

和刚才一样的事情发生了:SQL Server在表层级获得IX锁,在行上获得排它锁。在页层级没有锁……

停用行和叶层级锁

现在让我们更进一步,对于我们的具体索引停用行和页层级锁:

-- Disable Row and Page level locks
ALTER INDEX idx_ci ON Foo REBUILD
WITH (ALLOW_ROW_LOCKS = OFF, ALLOW_PAGE_LOCKS = OFF)
GO

现在当你读取一些数据,SQL Server只在表层级获得共享锁,你的整个表是只读的:

当你修改没有获得页和行锁的一条记录时,SQL Server在整个表上获得了排它锁——偶滴神:

小结

这篇文章的意义?为什么你应该在SQL Server里停用页和行层级锁,真的没有一个很好的理由。就用SQL  Server提供的默认的锁策略即可,因为不然的话锁会约束太多,从而伤及你的性能……

感谢关注!

原文链接:

https://www.sqlpassion.at/archive/2016/10/31/disabling-row-and-page-level-locks-in-sql-server/

 

相关实践学习
使用SQL语句管理索引
本次实验主要介绍如何在RDS-SQLServer数据库中,使用SQL语句管理索引。
SQL Server on Linux入门教程
SQL Server数据库一直只提供Windows下的版本。2016年微软宣布推出可运行在Linux系统下的SQL Server数据库,该版本目前还是早期预览版本。本课程主要介绍SQLServer On Linux的基本知识。 相关的阿里云产品:云数据库RDS SQL Server版 RDS SQL Server不仅拥有高可用架构和任意时间点的数据恢复功能,强力支撑各种企业应用,同时也包含了微软的License费用,减少额外支出。 了解产品详情: https://www.aliyun.com/product/rds/sqlserver
目录
相关文章
|
28天前
|
SQL 存储 数据库
sql serve基础
sql serve基础
9 0
|
1月前
|
存储 关系型数据库 MySQL
最全MySQL面试60题(含答案):存储引擎+数据库锁+索引+SQL优化等
最全MySQL面试60题(含答案):存储引擎+数据库锁+索引+SQL优化等
162 0
|
28天前
|
存储 SQL 数据库
sql serve存储过程
sql serve存储过程
14 0
|
3月前
|
SQL 关系型数据库 MySQL
Mysql系列-3.Mysql的SQL优化和锁(中)
Mysql系列-3.Mysql的SQL优化和锁
40 0
|
2月前
|
SQL Java API
Flink超时问题之Flink sql cdc锁超时如何解决
Apache Flink是由Apache软件基金会开发的开源流处理框架,其核心是用Java和Scala编写的分布式流数据流引擎。本合集提供有关Apache Flink相关技术、使用技巧和最佳实践的资源。
|
3月前
|
SQL 关系型数据库 MySQL
Mysql系列-3.Mysql的SQL优化和锁(下)
Mysql系列-3.Mysql的SQL优化和锁
44 0
|
3月前
|
SQL 存储 关系型数据库
Mysql系列-3.Mysql的SQL优化和锁(上)
Mysql系列-3.Mysql的SQL优化和锁
37 0
|
6月前
|
SQL 数据库管理
DMS中执行SQL时,提示"获取不到锁"
DMS中执行SQL时,提示"获取不到锁"
104 3
|
9月前
|
存储 SQL 缓存
MySQL高级第三篇(共四篇)之应用优化、查询缓存优化、内存管理优化、MySQL锁问题、常用SQL技巧(二)
锁是计算机协调多个进程或线程并发访问某一资源的机制(避免争抢)。 在数据库中,除传统的计算资源(如 CPU、RAM、I/O 等)的争用以外,数据也是一种供许多用户共享的资源。如何保证数据并发访问的一致性、有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要因素。从这个角度来说,锁对数据库而言显得尤其重要,也更加复杂。
368 0
|
9月前
|
SQL 存储 缓存
MySQL高级第三篇(共四篇)之应用优化、查询缓存优化、内存管理优化、MySQL锁问题、常用SQL技巧(一)
前面章节,我们介绍了很多数据库的优化措施。但是在实际生产环境中,由于数据库本身的性能局限,就必须要对前台的应用进行一些优化,来降低数据库的访问压力。
15960 7