Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Получить список не выполнившихся job-ов  [new]
ъ
Guest
Приветствую Уважаемый Коллективный Разум!

Есть сервер на котором "живёт" под сотню job-ов.
Job-ы с совершенно разными "шедулерами": есть те, что отрабатывают каждую ночь в заданное время; есть такие которые запускаются раз в месяц, конкретного числа ("разного" числа: 15, 10, 1), тоже ночью.

И вот в одну, не очень прекрасную ночь, серверу "поплохело" (электричество, например, "закончилось"), и job-ы, разумеется, не выполнились.
Теперь вопрос: можно ли как-то, запросом, узнать какие именно джобы не отработали (а должны были) с 0:00ч по 8:00ч этого дня?

Тут нашёл вроде бы как по делу материал , но нехватает "клепки" из него сделать то что хочется )) ...

Спасибо заранее!
16 дек 15, 18:18    [18569426]     Ответить | Цитировать Сообщить модератору
 Re: Получить список не выполнившихся job-ов  [new]
SQL2008
Member

Откуда: Москва
Сообщений: 4478
ъ, там вот даже готовый скрипт приведен
SELECT
    [sJOB].[job_id] AS [JobID]
    , [sJOB].[name] AS [JobName]
    , [sJSTP].[step_uid] AS [StepID]
    , [sJSTP].[step_id] AS [StepNo]
    , [sJSTP].[step_name] AS [StepName]
    , CASE [sJSTP].[last_run_outcome]
        WHEN 0 THEN 'Failed'
        WHEN 1 THEN 'Succeeded'
        WHEN 2 THEN 'Retry'
        WHEN 3 THEN 'Canceled'
        WHEN 5 THEN 'Unknown'
      END AS [LastRunStatus]
    , STUFF(
            STUFF(RIGHT('000000' + CAST([sJSTP].[last_run_duration] AS VARCHAR(6)),  6)
                , 3, 0, ':')
            , 6, 0, ':')
      AS [LastRunDuration (HH:MM:SS)]
    , [sJSTP].[last_run_retries] AS [LastRunRetryAttempts]
    , CASE [sJSTP].[last_run_date]
        WHEN 0 THEN NULL
        ELSE 
            CAST(
                CAST([sJSTP].[last_run_date] AS CHAR(8))
                + ' ' 
                + STUFF(
                    STUFF(RIGHT('000000' + CAST([sJSTP].[last_run_time] AS VARCHAR(6)),  6)
                        , 3, 0, ':')
                    , 6, 0, ':')
                AS DATETIME)
      END AS [LastRunDateTime]
FROM
    [msdb].[dbo].[sysjobsteps] AS [sJSTP]
    INNER JOIN [msdb].[dbo].[sysjobs] AS [sJOB]
        ON [sJSTP].[job_id] = [sJOB].[job_id]
ORDER BY [JobName], [StepNo]


И следующий за ним, в котором описаны расписания для джобов.
Объедините их и получите, то что вам нужно.
Полагаю, что писать скрипт за вас тут никто не будет.
16 дек 15, 18:44    [18569562]     Ответить | Цитировать Сообщить модератору
 Re: Получить список не выполнившихся job-ов  [new]
ъ
Guest
SQL2008,

От первого запроса - вообще мало толку.
Он, совершенно честно говорит, что джоб, запускающийся каждого 16-того числа месяца, 'Succeeded' отработал в ноябре.
Никакой информации о том, что он должен был ещё запустится 16 декабря, но не запустился, так как сервер был выключен ...
Понятно, что ко всему этому "счастью" нужно приджойнить использующийся шедулер (из второго запроса)

