Ran*_*gen 4 sql-server jobs availability-groups sql-server-2017
最近,在我们进行统计更新时,我们的阻止进程仪表板一直在报告被阻止的进程。
很快就找到了原因:更新统计作业步骤 (T-SQL) 在辅助 SQL Server 实例和主 SQL Server 实例上都启动。该作业更新同一数据库的多个统计信息,该数据库是 AlwaysOn 可用性组的一部分。我希望这会在辅助实例上失败。
故障转移历史的简要概述:
由于许可而应保持活动状态的服务器 A(将被命名为活动服务器),在 20/02 晚上 9 点意外故障转移到服务器 B(被动服务器)。
在计划外故障转移之后,我们在 2002 年 2 月 21 日中午 12 点进行了另一次(但这次是计划内的)手动故障转移回 Active Server。
工作经历
在第一次故障转移之前一切都很好,活动服务器是唯一运行该作业的服务器。
一项工作正在运行。
我们看到在活动端运行的统计更新。(这是当时的主要副本)
在无源服务器作为主要副本的短时间内,我们没有任何监控并且作业历史记录被清除。
故障转移后,回到“正常”状态,在被动节点上处于主节点不到 24 小时后,被动实例上的作业步骤也已在主动实例上启动并运行。
现在对我来说有趣的部分是,这两个作业都在活动服务器上运行,似乎该作业正在使用侦听器访问数据库。但这可能是一个完全不同的原因。
有一个复制作业 PowerShell 任务在每晚凌晨 01 点运行 (dbatools):
powershell.exe Copy-DbaAgentJob -ExcludeJob "CopyJobs,CopyLogins" -Source INDCSPSQLA01 -Destination INDCSPSQLP01 -Force
Run Code Online (Sandbox Code Playgroud)
我的猜测现在是针对一次,作业复制发生在主动、次要节点 --> 带有 -Force 的主要被动节点。这发生在 21/02 01 AM。
问题
为什么被动实例上的作业步骤在主动实例的数据库上执行?
清单
在这两种情况下,作业目标都是本地的:
EXEC @ReturnCode = msdb.dbo.sp_add_jobserver @job_id = @jobId, @server_name = N'(local)'
Run Code Online (Sandbox Code Playgroud)
服务器名称正确
select name from sys.servers
select @@SERVERNAME
Run Code Online (Sandbox Code Playgroud)
两者都返回无源服务器。
主动和被动的作业 ID 不同:
--08C63F07-0853-41DA-BC88-8FDF44AE491F -- passive
--E8C88965-C581-4E06-B651-CC10637FCEEF -- active
Run Code Online (Sandbox Code Playgroud)
两个作业都在其步骤中使用相关数据库:
@database_name=N'DB1',
Run Code Online (Sandbox Code Playgroud)
--> 不应该在被动实例上访问,导致失败。 没有可读的辅助
数据库在被动实例上不可访问:
两台服务器的版本:14.0.3030.27
T-SQL 作业步骤命令示例
@subsystem=N'TSQL',
@command=N'update statistics dbo.table with fullscan ...'
Run Code Online (Sandbox Code Playgroud)
作业开始时,被动实例上没有运行任何内容。
编辑:
重新启动被动节点上的代理“修复”了这个问题,导致执行时出现新错误:
无法连接到 SQL Server“INDCSPSQLP01”。步骤失败。
因此,它不再更新主实例的统计信息
申请信息
SQLAgent - TSQL JobStep (Job 0x9D358B2EF6C53C4BAD6A61CA87D51BF5 : Step 1)
SQLAgent - TSQL JobStep (Job 0x6589C8E881C5064EB651CC10637FCEEF : Step 1)
Run Code Online (Sandbox Code Playgroud)
我没有诊断为什么会出现此问题,但是如果您有在可用性组中的数据库上运行的作业,最好在步骤 1 中包含一个检查,该检查使用该fn_hadr_is_primary_replica
函数来检查它是在主数据库上运行还是在主数据库上运行次要的。
IF (sys.fn_hadr_is_primary_replica('DB1') <> 1)
BEGIN
RAISERROR('%s is secondary', 11, 1, @@servername );
END
Run Code Online (Sandbox Code Playgroud)
配置此步骤以在失败时退出作业。这比尝试运行失败的东西要好,因为它正在击中辅助。
归档时间: |
|
查看次数: |
412 次 |
最近记录: |