Zadanie należy zakończyć, jeśli nie zostanie wykonane w podstawowej replice
W takim przypadku każde zadanie na obu serwerach wymaga jednego z następujących dwóch fragmentów kodu jako kroku 1:
Sprawdź według nazwy grupy:
IF master.dbo.svf_AgReplicaState('my_group_name')=0
raiserror ('This is not the primary replica.',2,1)
Sprawdź według nazwy bazy danych:
IF master.dbo.svf_AgReplicaState('my_db_name')=0
raiserror ('This is not the primary replica.',2,1)
Jeśli użyjesz tego drugiego, uważaj jednak na systemowe bazy danych - z definicji nie mogą one należeć do żadnej grupy dostępności, więc dla nich zawsze zawiedzie.
Oba działają od razu po wyjęciu z pudełka dla użytkowników administracyjnych. W przypadku użytkowników niebędących administratorami musisz dodać dodatkowe uprawnienia, jedno z nich sugerowane tutaj :
GRANT VIEW SERVER STATE TO [user];
GRANT VIEW ANY DEFINITION TO [user];
Jeśli ustawisz akcję niepowodzenia jako Zakończ raportowanie zadania w pierwszym kroku, nie dostaniesz dziennika pracy pełnego brzydkich znaków czerwonego krzyża, dla głównego zadania zamiast tego zamieniają się w żółte znaki ostrzegawcze.
Z naszego doświadczenia wynika, że nie jest to idealne rozwiązanie. Najpierw przyjęliśmy to podejście, ale szybko straciliśmy orientację w poszukiwaniu zadań, które faktycznie miały problem, ponieważ wszystkie zadania wtórnej repliki zaśmiecały dziennik zadań komunikatami ostrzegawczymi.
Następnie wybraliśmy:
Zadania proxy
Jeśli zastosujesz tę koncepcję, będziesz musiał utworzyć dwa zadania dla każdego zadania, które chcesz wykonać. Pierwszym z nich jest „zadanie proxy”, które sprawdza, czy jest wykonywane w podstawowej replice. Jeśli tak, uruchamia „zadanie robocze”, jeśli nie, kończy się z gracją bez zaśmiecania dziennika komunikatami ostrzegawczymi lub komunikatami o błędach.
Chociaż osobiście nie podoba mi się pomysł posiadania dwóch zadań na zadanie na każdym serwerze, myślę, że jest to zdecydowanie łatwiejsze w utrzymaniu i nie musisz ustawiać działania niepowodzenia w kroku Wyjście z raportowania zadań , co jest nieco niezręczny.
W przypadku zadań przyjęliśmy schemat nazewnictwa. Zadanie proxy jest właśnie wywoływane {put jobname here}
. Nazywa się zadanie pracownika {put jobname here} worker
. Umożliwia to zautomatyzowanie uruchamiania zadania roboczego z serwera proxy. Aby to zrobić, dodałem następującą procedurę do obu master 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
Wykorzystuje to svf_AgReplicaState
funkcję pokazaną powyżej, można ją łatwo zmienić, sprawdzając przy użyciu nazwy bazy danych, wywołując inną funkcję.
Z poziomu jedynego kroku zadania proxy wywołujesz go w następujący sposób:
exec procStartWorkerJob $(ESCAPE_NONE(JOBID)), '{my_group_name}'
Wykorzystuje tokeny, jak pokazano tutaj i tutaj, aby uzyskać identyfikator bieżącego zadania. Procedura następnie pobiera bieżącą nazwę zadania z msdb, dołącza worker
do niej i uruchamia zadanie robocze za pomocą sp_start_job
.
Chociaż nadal nie jest to idealne, sprawia, że dzienniki zadań są bardziej uporządkowane i łatwiejsze w utrzymaniu niż poprzednia opcja. Ponadto zawsze możesz uruchomić zadanie proxy z użytkownikiem sysadmin, więc dodanie dodatkowych uprawnień nie jest konieczne.