А на второй запрос ("следующий за ним", который) я и так "пялюсь" пол дня :)
Вот вернул мне он такое:
RecurrenceFrequency
Occurs every 1 week(s) on , Tuesday, Wednesday, Thursday, FridayOccurs once at 21:00:00
Occurs every 1 week(s) on , Monday, Tuesday, Wednesday, Thursday, FridayOccurs once at 21:00:00
Occurs every 1 day(s)Occurs every 10 Minute(s) between 00:00:00 & 23:59:59
Occurs every 1 day(s)Occurs every 15 Minute(s) between 00:00:00 & 23:59:59
Occurs every 1 day(s)Occurs every 30 Minute(s) between 00:00:00 & 23:59:59
Occurs every 1 day(s)Occurs every 5 Minute(s) between 00:00:00 & 23:59:59
Occurs every 1 day(s)Occurs every 60 Minute(s) between 00:00:00 & 23:59:59
Occurs every 1 day(s)Occurs every 6 Hour(s) between 00:00:00 & 23:59:59
Occurs every 1 day(s)Occurs once at 13:30:00
Occurs every 1 day(s)Occurs every 4 Hour(s) between 06:00:00 & 20:59:59
Occurs every 1 week(s) on , TuesdayOccurs once at 07:00:00
Occurs every 1 day(s)Occurs once at 07:00:00
Occurs on Day 11 of every 1 month(s)Occurs once at 08:00:01
Occurs on Day 12 of every 1 month(s)Occurs once at 08:00:00
Occurs on Day 13 of every 1 month(s)Occurs once at 08:00:00
Occurs on Day 2 of every 1 month(s)Occurs once at 08:00:00
Occurs on Day 22 of every 1 month(s)Occurs once at 08:00:00
Occurs on Day 23 of every 1 month(s)Occurs once at 08:00:00
Occurs on Day 3 of every 1 month(s)Occurs once at 08:00:00
Occurs on Day 10 of every 1 month(s)Occurs once at 05:00:00
Occurs every 1 day(s)Occurs once at 00:30:00
Occurs every 1 day(s)Occurs once at 15:00:00
Occurs every 1 day(s)Occurs every 1 Hour(s) between 05:00:00 & 01:00:00
Occurs every 1 day(s)Occurs every 1 Hour(s) between 06:00:00 & 22:59:59
Occurs every 1 day(s)Occurs once at 10:00:00
Occurs every 1 week(s) on , MondayOccurs once at 07:00:00
Occurs on Day 1 of every 1 month(s)Occurs once at 05:00:00

это что ж, теперь "садиться" и парсить всё это "счастье", с проверками тек.даты на день недели и прочая, и прочая ... ? :) Хотелось же "универсально" что б было. Раз написать скрипт, и в другой раз использовать, а не просто для конкретно сегодняшней "среды" или "вторника" ...
Как-то "грустно" :)
Неужели проще нет какого-то варанта?
16 дек 15, 19:10    [18569668]     Ответить | Цитировать Сообщить модератору
 Re: Получить список не выполнившихся job-ов  [new]
SQL2008
Member

Откуда: Москва
Сообщений: 4478
Могу подкинуть идею.
Создаете 2 таблицы.
1. Джобы и даты-время, когда они должны запускаться, вплоть до текущей даты.
2. Джобы и их состоявшиеся запуски.

Джойните таблицы по LEFT JOIN. Там где во второй таблице NULL и есть дата, когда "должна была, но не смогла"
16 дек 15, 19:55    [18569840]     Ответить | Цитировать Сообщить модератору
 Re: Получить список не выполнившихся job-ов  [new]
ъ
Guest
SQL2008
Могу подкинуть идею.
Создаете 2 таблицы.
1. Джобы и даты-время, когда они должны запускаться, вплоть до текущей даты.
2. Джобы и их состоявшиеся запуски.

Джойните таблицы по LEFT JOIN. Там где во второй таблице NULL и есть дата, когда "должна была, но не смогла"

Вторая табличка, как бы есть - [dbo].[sysjobhistory]
А вот первую получить - совсем не тривиальная задача ...
Оно-то можно, вот тут даже нашёл как, но совсем не просто.

