バックアップ情報(成功および失敗)SQL Serverを表示するクエリ


9

2つの異なるデータベースをバックアップする2つのジョブがあります。
ジョブ1がDB1 をバックアップする
ジョブ2がDB2

をバックアップするドライブ1の空き容量が少なくなり、ジョブ1が失敗するため、DB1はバックアップに失敗します。この問題を修正するには、スペースを追加する必要がありました。大したことはありません。この問題が1か月にわたって発生しているときに、今日、このことについて知らされました。うん、それはクレイジーだと知っているが、それは開発者だ


DB1の完全なバックアップ履歴を取得したい。msdb.dbo.backupsetテーブルから正常なバックアップ情報を取得できることはわかっていますが、データベースの失敗したバックアップを表示するクエリがあるかどうかを知りたいです。

以下のクエリは、12/31 / 13-1 / 27/14の特定のデータベースのバックアップ履歴を表示します。情報には、サーバー、データベース名、バックアップの開始時間と終了時間、dbsのバックアップにかかった合計時間、dbサイズ、バックアップセット名が含まれます。

SELECT  
   distinct CONVERT(CHAR(100), SERVERPROPERTY('Servername')) AS Server, 
   msdb.dbo.backupset.database_name,  
   msdb.dbo.backupset.backup_start_date,  
   msdb.dbo.backupset.backup_finish_date, 
 CAST((DATEDIFF(second,  msdb.dbo.backupset.backup_start_date,msdb.dbo.backupset.backup_finish_date)) AS varchar)+ ' secs  ' AS [Total Time] ,

   Cast(msdb.dbo.backupset.backup_size/1024/1024 AS numeric(10,2)) AS 'Backup Size(MB)',   
   msdb.dbo.backupset.name AS backupset_name
FROM   msdb.dbo.backupmediafamily  
   INNER JOIN msdb.dbo.backupset ON msdb.dbo.backupmediafamily.media_set_id = msdb.dbo.backupset.media_set_id   
--Enter your database below
--and database_name = 'db_name_here'
and msdb.dbo.backupset.backup_start_date>'2013-12-31' and msdb.dbo.backupset.backup_start_date<'2014-01-27 23:59:59'
ORDER BY  
   msdb.dbo.backupset.database_name, 
   msdb.dbo.backupset.backup_start_date

コードを変更してその情報を取得する方法はありますか?sysjobhistoryおよびsysjobテーブルに対して実行するSQLステートメントを実行することで、JOB1の履歴を取得できます。これは長いショットかもしれません。msdbのsysjobhistory、sysjob、backupset、およびbackupsetmediafamilyテーブルを使用して、必要な結果を生成する方法はありますか?

回答:


15

残念ながら、backupset失敗したバックアップは含まれていません。また、すべての時間を含まない(保持設定によって異なります)msdbを信頼できない場合、これらが保存されている可能性があることを知りsysjobhistoryません。ジョブのコンテキスト外で行われたバックアップ試行-多くのデータベースをバックアップするジョブの場合-ジョブの早い段階で偶然発生しない限り、実際に失敗したデータベースは区別されません-これはメッセージングは​​かなり冗長ですが、切り捨てられるためです。

Job n1つのデータベースのみをバックアップすること、そしてそのジョブのすべての失敗がデータベースがバックアップされなかったことを意味することが絶対にわかっている場合(バックアップが成功した後、ジョブが失敗する可能性があるため、たとえば、縮小または他のメンテナンスの試行)、次に、次のようなクエリを使用できます。

DECLARE @job sysname, @db sysname;

SELECT @job = N'Job 1', @db = N'db_name';

SELECT  
   bs.database_name,  
   bs.backup_start_date,  
   bs.backup_finish_date, 
   [Total Time] = CAST((DATEDIFF(SECOND, bs.backup_start_date,bs.backup_finish_date))
     AS varchar(30))+ ' secs',
   CAST(bs.backup_size/1024/1024 AS decimal(10,2)) AS 'Backup Size(MB)',   
   h.[message]
FROM msdb.dbo.sysjobhistory AS h
INNER JOIN msdb.dbo.sysjobs AS j
ON h.job_id = j.job_id
AND h.step_id = 0
LEFT OUTER JOIN msdb.dbo.backupset AS bs
ON bs.database_name = @db
AND 
 ABS(DATEDIFF(SECOND, bs.backup_start_date, CONVERT(DATETIME,convert(char(8),h.run_date) 
   + ' ' + STUFF(STUFF(RIGHT('0'+CONVERT(char(6),h.run_time),6),3,0,':'),6,0,':')))) < 5
