작업 단위로이 작업을 수행하는 대신 (계속하기로 결정하기 전에 서버 상태에 대한 모든 작업 확인) 두 서버에서 실행중인 작업을 만들어 서버의 상태를 확인했습니다.
- 기본 인 경우 AG에서 데이터베이스를 대상으로하는 단계가있는 작업을 사용하십시오.
- 서버가 보조 서버 인 경우 AG에서 데이터베이스를 대상으로하는 작업을 비활성화하십시오.
이 방법은 여러 가지를 제공합니다
- AG에 데이터베이스가없는 서버 (또는 AG의 입 / 출력 혼합 DB)에서 작동합니다.
- 누구나 새 작업을 생성 할 수 있으며 DB가 AG에 있는지에 대해 걱정할 필요가 없습니다 (작업을 다른 서버에 추가해야한다는 것을 기억해야 함).
- 각 작업에 유용한 오류 이메일이있을 수 있습니다 (모든 작업에 실패 이메일이 있습니까?)
- 작업 기록을 볼 때 실제로 작업을 수행하지 않은 긴 성공 목록 (보조에서)을 보지 않고 실제로 작업이 실제로 실행되고 무언가를 수행했는지 (이것이 기본) 여부를 확인할 수 있습니다.
스크립트는 아래 필드에서 데이터베이스를 확인합니다
이 proc은 각 서버에서 15 분마다 실행됩니다. (작업이 비활성화 된 이유를 사람들에게 알리기 위해 설명을 추가하는 추가 보너스가 있습니다)
/*
This proc goes through all SQL Server agent jobs and finds any that refer to a database taking part in the availability Group
It will then enable/disable the job dependant on whether the server is the primary replica or not
Primary Replica = enable job
It will also add a comment to the job indicating the job was updated by this proc
*/
CREATE PROCEDURE dbo.sp_HADRAgentJobFailover (@AGname varchar(200) = 'AG01' )
AS
DECLARE @SQL NVARCHAR(MAX)
;WITH DBinAG AS ( -- This finds all databases in the AG and determines whether Jobs targeting these DB's should be turned on (which is the same for all db's in the AG)
SELECT distinct
runJobs = CASE WHEN role_desc = 'Primary' THEN 1 ELSE 0 END --If this is the primary, then yes we want to run the jobs
,dbname = db.name
,JobDescription = CASE WHEN hars.role_desc = 'Primary' -- Add the reason for the changing the state to the Jobs description
THEN '~~~ [Enabled] using automated process (DBA_tools.dbo.sp_HADRAgentJobFailover) looking for jobs running against Primary Replica AG ~~~ '
ELSE '~~~ [Diabled] using Automated process (DBA_tools.dbo.sp_HADRAgentJobFailover) because the job cant run on READ-ONLY Replica AG~~~ ' END
FROM sys.dm_hadr_availability_replica_states hars
INNER JOIN sys.availability_groups ag ON ag.group_id = hars.group_id
INNER JOIN sys.Databases db ON db.replica_id = hars.replica_id
WHERE is_local = 1
AND ag.Name = @AGname
)
SELECT @SQL = (
SELECT DISTINCT N'exec msdb..sp_update_job @job_name = ''' + j.name + ''', @enabled = ' + CAST(d.runJobs AS VARCHAR)
+ ',@description = '''
+ CASE WHEN j.description = 'No description available.' THEN JobDescription -- if there is no description just add our JobDescription
WHEN PATINDEX('%~~~%~~~',j.description) = 0 THEN j.description + ' ' + JobDescription -- If our JobDescription is NOT there, add it
WHEN PATINDEX('%~~~%~~~',j.description) > 0 THEN SUBSTRING(j.description,1,CHARINDEX('~~~',j.description)-1) + d.JobDescription --Replace our part of the job description with what we are doing.
ELSE d.JobDescription -- Should never reach here...
END
+ ''';'
FROM msdb.dbo.sysjobs j
INNER JOIN msdb.dbo.sysjobsteps s
INNER JOIN DBinAG d ON d.DbName =s.database_name
ON j.job_id = s.job_id
WHERE j.enabled != d.runJobs -- Ensure we only actually update the job, if it needs to change
FOR XML PATH ('')
)
PRINT REPLACE(@SQL,';',CHAR(10))
EXEC sys.sp_executesql @SQL
완벽한 증거는 아니지만 야간로드 및 시간별 작업의 경우 작업이 완료됩니다.
이 절차를 일정대로 실행하는 것보다 경고 1480 (AG 역할 변경 경고)에 대한 응답으로 실행하는 것이 좋습니다.