SQL Server 2014如何提升非在线的在线操作

在今天的文章里,我想谈下在线索引重建操作( Online Index Rebuild operations),它们在SQL Server 2014里有怎样的提升。我们都知道,自SQL Server 2005开始引入了在线索引重建操作。但这些在线操作并非真正的在线操作,因为在操作开始时,SQL Server需要获得共享表锁(Shared Table Lock (S) ),在操作结束时需要在对应表上获得架构修改锁(Schema Modification Lock (Sch-M) )。因此这些操作是真正的在线操作,只是营销技巧(marketing trick)。但是,亲,“在线”肯定比“部分在线”好听多了。

尽管如此,SQL Server 2014还是在在线索引重建的开始和结束发生的阻塞做了一些改进。因此,在你执行在线索引重建时,你可以定义所谓的锁优先级(Lock Priority)。来看看下面的代码,你会看到起作用的新语法:

 1 ALTER INDEX idx_Col1 ON Foo REBUILD
 2 WITH
 3 (
 4    ONLINE = ON
 5    (
 6       WAIT_AT_LOW_PRIORITY
 7       (
 8          MAX_DURATION = 1,
 9          ABORT_AFTER_WAIT = SELF
10       )
11    )
12 )
13 GO

当阻塞情况发生时,你可以用WAIT_AT_LOW_PRIORITY关键字定义如何处理。使用第1个属性MAX_DURATION指定你想要等待的时间——这里是分钟,不是秒!用ABORT_AFTER_WAIT属性你指定哪个会话需要被SQL Server回滚。SELF意味着那个ALTER INDEX REBUILD语句会回滚,当你指定BLOCKERS时,阻塞的会话会回滚。当然,当没有阻塞发生时,在线索引重建操作会立即执行。因此这里你只能配置当阻塞情况发生时要怎么处理。

好了,我们来实操下。我们新建一个数据库,一个简单的表和一个聚集索引。

 1 -- Creates a new database
 2 CREATE DATABASE Test
 3 GO
 4
 5 -- Use the database
 6 USE Test
 7 GO
 8
 9 -- Create a simple table
10 CREATE TABLE Foo
11 (
12     Col1 INT IDENTITY(1, 1) NOT NULL,
13     Col2 INT NOT NULL,
14     Col3 INT NOT NULL
15 )
16 GO
17
18 -- Create a unique Clustered Index on the table
19 CREATE UNIQUE CLUSTERED INDEX idx_Col1 ON Foo(Col1)
20 GO
21
22 -- Insert a few test records
23 INSERT INTO Foo VALUES (1, 1), (2, 2), (3, 3)
24 GO

为了触发阻塞,我在不同的会话开始一个新的事务,但不提交:

1 BEGIN TRANSACTION
2
3 UPDATE Foo SET Col2 = 2
4 WHERE Col1 = 1

这意味着我们在需要修改的记录上获得排它锁(Exclusive Lock (X)),在对应的页上获得意向排它锁(Intent-Exclusive Lock (IX)),在表本身获得意向排它锁(Intent-Exclusive Lock (IX))。我们刚刚在SQL Server里创建了典型的锁定层次(locking hierarchy):表=>页=>记录。在表级别的意向排它锁(IX Lock)和在线索引重建操作需要的共享锁(Shared Lock)是不兼容的——典型的锁/阻塞情形发生了。当你现在执行在线索引重建操作时,会发生阻塞:

1 ALTER INDEX idx_Col1 ON Foo REBUILD
2 WITH
3 (
4    ONLINE = ON
5 )
6 GO

当你查看DMV sys.dm_tran_locks时,你会看到那个需要共享锁(Shared Lock(S))的会话需要等待。这个会话会永远等待。我刚才就说过:“部分在线”……

1 SELECT * FROM    sys.dm_tran_locks

当我们执行带有锁优先级(Lock Priority)的在线索引重建时,有趣的事情发生了:

 1 -- Perform an Online Index Rebuild
 2 ALTER INDEX idx_Col1 ON Foo REBUILD
 3 WITH
 4 (
 5    ONLINE = ON
 6    (
 7       WAIT_AT_LOW_PRIORITY
 8       (
 9          MAX_DURATION = 1,
10          ABORT_AFTER_WAIT = SELF
11       )
12    )
13 )
14 GO

在这个情况下,我们的ALTER INDEX语句会等待1分钟(MAX_DURATION),然后语句本身取消了(ABORT_AFTER_WAIT)。

