Cara yang baik untuk memanggil beberapa pekerjaan SQL Server Agent secara berurutan dari satu pekerjaan utama?

11

Saya punya beberapa pekerjaan Agen SQL Server yang harus dijalankan secara berurutan. Untuk menyimpan ikhtisar bagus tentang pekerjaan yang seharusnya dijalankan, saya telah menciptakan pekerjaan utama yang memanggil pekerjaan lain dengan panggilan EXEC msdb.dbo.sp_start_job N'TEST1'. The sp_start_jobselesai langsung (Ayub Langkah 1), tapi kemudian saya ingin pekerjaan utama saya untuk menunggu sampai pekerjaan TEST1selesai sebelum memanggil pekerjaan berikutnya.

Jadi saya telah menulis skrip kecil ini yang mulai dieksekusi tepat setelah pekerjaan dipanggil (Pekerjaan Langkah 2), dan memaksa pekerjaan utama untuk menunggu sampai sub pekerjaan selesai:

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;

Ini cukup berhasil. Tetapi saya merasa solusi yang lebih cerdas dan / atau lebih aman ( WHILE 1 = 1?) Harus dimungkinkan.

Saya ingin tahu tentang hal-hal berikut, harap Anda dapat memberi saya beberapa wawasan:

  • Apa masalah dengan pendekatan ini?
  • Bisakah Anda menyarankan cara yang lebih baik untuk melakukan ini?

(Saya memposting pertanyaan ini di StackOverflow terlebih dahulu, karena saya fokus pada peningkatan kode. Masih valid. Tapi tebakan saya adalah bahwa orang-orang di sini pada umumnya akan memiliki hal-hal yang lebih pintar untuk mengatakan tentang mengapa saya tidak boleh mencoba melakukan ini dengan cara saya ' saya melakukannya sekarang, atau memberikan alternatif yang baik.)

EDIT (25 Juli)
Tampaknya tidak terlalu banyak yang salah dengan skrip saya, berdasarkan pada rendahnya jumlah jawaban yang menunjukkan masalah dengan skrip itu :-) Alternatif dari skrip semacam ini adalah dengan menggunakan alat yang dirancang untuk ini tugas (seperti SQL Sentry Event Manager atau ...) - atau untuk menulis sendiri alat tersebut. Kami tidak akan membeli alat seperti itu di perusahaan saya saat ini, jadi untuk sekarang saya hanya akan tetap dengan skrip.

Komunitas
sumber
Sudahkah Anda mempertimbangkan memiliki pekerjaan ini sebagai langkah dalam pekerjaan utama alih-alih pekerjaan mandiri? Itu akan mengurangi kerumitan, terutama jika mereka hanya dipanggil bersama secara berurutan seperti ini ...
Aaron Bertrand
Itu keseimbangan. Ini akan menjadi pemeliharaan 'bersih' jika kita menambahkan semua pekerjaan sebagai langkah ke pekerjaan utama, tetapi kita akan kehilangan banyak tinjauan dan kemungkinan untuk menjalankan pekerjaan tertentu secara manual saat kita melakukan itu. Jadi saya sudah pasti mempertimbangkannya, tetapi 'solusi' saat ini memiliki kelebihan terlalu banyak - selama itu berhasil.

Jawaban:

9

Penafian: Saya bekerja untuk SQL Sentry.

Produk SQL Sentry Event Manager kami memiliki fasilitas yang dibangun persis untuk ini: untuk rantai pekerjaan dan mengaturnya dalam berbagai pesanan alur kerja.

Saya mulai menggunakan SQL Sentry tahun lalu, sebelum saya bergabung dengan perusahaan, untuk melakukan hal ini. Apa yang saya inginkan adalah cara untuk memulai pekerjaan pemulihan di server pengujian kami segera setelah cadangan produksi selesai.

