Saya telah mengerjakan kode dalam T-SQL untuk menambahkan jadwal baru ke pekerjaan SQL Agent menggunakan sp_add_jobschedule proc dalam database msdb. Ketika saya menambahkan jadwal baru (biasanya sekali jalan pada tanggal / waktu tertentu) dan segera melihat nilai-nilai dalam sysjobschedules dan sysschedules, saya dapat melihat bahwa jadwal baru telah ditambahkan dan terkait dengan job_id untuk Agen SQL saya. pekerjaan. Namun, nilai untuk next_run_date dan next_run_time memiliki 0 di dalamnya. Ketika saya kembali dan melihat mereka lagi dalam 2 atau 3 menit, mereka masih menunjukkan 0 di dalamnya. Namun ketika saya kembali lagi 5 atau 10 menit kemudian, sekarang dengan benar menunjukkan nilai tanggal dan waktu yang sesuai dengan proses yang dijadwalkan berikutnya.
Jadi pertanyaan saya adalah:
- Seberapa sering nilai-nilai ini diperbarui?
- Proses apa yang memperbarui nilai-nilai ini?
- Jika saya menambahkan jadwal yang, katakanlah, 1 menit di masa depan, apakah itu berarti pekerjaan itu tidak akan berjalan karena next_run_date / waktu belum diperbarui?
Contoh kode yang saya gunakan untuk menambahkan jadwal baru:
exec msdb.dbo.sp_add_jobschedule @job_id = @jobID
, @name = @JobName
, @enabled = 1
, @freq_type = 1
, @freq_interval = 0
, @freq_subday_type = 0
, @freq_subday_interval = 0
, @freq_relative_interval = 0
, @freq_recurrence_factor = 0
, @active_start_date = @ScheduleRunDate
, @active_end_date = 99991231
, @active_start_time = @ScheduleRunTime
, @active_end_time = 235959
di mana @jobID adalah biner (16) yang menyimpan job_id dari pekerjaan tersebut, @ScheduleRunDate dan @ScheduleRunTime adalah INT dengan tanggal dan waktu masing-masing.
Jawaban:
Jawaban singkat
Sepertinya data dalam
msdb.dbo.sysjobschedules
diperbarui oleh utas latar belakang di SQL Agent, diidentifikasi sebagaiSQLAgent - Schedule Saver
, setiap 20 menit (atau kurang sering, jikaxp_sqlagent_notify
belum dipanggil dan tidak ada pekerjaan yang berjalan sementara itu).Untuk informasi yang lebih akurat, lihat
next_scheduled_run_date
dimsdb.dbo.sysjobactivity
. Ini diperbarui secara waktu-nyata kapan saja suatu pekerjaan diubah atau pekerjaan telah berjalan. Sebagai bonus tambahan,sysjobactivity
menyimpan data dengan cara yang benar (sebagai kolom datetime), membuatnya jauh lebih mudah untuk digunakan dibandingkan dengan INT yang bodoh itu.Itulah jawaban singkatnya:
Jawaban panjang
Jika Anda ingin mengikuti kelinci sejenak, saat Anda menelepon
sp_add_jobschedule
, rangkaian peristiwa ini mulai bergerak:Sekarang, kita tidak bisa mengejar kelinci lebih jauh lagi, karena kita tidak bisa mengintip ke dalamnya
xp_sqlagent_notify
. Tetapi saya pikir kita dapat menganggap bahwa prosedur yang diperluas ini berinteraksi dengan layanan Agen dan memberi tahu bahwa telah ada perubahan pada pekerjaan dan jadwal spesifik ini. Dengan menjalankan jejak sisi server kita dapat melihat bahwa, segera, SQL dinamis berikut ini disebut oleh SQL Agent:Tampaknya
sysjobactivity
diperbarui segera, dansysjobschedules
hanya diperbarui sesuai jadwal. Jika kita mengubah jadwal baru menjadi sekali sehari, misKami masih melihat pembaruan langsung
sysjobactivity
seperti di atas, dan kemudian pembaruan lain setelah pekerjaan selesai. Berbagai pembaruan berasal dari latar belakang dan utas lainnya dalam SQL Agent, misalnya:Utas latar belakang (utas "Penghemat Jadwal") akhirnya muncul dan diperbarui
sysjobschedules
; dari penyelidikan awal saya tampaknya ini setiap 20 menit, dan hanya terjadi jikaxp_sqlagent_notify
telah dipanggil karena ada perubahan pada pekerjaan sejak terakhir kali dijalankan (saya tidak melakukan pengujian lebih lanjut untuk melihat apa yang terjadi jika satu pekerjaan telah dilakukan diubah dan yang lain telah dijalankan, jika "Jadwal Saver" utas memperbarui keduanya - saya kira itu harus, tetapi akan meninggalkan itu sebagai latihan untuk pembaca).Saya tidak yakin apakah siklus 20 menit diimbangi dari saat SQL Agent dimulai, atau mulai tengah malam, atau dari sesuatu yang spesifik mesin. Pada dua contoh berbeda pada server fisik yang sama, utas "Schedule Saver" diperbarui
sysjobschedules
, pada kedua contoh, pada waktu yang hampir bersamaan - 18:31:37 & 18:51:37 pada satu, dan 18:31:39 & 18:51:39 di sisi lain. Saya tidak memulai SQL Server Agent pada saat yang sama pada server ini, tetapi ada kemungkinan jarak jauh bahwa waktu mulai kebetulan adalah 20 menit offset. Saya ragu, tetapi saya tidak punya waktu sekarang untuk mengonfirmasi dengan memulai kembali Agen pada salah satu dari mereka dan menunggu lebih banyak pembaruan terjadi.Saya tahu siapa yang melakukannya, dan kapan itu terjadi, karena saya meletakkan pelatuk di sana dan menangkapnya, kalau-kalau saya tidak bisa menemukannya di jejak, atau saya tidak sengaja menyaringnya.
Yang mengatakan, tidak sulit untuk menangkap dengan jejak standar, ini bahkan disebut sebagai DML non-dinamis:
Jika Anda ingin menjalankan jejak yang lebih difilter untuk melacak perilaku ini dari waktu ke waktu (mis. Bertahan melalui restart Agen SQL alih-alih sesuai permintaan), Anda dapat menjalankan yang memiliki appname =
'SQLAgent - Schedule Saver'
...Jadi saya pikir jika Anda ingin segera mengetahui jangka waktu berikutnya, lihatlah
sysjobactivity
, tidaksysjobschedules
. Tabel ini diperbarui secara langsung oleh Agen atau utas latar belakangnya ("Perbarui aktivitas pekerjaan", "Manajer Pekerjaan", dan "Mesin Doa Pekerjaan") saat aktivitas terjadi atau saat diberitahukan olehxp_sqlagent_notify
.Perlu diketahui, bahwa sangat mudah untuk membuat tabel baik - karena tidak ada perlindungan terhadap penghapusan data dari tabel ini. (Jadi, jika Anda memutuskan untuk membersihkan, misalnya, Anda dapat dengan mudah menghapus semua baris untuk pekerjaan itu dari tabel aktivitas.) Dalam hal ini saya tidak yakin bagaimana SQL Server Agent mendapatkan atau menyimpan tanggal menjalankan berikutnya. Mungkin layak untuk diselidiki lebih lanjut di kemudian hari ketika saya memiliki waktu luang ...
sumber
msdb.dbo.sp_help_job
selalu muncul untuk mengembalikan yang sebenarnyanext_run_date
/next_run_time
.Menggunakan
sp_get_composite_job_info
, yang melakukan panggilan berikut untuk benar-benar mengambilnext_run_date/time
.Karena
sysjobschedule
tampaknya tidak dapat diandalkan, saya hanya akan menggunakansp_help_job
.sumber