如果你在这里指定了BLOCKERS选项,那么阻塞的会话就会回滚。当我们同时(在1分钟期间)查看DMV sys.dm_tran_locks,我们看到了有趣的东西:

从图中可以看到,SQL Server这里请求一个LOW_PRIORITY_WAIT的状态。因此3个请求状态(GRANT,WAIT,CONVERT)有了第4个选项:LOW_PRIORITY_WAIT。当我们查看DMV sys.dm_os_waiting_tasks时,事情变得有意思(59是执行语句的会话ID):

1 SELECT * FROM sys.dm_os_waiting_tasks WHERE session_id=‘59‘

在线索引重建操作的等待会话报告了一个新的等待类型LCK_M_S_LOW_PRIORITY。这意味着当在线索引重建操作被阻塞时,我们可以从服务器级别(sys.dm_os_wait_stats)的等待统计信息里获得——不错!

但是LCK_M_S_LOW_PRIORITY并不是新的等待类型。在SQL Server 2014里,当你查看DMV sys.dm_os_wait_stats时,会看到21个新的等待类型:

1 SELECT * FROM sys.dm_os_wait_stats WHERE wait_type LIKE ‘%LOW_PRIORITY%‘
  • LCK_M_SCH_S_LOW_PRIORITY
  • LCK_M_SCH_M_LOW_PRIORITY
  • LCK_M_S_LOW_PRIORITY
  • LCK_M_U_LOW_PRIORITY
  • LCK_M_X_LOW_PRIORITY
  • LCK_M_IS_LOW_PRIORITY
  • LCK_M_IU_LOW_PRIORITY
  • LCK_M_IX_LOW_PRIORITY
  • LCK_M_SIU_LOW_PRIORITY
  • LCK_M_SIX_LOW_PRIORITY
  • LCK_M_UIX_LOW_PRIORITY
  • LCK_M_BU_LOW_PRIORITY
  • LCK_M_RS_S_LOW_PRIORITY
  • LCK_M_RS_U_LOW_PRIORITY
  • LCK_M_RIn_NL_LOW_PRIORITY
  • LCK_M_RIn_S_LOW_PRIORITY
  • LCK_M_RIn_U_LOW_PRIORITY
  • LCK_M_RIn_X_LOW_PRIORITY
  • LCK_M_RX_S_LOW_PRIORITY
  • LCK_M_RX_U_LOW_PRIORITY
  • LCK_M_RX_X_LOW_PRIORITY

所有主要的等待类型(LCK_M_*)都有额外的锁优先级等待类型。这个非常酷,也非常强大,因为你很容易从中可以跟踪到为什么在线重建索引操作被阻塞。另外,对于分区切换(Partition Switching)也适用同样的技术(锁优先级(Lock Priorities)),因为在切换期间,操作也要在2个表(原表,目标表)上获取架构修改锁(Schema Modification Lock (Sch-M))。

我希望这篇文章可以让你理解SQL Server 2014里的锁优先级(Lock Priorities),还有为什么SQL Server里的“在线”操作实际上只是“部分在线”。

感谢关注!

时间: 2024-10-20 21:09:19

SQL Server 2014如何提升非在线的在线操作的相关文章

SQL Server 2014里的性能提升

在这篇文章里我想小结下SQL Server 2014引入各种惊艳性能提升!! 缓存池扩展(Buffer Pool Extensions) 缓存池扩展的想法非常简单:把页文件存储在非常快的存储上,例如SSD硬盘,用来扩展缓存池.缓存池扩展来得非常方便,如果你不能给你的数据库服务器物理上增加更多的内存,可以考虑使用缓存池扩展. 资源调控器(Resource Governor) 资源调控器首次是在SQL Server 2008里引入的,但那个时候还不是个成熟的技术,因为你不能在存储级别调控I/O操作,

SQL Server 2014,表变量上的非聚集索引

从Paul White的推特上看到,在SQL Server 2014里,对于表变量(Table Variables),它是支持非唯一聚集索引(Non-Unique Clustered Indexes)和非聚集索引(Non-Clustered Indexes)的.看到这个,我决定在自己的虚拟机里尝试下,因为这将是个卓越的功能.表变量很棒,因为用它可以避免过多的重编译(excessive recompilations).当你创建它们时,它们是没有统计信息,你不会改变数据库架构.它们只是变量,但在Te

在SQL Server 2014里,如何用资源调控器压制你的存储?

