Зробіть роботу припиненою, якщо вона не виконується в основній репліку
У цьому випадку для кожного завдання на обох серверах потрібен будь-який із наведених нижче фрагментів коду як крок 1:
Перевірка за назвою групи:
IF master.dbo.svf_AgReplicaState('my_group_name')=0
raiserror ('This is not the primary replica.',2,1)
Перевірте по імені бази даних:
IF master.dbo.svf_AgReplicaState('my_db_name')=0
raiserror ('This is not the primary replica.',2,1)
Якщо ви використовуєте цей другий, остерігайтеся системних баз даних, однак за визначенням вони не можуть бути частиною будь-якої групи доступності, тому для них завжди буде невдало.
Обидва вони працюють з вікна для користувачів адміністратора. Для користувачів без адміністрування потрібно додати додаткові дозволи, один із них запропонований тут :
GRANT VIEW SERVER STATE TO [user];
GRANT VIEW ANY DEFINITION TO [user];
Якщо на цьому першому кроці встановити дію відмови, Вийдіть з повідомлення про успішність роботи , ви не отримаєте журнал завдань, повний негарних знаків червоного хреста, оскільки основна робота замість цього перетвориться на жовті попереджувальні знаки.
З нашого досвіду, це не ідеально. Ми спочатку застосували такий підхід, але швидко втратили шлях щодо пошуку роботи, яка насправді мала проблему, оскільки всі вторинні завдання репліки захаращували журнал завдань попереджувальними повідомленнями.
Тоді для чого ми пішли:
Проксі-завдання
Якщо ви приймете цю концепцію, вам фактично потрібно буде створити два завдання за завдання, яке ви хочете виконати. Перший - це "завдання проксі", яке перевіряє, чи виконується воно в основній репліку. Якщо так, то він запускає "робочу роботу", якщо ні, він просто витончено закінчується, не захаращуючи журнал попередженнями або повідомленнями про помилки.
Хоча мені особисто не подобається ідея мати два завдання на кожне завдання на кожному сервері, я вважаю, що це, безумовно, більш рентабельне, і вам не доведеться встановлювати дію відмови, щоб Вийти з успіху у звіті про роботу , що небагато незграбний
Для робочих місць ми прийняли схему називання. Завдання проксі просто називається {put jobname here}
. Робота працівника називається {put jobname here} worker
. Це дає можливість автоматизувати роботу робочого з проксі. Для цього я додав таку процедуру до обох головних dbs:
CREATE procedure [dbo].[procStartWorkerJob](@jobId uniqueidentifier, @availabilityGroup sysname, @postfix sysname = ' worker') as
declare @name sysname
if dbo.svf_AgReplicaState(@availabilityGroup)=0
print 'This is not the primary replica.'
else begin
SELECT @name = name FROM msdb.dbo.sysjobs where job_id = @jobId
set @name = @name + @postfix
if exists(select name from msdb.dbo.sysjobs where name = @name)
exec msdb.dbo.sp_start_job @name
else begin
set @name = 'Job '''+@name+''' not found.'
raiserror (@name ,2,1)
end
end
GO
При цьому використовується svf_AgReplicaState
функція, показана вище, ви можете легко змінити цю функцію, щоб перевірити, використовуючи ім'я бази даних, замість цього, зателефонувавши до іншої функції.
З єдиного кроку завдання проксі, ви називаєте це так:
exec procStartWorkerJob $(ESCAPE_NONE(JOBID)), '{my_group_name}'
При цьому використовуються маркери, як показано тут і тут, щоб отримати ідентифікатор поточної роботи. Потім процедура отримує поточну назву завдання від msdb, додає worker
її та запускає роботу робочого з використанням sp_start_job
.
Незважаючи на те, що це все ще не ідеально, вони зберігають журнали завдань більш охайними та доступними, ніж попередній варіант. Крім того, ви завжди можете запустити роботу проксі-сервера з користувачем sysadmin, тому додавати додаткові дозволи не потрібно.