forked from ktaranov/sqlserver-kit
-
Notifications
You must be signed in to change notification settings - Fork 0
/
DBA_sp_jobhistory_row_limiter.sql
84 lines (68 loc) · 2.97 KB
/
DBA_sp_jobhistory_row_limiter.sql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
/*
this is more or less a copy of MS-provided sp_jobhistory_row_limiter.
we have merely changed the logic to find the config data in our config table vs the registry
and to handle looping through deletes smartly.
no TABLOCKX
tests are in DBA_sysjobhistory_driver_Tests.sfu_dbo_test.sql
*/
if exists (select * from sysobjects where id = object_id('DBA_sp_jobhistory_row_limiter') and sysstat & 0xf = 4)
DROP procedure dbo.DBA_sp_jobhistory_row_limiter
GO
CREATE PROCEDURE DBA_sp_jobhistory_row_limiter
@job_id UNIQUEIDENTIFIER
AS
BEGIN
SET DEADLOCK_PRIORITY LOW
DECLARE @NumDaysToRetain INT
DECLARE @NumFailureDaysToRetain INT
DECLARE @LastDayToRetain INT
DECLARE @LastFailureDayToRetain INT
DECLARE @RowsDeleted INT
SET NOCOUNT ON
-- Get the NumDaysToRetain and NumFailureDaysToRetain
-- FailSafe: maintain 30 days.
SELECT
--j.* , c_byJob.*, c_ByCat.* , c_Default.*
@NumDaysToRetain = COALESCE(c_byJob.NumDaysToRetain,c_byCat.NumDaysToRetain,c_Default.NumDaysToRetain,30) ,
@NumFailureDaysToRetain = COALESCE(c_byJob.NumFailureDaysToRetain,c_byCat.NumFailureDaysToRetain,c_Default.NumFailureDaysToRetain,30)
FROM v_sysjobs j
LEFT JOIN DBA_sysjobhistory_config c_byJob --first we prefer to JOIN first by JobName
ON j.JobName = c_byJob.JobName
LEFT JOIN DBA_sysjobhistory_config c_byCat --next we prefer to JOIN first by Category
ON j.CategoryName = c_byCat.CategoryName
CROSS JOIN DBA_sysjobhistory_config c_Default --last, get me the defaults.
WHERE j.job_id = @job_id AND
c_Default.JobName = '(default)' AND c_Default.CategoryName = '(default)'
--get the actual date of the most recent rows that we wish to maintain.
--convert that to an INT so it works with msdb..sysjobhistory
SELECT @LastDayToRetain = CONVERT(int,CONVERT(varchar(200),(GETDATE() - @NumDaysToRetain),112))
SELECT @LastFailureDayToRetain = CONVERT(int,CONVERT(varchar(200),(GETDATE() - @NumFailureDaysToRetain),112))
--DELETE sysjobhistory rows in a loop, keep going until we have nothing left to delete
SELECT @RowsDeleted = 1
WHILE (@RowsDeleted <> 0)
BEGIN
--handle SUCCESS case
BEGIN TRAN
DELETE TOP (1000)
FROM v_sysjobhistory WITH (READPAST)
WHERE job_id = @job_id
AND run_status IN (1,2,3) --Succeeded, Retry, and Canceled. I view all of these as successes.
AND run_date < @LastDayToRetain
SELECT @RowsDeleted = @@ROWCOUNT;
--PRINT 'SUCCESS rows deleted: ' + convert(varchar(200),@RowsDeleted)
COMMIT
--handle FAILURE case
BEGIN TRAN
DELETE TOP (1000)
FROM v_sysjobhistory WITH (READPAST)
WHERE job_id = @job_id
AND run_status IN (0) --Failure
AND run_date < @LastFailureDayToRetain
COMMIT
SELECT @RowsDeleted = CASE WHEN @@ROWCOUNT = 0 THEN @RowsDeleted ELSE @@ROWCOUNT END
--PRINT 'FAILURE rows deleted (or successes from above): ' + convert(varchar(200),@RowsDeleted)
--catch your breath
--WAITFOR DELAY '00:00:01'
END
RETURN(0) -- Success
END