Estou trabalhando no código no T-SQL para adicionar novos agendamentos a um trabalho do SQL Agent usando o processo sp_add_jobschedule no banco de dados msdb. Quando adiciono um novo agendamento (normalmente uma vez em uma data / hora específica) e examino imediatamente os valores em sysjobschedules e sysschedules, vejo que o novo agendamento foi adicionado e está vinculado ao job_id do meu SQL Agent trabalho. No entanto, os valores para next_run_date e next_run_time têm 0 neles. Quando volto e olho para eles novamente em 2 ou 3 minutos, eles ainda mostram 0s neles. No entanto, quando volto mais 5 ou 10 minutos depois, ele agora mostra corretamente os valores de data e hora correspondentes à próxima execução agendada.
Então, minhas perguntas são:
- Com que frequência esses valores são atualizados?
- Que processo atualiza esses valores?
- Se eu adicionar uma programação que seja, digamos, 1 minuto no futuro, isso significa que o trabalho não será executado, pois o próximo_run_date / time ainda não foi atualizado?
Exemplo do código que eu uso para adicionar uma nova programação:
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
onde @jobID é binário (16) que contém o job_id do trabalho em questão, @ScheduleRunDate e @ScheduleRunTime são INTs com data e hora, respectivamente.
Respostas:
Resposta curta
Parece que os dados
msdb.dbo.sysjobschedules
são atualizados por um encadeamento em segundo plano no SQL Agent, identificado comoSQLAgent - Schedule Saver
cada 20 minutos (ou menos frequentemente, sexp_sqlagent_notify
não tiver sido chamado e nenhum trabalho tiver sido executado nesse meio tempo).Para obter informações mais precisas, olhada
next_scheduled_run_date
nomsdb.dbo.sysjobactivity
. Isso é atualizado em tempo real sempre que um trabalho é alterado ou um trabalho é executado. Como um bônus adicional, osysjobactivity
armazena os dados da maneira certa (como uma coluna de data e hora), facilitando muito o trabalho com essas INTs estúpidas.Essa é a resposta curta:
Resposta longa
Se você quiser seguir o coelho por um momento, quando ligar
sp_add_jobschedule
, essa cadeia de eventos será acionada:Agora, não podemos mais perseguir o coelho, porque realmente não podemos espiar o que
xp_sqlagent_notify
acontece. Mas acho que podemos presumir que esse procedimento estendido interage com o serviço do Agente e informa que houve uma alteração nesse trabalho e cronograma específicos. Ao executar um rastreamento do lado do servidor, podemos ver que, imediatamente, o SQL dinâmico a seguir é chamado pelo SQL Agent:Parece que
sysjobactivity
é atualizado imediatamente esysjobschedules
é atualizado apenas em uma programação. Se mudarmos o novo horário para uma vez por dia, por exemplo,Ainda vemos a atualização imediata
sysjobactivity
conforme acima e, em seguida, outra atualização após a conclusão do trabalho. Várias atualizações vêm de segundo plano e outros threads no SQL Agent, por exemplo:Um thread em segundo plano (o thread "Schedule Saver") finalmente aparece e é atualizado
sysjobschedules
; da minha investigação inicial, parece que isso é a cada 20 minutos e só acontece sexp_sqlagent_notify
tiver sido chamado devido a uma alteração feita em um trabalho desde a última vez em que ele foi executado (não realizei nenhum teste adicional para ver o que acontece se um trabalho tiver sido executado). mudou e outro foi executado, se o segmento "Schedule Saver" atualizar os dois - eu suspeito que deve, mas deixará isso como um exercício para o leitor).Não tenho certeza se o ciclo de 20 minutos é deslocado a partir do momento em que o SQL Agent é iniciado, ou da meia-noite ou de algo específico da máquina. Em duas instâncias diferentes no mesmo servidor físico, o segmento "Schedule Saver" foi atualizado
sysjobschedules
, nas duas instâncias, quase exatamente no mesmo horário - 18:31:37 e 18:51:37 em um e 18:31:39 e 18:51:39 por outro. Não iniciei o SQL Server Agent ao mesmo tempo nesses servidores, mas existe a possibilidade remota de que os horários de início tenham sido 20 minutos de deslocamento. Duvido, mas não tenho tempo no momento para confirmar reiniciando o Agent em um deles e aguardando mais atualizações.Sei quem o fez e quando aconteceu, porque coloquei um gatilho lá e o capturei, caso não conseguisse encontrá-lo no rastro ou o filtrasse inadvertidamente.
Dito isto, não é difícil capturar com um rastreamento padrão, esse mesmo aparece como DML não dinâmico:
Se você deseja executar um rastreamento mais filtrado para rastrear esse comportamento ao longo do tempo (por exemplo, persistir na reinicialização do SQL Agent em vez de sob demanda), é possível executar um que tenha appname =
'SQLAgent - Schedule Saver'
...Então, acho que se você quiser saber o próximo tempo de execução imediatamente, olhe
sysjobactivity
, nãosysjobschedules
. Esta tabela é diretamente atualizada pelo Agent ou por seus encadeamentos em segundo plano ("Atualizar atividade da tarefa", "Gerenciador de tarefas" e "Mecanismo de chamada de tarefas") à medida que a atividade acontece ou é notificada porxp_sqlagent_notify
.Esteja ciente, no entanto, de que é muito fácil ocultar uma das tabelas - pois não há proteção contra a exclusão de dados dessas tabelas. (Portanto, se você decidir limpar, por exemplo, poderá remover facilmente todas as linhas desse trabalho da tabela de atividades.) Nesse caso, não tenho certeza de como o SQL Server Agent obtém ou salva a próxima data de execução. Talvez seja digno de mais investigação em uma data posterior, quando eu tiver algum tempo livre ...
fonte
msdb.dbo.sp_help_job
sempre aparece para retornar o valor realnext_run_date
/next_run_time
.Ele usa
sp_get_composite_job_info
, que faz a seguinte chamada para recuperar onext_run_date/time
.Desde que
sysjobschedule
parece não ser confiável, eu apenas usariasp_help_job
.fonte