Technical Article

Faster Backuphistory delete

,

Should be orders of magnitude faster than the default cleanup proc.

Mine was running for 25 minutes when I decided to kill it and add a small change.

The solution to the slowness was to replace all the table variables in the MS proc with temp tables.

Additionally, added clustered primary keys to the temp tables.

Choose how much history you want to keep and assign it as per below.

declare @olddate datetime

declare @var int = -120

set @olddate = DATEADD(day,@var,GETDATE())

exec [dbo].[faster_delete_backuphistory] @oldest_date = @olddate

Be careful as it may complete the task before you have a chance to stop it in SSMS, so test it first to see if it meets your needs.

/*
This is the MS proc but using temp tables instead of table variables.

declare @olddate datetime
declare @var int = -120
set @olddate = DATEADD(day,@var,GETDATE())
exec [dbo].[faster_delete_backuphistory] @oldest_date = @olddate

*/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE  PROCEDURE [dbo].[faster_delete_backuphistory]
  @oldest_date datetime
AS
BEGIN
  SET NOCOUNT ON

  CREATE TABLE #backup_set_id  (backup_set_id INT primary key clustered)
  CREATE TABLE  #media_set_id        (media_set_id INT primary key clustered)
  CREATE TABLE  #restore_history_id  (restore_history_id INT primary key clustered)

  INSERT INTO #backup_set_id (backup_set_id)
  SELECT DISTINCT backup_set_id
  FROM msdb.dbo.backupset
  WHERE backup_finish_date < @oldest_date

  INSERT INTO #media_set_id (media_set_id)
  SELECT DISTINCT media_set_id
  FROM msdb.dbo.backupset
  WHERE backup_finish_date < @oldest_date

  INSERT INTO #restore_history_id (restore_history_id)
  SELECT DISTINCT restore_history_id
  FROM msdb.dbo.restorehistory
  WHERE backup_set_id IN (SELECT backup_set_id
                          FROM #backup_set_id)

  BEGIN TRANSACTION

  DELETE FROM msdb.dbo.backupfile
  WHERE backup_set_id IN (SELECT backup_set_id
                          FROM #backup_set_id)
  IF (@@error > 0)
    GOTO Quit

  DELETE FROM msdb.dbo.backupfilegroup
  WHERE backup_set_id IN (SELECT backup_set_id
                          FROM #backup_set_id)
  IF (@@error > 0)
    GOTO Quit

  DELETE FROM msdb.dbo.restorefile
  WHERE restore_history_id IN (SELECT restore_history_id
                               FROM #restore_history_id)
  IF (@@error > 0)
    GOTO Quit

  DELETE FROM msdb.dbo.restorefilegroup
  WHERE restore_history_id IN (SELECT restore_history_id
                               FROM #restore_history_id)
  IF (@@error > 0)
    GOTO Quit

  DELETE FROM msdb.dbo.restorehistory
  WHERE restore_history_id IN (SELECT restore_history_id
                               FROM #restore_history_id)
  IF (@@error > 0)
    GOTO Quit

  DELETE FROM msdb.dbo.backupset
  WHERE backup_set_id IN (SELECT backup_set_id
                          FROM #backup_set_id)
  IF (@@error > 0)
    GOTO Quit

  DELETE msdb.dbo.backupmediafamily
  FROM msdb.dbo.backupmediafamily bmf
  WHERE bmf.media_set_id IN (SELECT media_set_id
                             FROM #media_set_id)
    AND ((SELECT COUNT(*)
          FROM msdb.dbo.backupset
          WHERE media_set_id = bmf.media_set_id) = 0)
  IF (@@error > 0)
    GOTO Quit

  DELETE msdb.dbo.backupmediaset
  FROM msdb.dbo.backupmediaset bms
  WHERE bms.media_set_id IN (SELECT media_set_id
                             FROM #media_set_id)
    AND ((SELECT COUNT(*)
          FROM msdb.dbo.backupset
          WHERE media_set_id = bms.media_set_id) = 0)
  IF (@@error > 0)
    GOTO Quit

  COMMIT TRANSACTION
  RETURN

Quit:
  ROLLBACK TRANSACTION

END

Rate

You rated this post out of 5. Change rating

Share

Share

Rate

You rated this post out of 5. Change rating