Birincil kopyada çalıştırılmadıysa işi sonlandırın
Bu durumda, her iki sunucudaki her iş, Adım 1 olarak aşağıdaki iki kod parçasından birine ihtiyaç duyar:
Grup adına göre kontrol edin:
IF master.dbo.svf_AgReplicaState('my_group_name')=0
raiserror ('This is not the primary replica.',2,1)
Veri tabanı adına göre kontrol et:
IF master.dbo.svf_AgReplicaState('my_db_name')=0
raiserror ('This is not the primary replica.',2,1)
Bu ikincisini kullanırsanız, sistem veritabanlarına dikkat edin - tanım gereği herhangi bir kullanılabilirlik grubunun parçası olamazlar, bu nedenle bunlar için her zaman başarısız olacaktır.
Bunların ikisi de yönetici kullanıcılar için kutudan çıkar. Yönetici olmayan kullanıcılar için, bunlardan biri burada önerilen ek izinler eklemeniz gerekir :
GRANT VIEW SERVER STATE TO [user];
GRANT VIEW ANY DEFINITION TO [user];
Bu ilk adımda başarısızlık eylemini İş raporlama başarısından çık olarak ayarladıysanız, iş günlüğünü çirkin kırmızı çarpı işaretleriyle doldurmazsınız, asıl iş yerine sarı uyarı işaretlerine dönüşürler.
Tecrübelerimize göre bu ideal değil. İlk başta bu yaklaşımı benimsedik, ancak asıl sorunu olan işleri bulma konusunda hızlı bir şekilde izini kaybettik, çünkü tüm ikincil çoğaltma işleri iş günlüğünü uyarı mesajlarıyla karıştırdı.
O zaman ne için gittik:
Proxy işleri
Bu kavramı benimserseniz, gerçekten yapmak istediğiniz görev başına iki iş oluşturmanız gerekir. Birincisi, birincil kopyada çalıştırılıp çalıştırılmadığını kontrol eden "proxy işi". Eğer öyleyse, "işçi işini" başlatır, değilse, günlüğü uyarı veya hata mesajlarıyla karıştırmadan zarafetle sona erer.
Şahsen her sunucuda görev başına iki iş yapma fikrinden hoşlanmıyorum, bunun kesinlikle daha sürdürülebilir olduğunu düşünüyorum ve adımın başarısızlık eylemini, biraz da olsa iş raporlama başarısından çıkmaya ayarlamak zorunda değilsiniz. garip.
İşler için bir adlandırma şeması kabul ettik. Proxy işi sadece denir {put jobname here}
. İşçi işi denir {put jobname here} worker
. Bu, işçi işini proxy'den başlatmayı otomatikleştirmeyi mümkün kılar. Bunu yapmak için, ana dbs'nin ikisine de aşağıdaki prosedürü ekledim:
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
Bu, svf_AgReplicaState
yukarıda gösterilen işlevi kullanır; bunun yerine, diğer işlevi çağırmak yerine, veritabanı adını kullanarak kontrol etmek için kolayca değiştirebilirsiniz.
Proxy işinin tek adımından, buna şöyle diyorsunuz:
exec procStartWorkerJob $(ESCAPE_NONE(JOBID)), '{my_group_name}'
Bu , mevcut işin kimliğini almak için burada ve burada gösterildiği gibi Simgeleri kullanır . Daha sonra prosedür, geçerli iş adını msdb'den alır, ekler worker
ve çalışan işçiyi başlatır sp_start_job
.
Bu hala ideal olmamakla birlikte, iş kayıtlarını bir önceki seçenekten daha düzenli ve sürdürülebilir tutar. Ayrıca, her zaman proxy işinin bir sysadmin kullanıcısıyla çalışmasını sağlayabilirsiniz, bu nedenle herhangi bir ekstra izin eklemek gerekmez.