我刚刚将我的高可用性环境从 SQL 2017 升级到 2019 版本 15.0.4236.7 我在两台服务器上都有相同的 SQL 代理作业,并带有一个初始子句来确定作业是否应该运行(如果服务器是主服务器)。这在过去一直有效,但我遇到了错误。现在,如果辅助服务器上的同一作业调用存储过程,它就会失败。如果作业对只读表进行内联选择,则作业运行没有问题,但 proc 会抛出“目标数据库当前是……”的错误。就好像在执行之前读取了过程,而在调用该行之前不会读取行内选择。这是一个适用于 2017 年辅助服务器但不适用于 2019 年的简单测试。不确定它是错误还是功能。
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
use master;
Declare @AGName varchar(20) = 'MY-SQLAGNAME'
declare @ret bit
SELECT
@ret = count(AGC.name)
FROM
sys.availability_groups_cluster AS AGC
INNER JOIN sys.dm_hadr_availability_replica_cluster_states AS RCS ON RCS.group_id = AGC.group_id
INNER JOIN sys.dm_hadr_availability_replica_states AS ARS ON ARS.replica_id = RCS.replica_id
WHERE
ARS.role_desc = 'PRIMARY' and AGC.name = @AGName and RCS.replica_server_name = @@ServerName
if @ret = 1
begin;
Select 'Shouldt go in here'
select top 1 * from MyDby.dbo.MyTable -- This works
exec MyDb.dbo.AnyProcedure -- This Bombs
end
我建议改变你的流程。
将主要检查逻辑从过程中移到作业的第一步。如果该步骤失败,则退出报告成功的作业。这样,不会运行其他步骤,并且您不必重复逻辑。
您可以使用函数sys.fn_hadr_is_primary_replica而不是查询 DMV 。
一个数据库只能属于一个 AG。所以这里有一个第一步逻辑的例子。然后,当然,您也可以将其包装在一个过程中。