Cle*_*ent 6 sql-server clustered-index azure-sql-database index-maintenance online-operations
我正在尝试在 Azure SQL 数据库上重建大表 (77GB) 的聚集索引。表上有高并发事务活动,因此我正在使用该ONLINE=ON
选项。
这对于较小的表很有效;但是,当我在这个大表上运行它时,它似乎在表上使用了排他锁。我不得不在 5 分钟后停止它,因为所有事务活动都超时了。
来自 SPID 199 的会话:
ALTER INDEX PK_Customer ON [br].[Customer]
REBUILD WITH (ONLINE = ON, RESUMABLE = ON);
Run Code Online (Sandbox Code Playgroud)
从另一个会话:
在相同的结果中更进一步:
我知道在线重建可以在过程开始和结束时锁定“短”持续时间。但是,这些锁定会持续几分钟,这并不完全是“短”持续时间。
在重建运行时,我运行了SELECT * FROM sys.index_resumable_operations;
但它返回了 0 行,就好像重建根本没有开始一样。
较小的表也有一个可能大于 900 字节的 PK,并且相同的ALTER
语句在没有任何长时间阻塞的情况下工作,所以我认为它与 PK 大小无关。这些较小的表也有相似数量的nvarchar(max)
列。我能想到的唯一真正的区别是这个表有更多的行。
这是 的完整定义br.Customer
。没有外键或非聚集索引。
CREATE TABLE [br].[Customer](
[Id] [bigint] NOT NULL,
[ShopId] [nvarchar](450) NOT NULL,
[accepts_marketing] [bit] NOT NULL,
[address1] [nvarchar](max) MASKED WITH (FUNCTION = 'partial(2, "XXX", 0)') NULL,
[address2] [nvarchar](max) MASKED WITH (FUNCTION = 'partial(2, "XXX", 0)') NULL,
[city] [nvarchar](max) NULL,
[company] [nvarchar](max) NULL,
[country] [nvarchar](max) NULL,
[country_code] [nvarchar](max) NULL,
[email] [nvarchar](max) MASKED WITH (FUNCTION = 'email()') NULL,
[first_name] [nvarchar](max) MASKED WITH (FUNCTION = 'partial(2, "XXX", 0)') NULL,
[last_name] [nvarchar](max) MASKED WITH (FUNCTION = 'partial(2, "XXX", 0)') NULL,
[note] [nvarchar](max) NULL,
[phone] [nvarchar](max) MASKED WITH (FUNCTION = 'partial(2, "XXX", 0)') NULL,
[province] [nvarchar](max) NULL,
[province_code] [nvarchar](max) NULL,
[state] [nvarchar](max) NULL,
[tax_exempt] [bit] NOT NULL,
[verified_email] [bit] NOT NULL,
[zip] [nvarchar](max) NULL,
[multipass_identifier] [nvarchar](max) NULL,
[created_at_local] [datetimeoffset](7) NOT NULL,
[updated_at_local] [datetimeoffset](7) NOT NULL,
[tags] [nvarchar](max) NULL,
[address_phone] [nvarchar](max) MASKED WITH (FUNCTION = 'partial(2, "XXX", 0)') NULL,
[address_firstname] [nvarchar](max) MASKED WITH (FUNCTION = 'partial(2, "XXX", 0)') NULL,
[address_lastname] [nvarchar](max) MASKED WITH (FUNCTION = 'partial(2, "XXX", 0)') NULL,
CONSTRAINT [PK_Customer] PRIMARY KEY CLUSTERED
(
[ShopId] ASC,
[Id] ASC
)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
ALTER TABLE [br].[Customer] ADD DEFAULT ('0001-01-01T00:00:00.000+00:00') FOR [created_at_local]
GO
ALTER TABLE [br].[Customer] ADD DEFAULT ('0001-01-01T00:00:00.000+00:00') FOR [updated_at_local]
GO
Run Code Online (Sandbox Code Playgroud)
我今天(9 月 24 日)进一步调查并运行了SP_WHOISACTIVE @get_locks = 1
,它清楚地显示UPDATE/INSERT/DELETE
了运行ALTER INDEX
.
通过查询运行在 Customer 表上持有的锁ALTER INDEX
:
ALTER INDEX PK_Customer ON [br].[Customer]
REBUILD WITH (ONLINE = ON, RESUMABLE = ON);
Run Code Online (Sandbox Code Playgroud)
来自UPDATE
在同一张表上运行的会话的锁:
CREATE TABLE [br].[Customer](
[Id] [bigint] NOT NULL,
[ShopId] [nvarchar](450) NOT NULL,
[accepts_marketing] [bit] NOT NULL,
[address1] [nvarchar](max) MASKED WITH (FUNCTION = 'partial(2, "XXX", 0)') NULL,
[address2] [nvarchar](max) MASKED WITH (FUNCTION = 'partial(2, "XXX", 0)') NULL,
[city] [nvarchar](max) NULL,
[company] [nvarchar](max) NULL,
[country] [nvarchar](max) NULL,
[country_code] [nvarchar](max) NULL,
[email] [nvarchar](max) MASKED WITH (FUNCTION = 'email()') NULL,
[first_name] [nvarchar](max) MASKED WITH (FUNCTION = 'partial(2, "XXX", 0)') NULL,
[last_name] [nvarchar](max) MASKED WITH (FUNCTION = 'partial(2, "XXX", 0)') NULL,
[note] [nvarchar](max) NULL,
[phone] [nvarchar](max) MASKED WITH (FUNCTION = 'partial(2, "XXX", 0)') NULL,
[province] [nvarchar](max) NULL,
[province_code] [nvarchar](max) NULL,
[state] [nvarchar](max) NULL,
[tax_exempt] [bit] NOT NULL,
[verified_email] [bit] NOT NULL,
[zip] [nvarchar](max) NULL,
[multipass_identifier] [nvarchar](max) NULL,
[created_at_local] [datetimeoffset](7) NOT NULL,
[updated_at_local] [datetimeoffset](7) NOT NULL,
[tags] [nvarchar](max) NULL,
[address_phone] [nvarchar](max) MASKED WITH (FUNCTION = 'partial(2, "XXX", 0)') NULL,
[address_firstname] [nvarchar](max) MASKED WITH (FUNCTION = 'partial(2, "XXX", 0)') NULL,
[address_lastname] [nvarchar](max) MASKED WITH (FUNCTION = 'partial(2, "XXX", 0)') NULL,
CONSTRAINT [PK_Customer] PRIMARY KEY CLUSTERED
(
[ShopId] ASC,
[Id] ASC
)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
ALTER TABLE [br].[Customer] ADD DEFAULT ('0001-01-01T00:00:00.000+00:00') FOR [created_at_local]
GO
ALTER TABLE [br].[Customer] ADD DEFAULT ('0001-01-01T00:00:00.000+00:00') FOR [updated_at_local]
GO
Run Code Online (Sandbox Code Playgroud)
Microsoft 支持已确认这是 Sql Azure 中的一个错误(不确定它是否会影响 Sql Server)。我的理解是,如果从表中删除一些列,那么下次我们重建索引时,sql server将尝试回收已删除的列空间(我在这里故意含糊其辞,因为我不完全确定这意味着)并且即使提供了 ONLINE = ON 选项,此过程也会在表上有独占锁的情况下发生。他们正在努力修复。
归档时间: |
|
查看次数: |
460 次 |
最近记录: |