我在云中某处(可能是 Azure)的两台不同机器上有两个 SQL Server。
一种是 Microsoft SQL Server 2012 (SP3-CU10) (KB4025925) - 11.0.6607.3 (X64) Jul 8 2017 16:43:40 版权所有 (c) Microsoft Corporation Standard Edition (64-bit) on Windows NT 6.3 (Build 9600: )(管理程序)
在这台服务器上有一个到第二台服务器的链接。
第二台服务器 ( aae-sqldw-02
) 是 Microsoft SQL Server 2016 (SP1-CU15-GDR) (KB4505221) - 13.0.4604.0 (X64) Jun 15 2019 07:56:34 版权所有 (c) Microsoft Corporation Enterprise Edition:基于内核的许可 (64 -bit) 在 Windows Server 2016 Datacenter 10.0 (Build 14393:) (Hypervisor) 上
在第一台服务器上,我们正在运行“简单”查询:
TRUNCATE TABLE [dbo].[LocalTable]
INSERT INTO [dbo].[LocalTable]
([DatabaseName]
,[SalesContractNumber]
,... 60 columns
)
SELECT
convert(varchar(128), DatabaseName) collate Latin1_General_CI_AS
,convert(varchar(60), SalesContractNumber) collate Latin1_General_CI_AS
,... 60 columns
FROM [aae-sqldw-02].[Fin_DWH].[dbo].[RemoteView]
WHERE DatabaseName = 'somename'
此查询有时会失败并出现错误:
Cannot fetch a row from OLE DB provider "SQLNCLI11" for linked server "aae-sqldw-02".
或出现此错误:
Cannot fetch the rowset from OLE DB provider "SQLNCLI11" for linked server "aae-sqldw-02". .
我知道第二台服务器一天中的大部分时间都承受着非常重的负载。它实际上最大化了它的磁盘 IO(255MB/秒)。蛮力解决方案是简单地将其移至具有更多 IO 的更昂贵的计划。这种变化需要大量的官僚主义,并且需要很长时间。此外,不能保证下一层就足够了。
我现在可以用给定的资源做些什么吗?
查询成功完成后,可能需要 1-3 小时。该查询返回大约 3M 行,大约 4GB 的数据,所以不会太多。
当查询失败时Cannot fetch a row
,最后几次在 9294 秒(2.5 小时)、12326 秒(3.5 小时)后失败。
当查询失败时Cannot fetch the rowset
,它在 606 秒、611 秒后失败。
因此,600 秒建议一些默认的 10 分钟超时(用于连接?)在连接成功的情况下,它开始获取数据,但在此过程中失败。也许链接服务器无法足够快地发送下一行,并且出现了其他一些超时。
查询成功时,上次耗时 3841 秒。
以下是链接服务器的设置:
EXEC master.dbo.sp_addlinkedserver @server = N'aae-sqldw-02', @srvproduct=N'SQL Server'
EXEC master.dbo.sp_addlinkedsrvlogin @rmtsrvname=N'aae-sqldw-02',@useself=N'True',@locallogin=NULL,@rmtuser=NULL,@rmtpassword=NULL
GO
EXEC master.dbo.sp_serveroption @server=N'aae-sqldw-02', @optname=N'collation compatible', @optvalue=N'false'
EXEC master.dbo.sp_serveroption @server=N'aae-sqldw-02', @optname=N'data access', @optvalue=N'true'
EXEC master.dbo.sp_serveroption @server=N'aae-sqldw-02', @optname=N'dist', @optvalue=N'false'
EXEC master.dbo.sp_serveroption @server=N'aae-sqldw-02', @optname=N'pub', @optvalue=N'false'
EXEC master.dbo.sp_serveroption @server=N'aae-sqldw-02', @optname=N'rpc', @optvalue=N'true'
EXEC master.dbo.sp_serveroption @server=N'aae-sqldw-02', @optname=N'rpc out', @optvalue=N'true'
EXEC master.dbo.sp_serveroption @server=N'aae-sqldw-02', @optname=N'sub', @optvalue=N'false'
EXEC master.dbo.sp_serveroption @server=N'aae-sqldw-02', @optname=N'connect timeout', @optvalue=N'0'
EXEC master.dbo.sp_serveroption @server=N'aae-sqldw-02', @optname=N'collation name', @optvalue=null
EXEC master.dbo.sp_serveroption @server=N'aae-sqldw-02', @optname=N'lazy schema validation', @optvalue=N'false'
EXEC master.dbo.sp_serveroption @server=N'aae-sqldw-02', @optname=N'query timeout', @optvalue=N'0'
EXEC master.dbo.sp_serveroption @server=N'aae-sqldw-02', @optname=N'use remote collation', @optvalue=N'true'
EXEC master.dbo.sp_serveroption @server=N'aae-sqldw-02', @optname=N'remote proc transaction promotion', @optvalue=N'true'
query timeout
你怎么看,如果我明确地将选项设置为 5 小时,会有什么不同吗?它能让事情变得更糟吗?
显然,正确的解决方法是查看服务器上正在发生的事情并优化查询以减少整体负载,但是我可以在更高的服务器/数据库级别做些什么,以便查询完成,即使真的需要很长时间吗?
我们需要每周运行一次这个查询,现在我们必须重试几次,直到它成功完成。
根据我们在评论中的讨论,我认为此Microsoft 文档可能是您正在寻找的内容,但我觉得这仅适用于本地实例,您将无法在 Azure 中进行调整。
我还发现了一个与StackOverflow 相关的帖子,其中接受的答案是为高度密集的IO工作负载增加DTU,即使您只是暂时扩大规模以运行该查询并在完成后缩小规模。(再次扩展到基于 NVMe 的层可能会在这里获得巨大的回报。)
不幸的是,您收到的错误没有很多具体信息,而且原因各不相同。我发现唯一可能与您的案例相关的是这个StackExchange 帖子,该帖子的问题是由于链接服务器上发生的死锁。也许您遇到了同样的问题?(理论上这可能是由于您的服务器在IO最大化时抓取其他并发运行的查询而导致的时间问题。)
除此之外,我认为您拥有的唯一其他选择是调整查询本身以提高性能。即使在这里以约 250 MB/s 的 IO 被限制,4 GB 的数据应该在大约 16 秒内处理 + 任何可能为网络延迟添加的瓶颈。但是 1 小时以上的时间肯定会消失,即使是 300 万行(死锁似乎更可疑)。对于您遇到的错误本身并不是直接超时错误,我会考虑与 Azure 代表交谈,看看您的潜在问题是否还有其他问题。