SQLSERVER--定期清理维护作业的历史记录

刚删除一个数据库时,在清理数据库备份历史记录时,执行超过近10分钟还未完成,随时查了下,吓死宝宝啦,逻辑读操作竟然高达8000万次以上!

通过UI进行删除数据库时,会默认勾选上“删除数据库备份和还原历史记录信息”,作为多年的老司机,删除数据库应该写脚本进行删除,即使使用UI删除,也应该不勾选该选项,但一时偷懒,直接点执行,导致该操作消耗大量逻辑IO和CPU并持续10分钟还不能成功完成。

勾选上“删除数据库备份和还原历史记录信息”后,会执行下面语句:

EXEC msdb.dbo.sp_delete_database_backuphistory @database_name = N‘monitor‘
GO

执行该存储过程后,会在msdb数据库中嵌套地删除备份相关的N张表,其中一条删除语句如下:

 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 )

当备份和还原历史记录信息较多的时候,删除操作消耗的资源会成几何数增长,由于该服务器用作日志传送服务器,承载很多个数据库的日志传送,因此相关备份表中存有大量数据,导致删除操作长时间不能完成。

解决办法:

定期执行下面脚本来清理备份还原数据:

--设置历史记录保存期限为1天
DECLARE @keepMinutes BIGINT
SET @keepMinutes= 60*24

DECLARE @expiredDT NVARCHAR(100)
SELECT  @expiredDT = dbo.ufn_FormatDate(DATEADD(MINUTE, 0 - @keepMinutes,
                                                GETDATE()),
                                        ‘yyyy-MM-ddTHH:mm:ss‘)

EXEC msdb.dbo.sp_delete_backuphistory @expiredDT

EXEC msdb.dbo.sp_purge_jobhistory @oldest_date = @expiredDT

EXEC msdb.dbo.sp_maintplan_delete_log NULL, NULL, @expiredDT

上面脚本中使用到一个日期格式转换函数,代码为:

/****** Object:  UserDefinedFunction [dbo].[ufn_FormatDate]    Script Date: 2015/11/24 19:40:45 ******/
DROP FUNCTION [dbo].[ufn_FormatDate]
GO

