Bir ana işten sırayla birden fazla SQL Server Agent iş çağırmak için iyi bir yol?


11

Ben sırayla çalışması gereken birkaç SQL Server Agent işleri var. Yürütülmesi gereken işlerle ilgili güzel bir genel bakış sağlamak için, diğer işleri bir çağrı ile çağıran bir ana iş yarattım EXEC msdb.dbo.sp_start_job N'TEST1'. sp_start_jobİş dek anında bitirir (İş Adım 1), ama sonra bekle benim ana iş istiyorum TEST1sonraki işi çağırmadan önce tamamladı.

Bu yüzden iş çağrıldıktan hemen sonra yürütülmeye başlayan bu küçük komut dosyasını yazdım (İş Adımı 2) ve ana işi alt iş bitene kadar beklemeye zorlar:

WHILE 1 = 1
  BEGIN
    WAITFOR DELAY '00:05:00.000';

    SELECT *
    INTO   #jobs
    FROM   OPENROWSET('SQLNCLI', 'Server=TESTSERVER;Trusted_Connection=yes;',
           'EXEC msdb.dbo.sp_help_job @job_name = N''TEST1'',
           @execution_status = 0, @job_aspect = N''JOB''');

    IF NOT (EXISTS (SELECT top 1 * FROM #jobs))
      BEGIN
        BREAK
      END;

    DROP TABLE #jobs;

  END;

Bu yeterince iyi çalışıyor. Ama daha akıllı ve / veya daha güvenli ( WHILE 1 = 1?) Çözümlerin mümkün olması gerektiğini hissettim .

Aşağıdaki şeyleri merak ediyorum, umarım bana bazı bilgiler verebilirsin:

  • Bu yaklaşımla ilgili sorunlar nelerdir?
  • Bunu yapmanın daha iyi bir yolunu önerebilir misiniz?

(Bu soruyu ilk önce StackOverflow'a gönderdim , çünkü kodun geliştirilmesine odaklanıyordum. Hala geçerli. Ama benim tahminim, buradaki insanların genel olarak bunu neden böyle yapmaya çalışmamam gerektiğini söyleyecek daha akıllı şeyleri olacağı ' şimdi yapıyorum veya iyi alternatifler sunuyorum.)

DÜZENLEME (25 Temmuz)
Görünüşe göre senaryo ile çok fazla yanlış değil, onunla ilgili sorunları gösteren düşük cevap sayısına göre :-) Bu tür komut dosyalarına alternatif olarak, bunlar için tasarlanmış bir araç kullanmak gibi görünüyor görevleri (SQL Sentry Event Manager veya ... gibi) - veya böyle bir aracı kendiniz yazmak için. Şu anki şirketimde böyle bir araç satın almayacağız, bu yüzden şimdilik senaryoya sadık kalacağım.


Bu işleri bağımsız işler yerine ana işte adım olarak görmeyi düşündünüz mü? Bu karmaşıklığı azaltacaktır, özellikle de bu şekilde bir sırada birlikte çağrıldıklarında ...
Aaron Bertrand

Bu bir denge. Tüm işleri ana işe adım olarak eklersek 'daha temiz' bakım olurdu, ancak bunu yaparken çok fazla genel bakış ve belirli işleri manuel olarak yürütme olasılığını kaybederdik. Bu yüzden kesinlikle düşündüm, ama mevcut 'çözüm'ün' çalıştığı sürece çok fazla avantajı var.

Yanıtlar:


9

Yasal Uyarı: SQL Sentry için çalışıyorum.

Bizim SQL Nöbetçi Etkinlik Yöneticisi ürünü bunun için tam olarak inşa edilmiş bir tesis vardır: zincir işlerine ve çeşitli iş akışı siparişlerinde düzenleyin.

SQL Sentry'i yıllar önce, şirkete katılmadan önce, tam olarak bunu yapmak için kullanmaya başladım. İstediğim, üretim yedeklemesi bittikten hemen sonra test sunucumuzda bir geri yükleme işine başlamanın bir yoluydu.

Başlangıçta uyguladığım sadece yedekleme işi başlangıç ​​zamanı ve geri yükleme başlangıç ​​zamanı arasında önemli bir arabellek oldu. Bu tam olarak kusursuz değildi; yedekleme süreleri değiştiğinden, arabellek genellikle geri yüklemenin başlamamasına rağmen boşa harcadığımız zamanı bıraktı. Ve bazen arabellek yeterli değildi.

Daha sonra uyguladığım, sahip olduğunuza benziyordu - Test sunucusunda planlanan yedeklemeden kısa bir süre sonra başlayan bir iş yazdım ve işin ne zaman bittiğini görmek için oylamaya devam ettim. Daha sonra, yedekleme sunucusunda test sunucusundaki bir tabloyu güncelleyen ikinci bir adım olacak şekilde değiştirildi. Geri yükleme işinin, iş geçmişini uzaktan izlemek yerine yalnızca yerel olarak bir tablo izlemek zorunda olması dışında pek farklı değil. Bunu düşünmek, o masada çağrılan bir tetikleyici olabilirdi, bu sp_start_jobyüzden iş her n dakikada bir çalışmak zorunda kalmadı (ya da hiç planlanmadı).

Son çözüm, işleri birlikte zincirlemekti ... A sunucusundaki yedekleme bittiğinde, Event Manager B sunucusunda geri yükleme işine başlar. bir iş başarısız olduğunda vs. başarılı olursa, bu durumun tümü açıklanabilir. İş akışı tasarımcısı size biraz SSIS'yi hatırlatacak:

resim açıklamasını buraya girin

Açıkladığım şeyin altında yatan mekaniği elbette roket ameliyatı değil. Oturup yaparsanız, bu tür zincirleme ambalajını kendiniz yazabilirsiniz. Sadece gerekmeyen bir alternatif sunuyor.


2

Yaklaşımınızla ilgili temel sorun, bir şey olana kadar (çok uzun bir süre ya da asla olmayabilir) ve bu pek doğru hissetmeyene kadar sürekli olarak döngü yapmanız gerektiğidir. Bu yüzden soruyu soruyorsun sanırım.

Peki, probleminize veri odaklı bir yaklaşım kullanmaya ne dersiniz? Örneğin, her işin başladığı ve bittiği zaman yazacağı bir 'denetim' tablosu oluşturun:

İş Adı | Başlangıç ​​Zamanı | Bitiş zamanı
--------- + ------------------- + ------------------
Test1 2012-07-26 07:30 2012-07-26 07:35

Tüm işleri ve yürütülmesi gereken sırayı listeleyen bir 'işleme' tablosu oluşturun:

İş Adı | Siparişi Çalıştır
--------- + ---------
Test1 | 1
Test2 | 2
Test3 | 3

Denetim tablosunda bir ekleme tetikleyicisi oluşturun, böylece bir iş tamamlandığında ve denetim kaydı eklendiğinde, tetikleyici bir sonraki iş için işleme tablosunu (Çalıştırma Sırası ile) sorgular ve sonra başlatır.

Bu yaklaşımın faydaları:

  1. Geliştirilmesi ve bakımı oldukça basittir.
  2. Bir kod satırını değiştirmek zorunda kalmadan işlem tablosu aracılığıyla yeni işler ekleme veya mevcut işlerin sırasını değiştirme olanağı verir.
  3. Denetim tablosu, işlerin ne zaman gerçekleştiği konusunda bir miktar görünürlük sağlar.
  4. CPU döngülerini boşa harcamaz. Tetikleyici sadece bir şey olduğunda tetiklenir.
  5. Doğru hissediyor 😉

HTH


1
Çok teşekkürler, cevabını seviyorum! Bunu kesinlikle deneyeceğim!
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.