在今天的文章里,我想谈下SQL Server 2014里非常酷的提升:现在你终于可以根据需要的IOPS来压制查询!资源调控器(Resource Governor)自SQL Server 2008起引入,但提供的功能还是有所限制:你只能限制CPU时间(这个已经很棒了),还有你能限制查询(从每个独立的查询)内存量. 但作为DBA的你,你经常会进行一些数据库维护操作,例如索引重建,DBCC CHECKDB操作等.我们都知道,这些操作会在你的存储里带来大量的IOPS直至峰值.如果在7 * 24在线的数据

SQL Server 2014 日志传送部署(2):日志传送系统要求和实验架构

13.2 部署日志传送 13.2.1 部署日志传送的系统要求 SQL Server 2014日志传送的部署对硬件基础设施有一定的要求,下面将概述这些系统要求. 网络 日志传送不一定需要Windows域环境,但是Windows域环境方便了日志传送的配置和管理:相对非域环境,其安全性提升不少. 参与日志传送的SQL Server服务器必须在网络中相互连通,主服务器能够将事务日志备份到共享文件夹,辅助服务器可以将事务日志备份复制到本地文件夹:监视服务器能够连接到主服务器和辅助服务器. 服务器和存储 主

解读SQL Server 2014可更新列存储索引——存储机制

概述 SQL Server 2014被号称是微软数据库的一个革命性版本,其性能的提升的幅度是有史以来之最. 可更新的列存储索引作为SQL Server 2014的一个关键功能之一,在提升数据库的查询性能方面贡献非常突出.据微软统计,在面向OLAP查询统计类系统中,相比其他SQL传统版本的数据库,报表查询的性能最大可提升上十倍. 下面我们从存储的角度来了解下SQL Server 2014的可更新列存储索引. 什么是列存储 微软为了提升SQL Server的查询性能,更好的支持大数据分析,早在SQL

sql server 2014内存表

内存数据库,指的是将数据库的数据放在内存中直接操作.相对于存放在磁盘上,内存的数据读写速度要高出很多,故可以提高应用的性能.微软的SQL Server 2014已于2014年4月1日正式发布,SQL 2014一个主要的功能即为内存数据库. 目前来说,数据库镜像和复制是无法与内存优化表兼容的,但AlwaysOn,日志传送,备份还原是完整支持. 由于内存表数据的存放机制和普通表(基于磁盘的表)完全不同,因此内存表的数据需要一个特别的文件夹(注意不是文件哦)来存放 USE [master] --创建数

SQL Server 2014新功能 -- 内存中OLTP(In-Memory OLTP)

SQL Server 2014新功能 -- 内存中OLTP(In-Memory OLTP) 概述 内存中OLTP(项目"Hekaton")是一个全新的.完全集成到SQL Server的数据库引擎组件. 对OLTP工作负载访问中在内存中的数据进行了优化.内存中OLTP能够帮助OLTP工作负载实现显著的性能改善,并减少处理时间.表能被视为"内存优化",提升内存中的OLTP功能.内存优化表是完全可事务的.并可以使用Transact-SQL进行访问.Transact-SQL

SQL Server 执行计划利用统计信息对数据行的预估原理以及SQL Server 2014中预估策略的改变

前提  本文仅讨论SQL Server查询时, 对于非复合统计信息,也即每个字段的统计信息只包含当前列的数据分布的情况下, 在用多个字段进行组合查询的时候,如何根据统计信息去预估行数的. 利用不同字段的统计信息做数据行数预估的算法原理,以及SQL Server 2012和SQL Server 2014该算法的差异情况, 这里暂时不涉及复合统计信息,暂不涉及统计信息的更新策略及优化相关话题,以及其他SQL Server版本计算方式. 统计信息是什么 简单说就是对某些字段的数据分布的一种描述,让SQ

在SQL Server 2014里可更新的列存储索引 (Updateable Column Store Indexes)

传统的关系数据库服务引擎往往并不是对超大量数据进行分析计算的最佳平台,为此,SQL Server中开发了分析服务引擎去对大笔数据进行分析计算.当然,对于数据的存放平台SQL Server数据库引擎而言,也是需要强大的数据处理能力的. 在SQL Server 2012时,SQL Server 引入了列存储索引,用以显著提供高传统数据仓库类型语句的性能,并在SQL Server 2014中做了进一步加强.本文将在对SQL Server 2012列存储索引简单介绍的基础上,进一步解释SQL Serve