/****** Object:  UserDefinedFunction [dbo].[ufn_FormatDate]    Script Date: 2015/11/24 19:40:45 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

--====================================
--将时间转换成制定格式的字符串
CREATE FUNCTION [dbo].[ufn_FormatDate]
   (
     @Datetime DATETIME ,
     @FormatMask VARCHAR(32)
   )
RETURNS VARCHAR(32)
AS
   BEGIN

       DECLARE @StringDate VARCHAR(32)

       SET @StringDate = @FormatMask

       IF ( CHARINDEX(‘YYYY‘, @StringDate) > 0 )
           SET @StringDate = REPLACE(@StringDate, ‘YYYY‘,
                                     DATENAME(YY, @Datetime))

       IF ( CHARINDEX(‘YY‘, @StringDate) > 0 )
           SET @StringDate = REPLACE(@StringDate, ‘YY‘,
                                     RIGHT(DATENAME(YY, @Datetime), 2))
       IF ( CHARINDEX(‘MM‘, @StringDate) > 0 )
           SET @StringDate = REPLACE(@StringDate, ‘MM‘,
                                     RIGHT(‘0‘ + CONVERT(VARCHAR, DATEPART(MM,
                                                             @Datetime)), 2))

       IF ( CHARINDEX(‘DD‘, @StringDate) > 0 )
           SET @StringDate = REPLACE(@StringDate, ‘DD‘,
                                     RIGHT(‘0‘ + DATENAME(DD, @Datetime), 2))

       IF ( CHARINDEX(‘HH‘, @StringDate) > 0 )
           SET @StringDate = REPLACE(@StringDate, ‘HH‘,
                                     RIGHT(‘0‘ + DATENAME(HH, @Datetime), 2))

       IF ( CHARINDEX(‘mm‘, @StringDate) > 0 )
           SET @StringDate = REPLACE(@StringDate, ‘mm‘,
                                     RIGHT(‘0‘ + DATENAME(mm, @Datetime), 2))

       IF ( CHARINDEX(‘ss‘, @StringDate) > 0 )
           SET @StringDate = REPLACE(@StringDate, ‘ss‘,
                                     RIGHT(‘0‘ + DATENAME(ss, @Datetime), 2))

       IF ( CHARINDEX(‘ms‘, @StringDate) > 0 )
           SET @StringDate = REPLACE(@StringDate, ‘ms‘,
                                     RIGHT(‘0‘ + DATENAME(ms, @Datetime), 2))

       RETURN @StringDate

   END
--====================================

GO

没多少技术含量,厚脸拿出来供初学者学习下!

============================================

时间: 2024-10-10 05:14:31

SQLSERVER--定期清理维护作业的历史记录的相关文章

SQLSERVER 索引维护

SQLSERVER 索引维护 2012-03-08 00:30:09|  分类: 默认分类 |  标签:sql  sqlserver  索引  |举报|字号 订阅 Pages & Extents(页和扩展盘区)SQL Server 2000最基本的数据存储单元是data page,1个8K的存储空间.在分配存储空间时,SQL Server 2000并不是每次分配1个page,基本的存储空间分配单元是8个page的连续空间,称为extent.关于SQL Server 2000的page.exten

sqlserver 监控自动化作业执行情况

ALTER procedure [dbo].[monitorJob] @name varchar(100) as begin declare @bd varchar(100) ; if exists( select * from  msdb.dbo.sysjobhistory where job_id in (select job_id from msdb.dbo.sysjobs where [name][email protected] ) and run_date=convert(varch

sqlserver 作业调度(作业常用的几个步骤)

--[作业常用的几个步骤] EXEC msdb.dbo.sp_delete_job EXEC msdb.dbo.sp_add_job EXEC msdb.dbo.sp_add_jobstep EXEC msdb..sp_add_jobschedule EXEC msdb.dbo.sp_add_jobserver EXEC msdb.dbo.sp_start_job --删除作业 IF EXISTS (SELECT JOB_ID FROM MSDB.DBO.SYSJOBS_VIEW WHERE N

禁用SQLSERVER代理的作业

USE msdb ;GOEXEC dbo.sp_update_job    @job_name = N'作业名称',    @new_name = N'作业名称'',    @description = N'',    @enabled = 0 ;--1 启用作业 ,0 禁用作业GO

sqlserver日常维护脚本

SQL code --备份declare @sql varchar(8000) set @sql='backup database mis to disk=''d:\databack\mis\mis'+rtrim(convert(varchar,getdate(),112))+'.bak''' exec(@sql) --删除15天前备份文件 set @sql='del d:\databack\mis\mis' +rtrim(convert(varchar,getdate()-15,112))+'

sqlserver 自动创建作业执行备份数据库

declare @name varchar(250)set @name='I:\dydb_n\dydb_n'+convert(varchar(50),getdate(),112)+ left(right(convert(varchar(50),getdate(),120),8),2) + substring(right(convert(varchar(50),getdate(),120),8),4,2) + '.bak'BACKUP DATABASE [dydb_n] TODISK = @nam

查看SQLServer 代理作业的历史信息

原文:查看SQLServer 代理作业的历史信息 不敢说众所周知,但是大部分人都应该知道SQLServer的代理作业情况都存储在SQLServer5大系统数据库(master/msdb/model/tempdb/resources)中的MSDB中,而由于代理作业的长期运行和种类较多,所以一般可以看到msdb的大小往往比其他库加起来还大.本文主要专注在如何查询作业的运行时间点及运行持续时间上. 作为DBA,周期性检查作业情况是一下非常重要的任务.本文不讲述太深入.只讲述如何查询作业的历史运行情况.

SSIS实践入门2:SSIS批量包的调度和SQLServer代理作业配置

趁着上一篇文章的余温,我们继续研究一下SSIS中多个包如何调度,难道需要一个包一个包的配置调度程序吗?显然不是的,接下来我们就说一说在SSIS应用中如何批量的调度所有的作业,本文只讲述一个基本的逻辑过程以及简单测试. 1:发布SSIS包 调度包,就需要我们首先将SSIS包发布到SQLServer的集成服务下面 下面我们就着手把SSIS实践入门1中创建的两个包sqltosql.dtsx和oratosql.dtsx发布到SQLServer服务中的Integration Services下面 1.1:

(转)SQLServer查询数据库各种历史记录

原文地址https://www.cnblogs.com/seusoftware/p/4826958.html 在SQL Server数据库中,从登陆开始,然后做了什么操作,以及数据库里发生了什么,大多都是有记录可循的,但是也有一些确实无从查起. 一. 数据库启动记录 1. 最近一次启动SQL Server的时间 select sqlserver_start_time from sys.dm_os_sys_info; --也可参考系统进程创建的时间,比服务启动时间略晚(秒级) select log