Apa yang awalnya saya terapkan hanyalah buffer substansial antara waktu mulai pekerjaan cadangan dan waktu mulai pemulihan. Ini bukan sangat mudah; karena waktu pencadangan bervariasi, buffer sering kali meninggalkan kami dengan waktu yang terbuang dimana pemulihan belum dimulai meskipun bisa. Dan terkadang buffer tidak cukup.

Apa yang saya terapkan selanjutnya mirip dengan apa yang Anda miliki - saya menulis pekerjaan di server uji yang dimulai segera setelah cadangan yang dijadwalkan, dan terus melakukan polling untuk melihat kapan pekerjaan itu selesai. Yang kemudian diubah hanya memiliki langkah kedua dalam pekerjaan cadangan yang memperbarui tabel di server pengujian. Tidak jauh berbeda, kecuali pekerjaan pemulihan hanya harus menonton meja secara lokal alih-alih memantau riwayat pekerjaan dari jarak jauh. Memikirkan kembali ini bisa menjadi pemicu di meja itu yang memanggil sp_start_jobagar pekerjaan itu tidak harus berjalan setiap n menit (atau dijadwalkan sama sekali).

Solusi terakhir adalah untuk rantai pekerjaan bersama ... ketika cadangan di server A selesai, Manajer Acara memulai pekerjaan pemulihan di server B. Dan jika ada pekerjaan ketiga, dan pekerjaan keempat, atau logika kondisional berdasarkan apa yang harus dilakukan ketika suatu pekerjaan gagal vs. berhasil, dll., ini semua dapat dipertanggungjawabkan. Desainer alur kerja akan mengingatkan Anda sedikit tentang SSIS:

masukkan deskripsi gambar di sini

Mekanika yang mendasari apa yang saya jelaskan bukanlah operasi roket, tentu saja. Anda bisa menulis sendiri bungkus chaining jenis ini jika Anda duduk dan melakukannya. Hanya memberi Anda satu alternatif di mana Anda tidak perlu melakukannya.

Aaron Bertrand
sumber
2

Masalah utama dengan pendekatan Anda adalah bahwa Anda harus terus-menerus berputar sampai sesuatu terjadi (yang bisa menjadi waktu yang sangat lama atau bahkan tidak pernah) dan itu tidak terasa benar. Itulah sebabnya saya kira Anda mengajukan pertanyaan.

Jadi, bagaimana dengan menggunakan pendekatan berbasis data untuk masalah Anda? Misalnya, buat tabel 'audit' yang ditulis masing-masing pekerjaan saat dimulai dan selesai:

Nama Pekerjaan | Waktu Mulai | Akhir waktu
--------- + ------------------- + ------------------
Test1 2012-07-26 07:30 2012-07-26 07:35

Buat tabel 'pemrosesan' yang mencantumkan semua pekerjaan dan urutan pelaksanaannya:

Nama Pekerjaan | Jalankan Pesanan
--------- + ---------
Test1 | 1
Test2 | 2
Test3 | 3

Buat pemicu sisipan di tabel audit, sehingga ketika pekerjaan selesai dan catatan audit dimasukkan, pemicu kueri tabel pemrosesan untuk pekerjaan berikutnya (dengan Run Order) dan kemudian meluncurkannya.

Manfaat dari pendekatan ini adalah:

  1. Cukup mudah untuk dikembangkan dan dipelihara.
  2. Ini memberi kemampuan untuk menambahkan pekerjaan baru atau mengubah urutan pekerjaan yang ada melalui tabel pemrosesan tanpa harus mengubah baris kode.
  3. Tabel audit memberikan beberapa visibilitas ketika hal-hal telah terjadi.
  4. Itu tidak membuang siklus CPU. Pemicunya hanya akan menyala ketika sesuatu telah terjadi.
  5. Ini terasa 😉 tepat

HTH

paco
sumber
1
Terima kasih banyak, cintai jawaban Anda! Saya pasti akan mencoba ini!