为什么CREATE INDEX…WITH ONLINE = ON会在几分钟内阻止对表的访问?


22

我有一个现有表:

CREATE TABLE dbo.ProofDetails
(
    ProofDetailsID int NOT NULL 
        CONSTRAINT PK_ProofDetails 
        PRIMARY KEY CLUSTERED IDENTITY(1,1)
    , ProofID int NULL
    , IDShownToUser int NULL
    , UserViewedDetails bit NOT NULL 
        CONSTRAINT DF_ProofDetails_UserViewedDetails 
        DEFAULT ((0))
);

该表有150,000,000行。系统以24x7x365运行,因此没有定期发生的维护时段。

我想向表添加索引,并且使用SQL Server企业版,我应该能够做到这一点而不会阻止对表的写访问。我使用的命令是:

CREATE INDEX IX_ProofDetails_ProofID_Etc 
ON dbo.ProofDetails (ProofID, IDShownToUser)
INCLUDE (UserViewedDetails)
WITH (ONLINE=ON
    , ALLOW_ROW_LOCKS=ON
    , ALLOW_PAGE_LOCKS=ON
    , FILLFACTOR=100
    , MAXDOP=4
);

我在SSMS中通过按自己执行了该语句F5。它运行了超过一分钟,然后开始阻止其他会话。然后,CREATE INDEX由于无法阻止其他会话,我立即取消了该命令。

在第一分钟内,没有任何东西阻塞我的CREATE INDEX命令,当然sys.dm_exec_requests以等待类型CXPACKET- 显示了该过程。自从操作并行以来,我认为这不是一件坏事。

我没有很多时间检查的输出sys.dm_exec_requests。查询仅返回一行WHERE session_id = xxx。被阻止的会话正在尝试将行插入目标表。

我不知道锁可以持续多久,只是说我在语句开始后2分钟左右取消了该语句的执行。此时大约一分钟发生了阻塞。

我误解了WITH (ONLINE=ON)吗?还是我需要注意的其他事项?

该服务器是一台功能强大的机器,配备2个四核Xeon E5-2643 3.3Ghz处理器,192GB RAM和能够存储5,000+ iops的SAN存储。CPU通常低于20%,RAM则占93%,主要是由SQL Server使用的。包装盒上没有其他任何东西运行,只有Windows Server 2012和SQL Server 2012。

Answers:


23

当使用online = on创建索引时,创建索引对象本身时,创建索引过程不会阻塞,但是在接近过程结束时,它将获得一段时间的模式修改锁*,以便将索引添加到表中,此锁定类型将阻止所有外部操作,直到释放锁定为止,这可以解决您的阻止问题。

* Sch-M在线构建新的非聚集索引不需要锁,尽管在所有其他情况下都需要锁。在准备阶段,新的非聚集索引在最后阶段仅需要表级共享锁。

有关详细信息,请参见此白皮书:

SQL Server 2005中的联机索引操作

正如穆什塔克·穆罕默德Mushtaq Mohammed)在对该问题的评论中所建议的那样,另请参阅:

独角兽,彩虹,和联机索引操作保罗·兰德尔

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.