WHERE j.name = @job
ORDER BY bs.backup_start_date;

はい、それはので、本当に醜いですsysjobhistorySQL Serverの2014年にも、店舗には、まだrun_dateしてrun_time別々の整数として。35人の建物全体のダーツボードの背景にまだ決定を下している人は誰でもいると思います。また、バックアップがジョブの最初のステップであることを想定しているため、科学的な日付/時刻の比較ではなく、ジョブの適切なインスタンスをバックアップの適切なインスタンスに関連付けました。ああ、どうすればバックアップとジョブのスキーマを再設計できたらいいのか。

ジョブ以外のより広い範囲が必要な場合は、SQL Serverエラーログで失敗したバックアップを探すことができます(循環していない場合)。

EXEC sp_readerrorlog 0, 1, 'BACKUP failed'; -- current
EXEC sp_readerrorlog 1, 1, 'BACKUP failed'; -- .1 (previous)
EXEC sp_readerrorlog 2, 1, 'BACKUP failed'; -- .2 (the one before that)
....

(しかし、その出力を既存のクエリに組み込むための優れた簡単な方法はわかりません。)

また、デフォルトのトレースから、「欠落した」成功したバックアップを関連付けることもできます。

DECLARE @path nvarchar(260);

SELECT 
   @path = REVERSE(SUBSTRING(REVERSE([path]), 
   CHARINDEX(CHAR(92), REVERSE([path])), 260)) + N'log.trc'
FROM    sys.traces
WHERE   is_default = 1;

SELECT dt.DatabaseName, dt.StartTime, bs.backup_start_date, bs.backup_finish_date, 
  [Status] = CASE WHEN bs.backup_start_date IS NULL 
    THEN 'Probably failed'
    ELSE 'Seems like success'
  END
FROM sys.fn_trace_gettable(@path, DEFAULT) AS dt
LEFT OUTER JOIN msdb.dbo.backupset AS bs
ON dt.DatabaseName = bs.database_name
AND ABS(DATEDIFF(SECOND, dt.StartTime, bs.backup_start_date)) < 5
WHERE dt.EventClass = 115 -- backup/restore events
AND UPPER(CONVERT(nvarchar(max),dt.TextData)) LIKE N'BACKUP%DATABASE%'
--AND dt.DatabaseName = N'db_name' -- to filter to a single database
--AND bs.database_name = N'db_name'
ORDER BY dt.StartTime;

もちろん、これは、デフォルトのトレースサイクリングからのデータ、データベース名が変更されていないことなどにも依存します。残念ながら、デフォルトのトレースでは、成功したバックアップと失敗したバックアップが区別されず、開始時刻はMSDBと正確に一致しませんデータ、ただしループでバックアップを実行していない限り、これは目を見張るのに大丈夫です。これらの問題をクエリに組み込んでみました。

最後に、FULL OUTER JOINbackupsetの履歴がデフォルトのトレースよりも長い場合に備えて、そこを使用することもできます。これはのセマンティクスを[Status]わずかに変更します。

また、私はあまり運が悪かったのですが、この厄介なことを試してみることもできます。私は現在または最新のステータスしか確認できなかったため、ジョブが最後に実行されたときにジョブが失敗した場合にのみ役立ち、ジョブのsysjobhistory実行ではなく、試行されたバックアップに関する情報を取得できませんでした。


詳細な説明をありがとうございましたが、最初のクエリを実行するとエラーが発生します。メッセージ139、レベル15、状態1、行0ローカル変数にデフォルト値を割り当てることはできません。メッセージ137、レベル15、状態2、行16スカラー変数「@db」を宣言する必要があります
iamZel

@iamZelあなたは、いないSQL Server 2008のSQL Server 2005の上にある
アーロン・ベルトラン

はい、そうです。そのことを忘れていました。SQL2K5を使用しています
iamZel

1
@iamZel SQL Server 2008を使用していると思ったのは、質問にそのバージョンのタグを付けたからです。慎重にタグ付けしてください。
アーロンバートランド

sp_readerrorlogで十分です。アーロン、
どうも
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.