Вообщем, свою задачку я немного упростил, ограничился периодом в рамках одних каледарн.суток,
+ не проверяю разные "навороченные" виды расписаний (типа "третий понедельник" или "второй "week end" месяца, благо таких у меня нет)
Вот такое делает то что нужно


use msdb
go

declare
	 @dt1	datetime	='20151214 00:00'		--	Дата/время-начало проверяемого интервала
	,@dt2	datetime	='20151215 09:00'		--	Дата/время-конец проверяемого интервала

if cast(@dt1 as date)<>cast(@dt2 as date)
begin
	raiserror ('Даты интервала должны быть в рамках одного календарного дня!',16,1)
	goto Exit_
end


-------------------------------------------------------------
declare @DATEFIRST int

print @@DATEFIRST
set @DATEFIRST=@@DATEFIRST
print @@DATEFIRST

set datefirst 7

;with 
--	Список "шедулеров", которые должны были сработать в интервале [@dt1;@dt2]
schedules as 
	(select
		 [schedule_id]
		,[schedule_uid]
		,[name]
		,case [freq_type]
			when 1		then 'One Time'
			when 4		then 'Daily'
			when 8		then 'Weekly'
			when 16		then 'Monthly'
			when 32		then 'Monthly - Relative to Frequency Interval'
			when 64		then 'Start automatically when SQL Server Agent starts'
			when 128	then 'Start whenever the CPUs become idle'
		end as [Occurrence]
	
	
	from [dbo].[sysschedules]

	where [enabled]=1
	and [active_start_time] between datepart(hour, @dt1)*10000+datepart(minute, @dt1)*100+datepart(second, @dt1) and datepart(hour, @dt2)*10000+datepart(minute, @dt2)*100+datepart(second, @dt2)
	and (		
	/*Daily*/	(freq_type=4 and [freq_interval]=1 and freq_subday_type=1)
		or
	/*Weekly*/	(freq_type=8 and ([freq_interval] & power(2,datepart(weekday,@dt1)-1) <> 0))
		or
	/*Monthly*/	(freq_type=16 and [freq_interval]=datepart(day,@dt1))
		)
	),

--	Список джобов, с выбранными "шедулерами". Эти джобы должны были запускаться в интервале [@dt1;@dt2]
jobs as
	(select distinct job_id
	from [dbo].[sysjobschedules]
	where	[schedule_id] in (select [schedule_id] from schedules)),

--	Список джобов (из отобранных), для которых в history нет записи для интервала [@dt1;@dt2]
NoStartJobs as
	(select a.job_id
	from	jobs a
	where not exists 
		(select 1 from	[dbo].[sysjobhistory] b
		where	a.job_id=b.job_id 
		and		run_date=cast(convert(varchar, @dt1,112) as int)  
		and		run_time between datepart(hour, @dt1)*10000+datepart(minute, @dt1)*100+datepart(second, @dt1) and datepart(hour, @dt2)*10000+datepart(minute, @dt2)*100+datepart(second, @dt2)))


--	Результат
select @dt1 as dt, a.[job_id],
	 a.name	as job_name
	,a.description 
	,d.name	as schedule_name
	,d.Occurrence
from		[dbo].[sysjobs]			a
inner join	NoStartJobs				b	on	b.job_id=a.job_id 
inner join	[dbo].[sysjobschedules]	c	on	c.job_id=a.job_id    
inner join	schedules				d	on	d.schedule_id=c.schedule_id    
where a.enabled=1


set datefirst @DATEFIRST
-----------------------------------------------------------------------------

Exit_:


ссылочка по теме, полезная https://msdn.microsoft.com/ru-ru/library/ms178644.aspx
17 дек 15, 14:59    [18573361]     Ответить | Цитировать Сообщить модератору
 Re: Получить список не выполнившихся job-ов  [new]
ъ
Guest
ъ
Оно-то можно, вот тут даже нашёл как, но совсем не просто.

https://www.sql.ru/forum/actualutils.aspx?action=gotomsg&tid=1017296&msg=14191518
17 дек 15, 15:00    [18573375]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить