sql >> データベース >  >> RDS >> Sqlserver

SQL Serverシステムデータベース–MSDBのメンテナンス

    SQL Serverシステムデータベースシリーズのこれまでの記事では、SQL Serverのインストール中にデフォルトでインストールされるシステムデータベースについて説明し、これらの各システムデータベースの目的を理解し、Tempdbデータベースとそのメンテナンスについて詳しく説明しました。この記事では、MSDBデータベースに関して頻繁に直面する問題と、それらを正しい方法で解決する方法とともに、MSDBデータベースについて詳しく説明します。

    MSDBデータベース

    MSDB SQL Serverシステムデータベースには、SQL Serverエージェントサービス、SQL Serverサービスブローカー、データベースメール、ログ配布、データベースミラーリングなどに関連するすべての重要な構成情報と履歴情報が格納されます。

    • SQLServerエージェントサービス
      • SQL Serverエージェントジョブ–構成データと履歴の詳細
      • SQL Serverエージェントアラート–構成データ
      • SQL Serverエージェントオペレーター–構成データ
      • SQL Serverエージェントプロキシ–構成データ
      • 関連情報
    • ServiceBrokerを含むSQLServerデータベースメール–構成データと履歴メールログの詳細。
    • SQL Serverのバックアップと復元の詳細–SQLServerのインスタンスで発生するすべてのデータベースのバックアップと復元イベントの履歴データ。
    • メンテナンスプラン、SSISパッケージ、および関連情報–構成データ、関連データ、およびSQLServerエージェントジョブを介したこれらすべてのアイテムの実行に関するデータ。
    • ログ配布構成、レプリケーションエージェントプロファイル、データコレクタージョブ–前述のすべての高可用性手法の構成データ。

    上記の重要な構成のいずれかを変更する場合は、フルを使用することをお勧めします。 障害が発生した場合のデータ損失を回避するためのMSDBデータベースのバックアップ。

    SQL Server Agent Serviceは、重要な構成の詳細を MSDBのテーブル全体に保存しますが データベースでは、SQLServerはWindowsレジストリにもいくつかの構成の詳細を保存します。そのために、 sp_set_sqlagent_propertiesという名前の拡張ストアドプロシージャを使用します

    SQLServerがSQLServerエージェントサービスの構成を格納するレジストリの場所を簡単に見てみましょう。 重要 :これは学習目的のみであり、構成値を変更することはお勧めしません。そうしないと、SQLServerエージェントサービスに関連する奇妙なエラーが発生する可能性があります。

    レジストリエディタを開きます regeditと入力します コマンドプロンプトで:

    入力をクリックします レジストリエディタを開くには

    次に、パスに移動します:

    Computer \ HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Microsoft SQL Server \ MSSQL13.MSSQLSERVER \ SQLServerAgent

    以下の構成の詳細を表示します。マークされたフラグメントはSQLServerインスタンス名を示しており、SQLServerのバージョンとインスタンス名によって環境によって異なる場合があります。

    レジストリをざっと見てみると、SQLServerエージェントサービスに関連する特定のパラメータが保存されていることがわかります。 SQL Serverエージェントサービスに関連するパラメータを変更することはお勧めしません。上記で共有したのは学習目的のみであるため、ここでは詳しく説明しません。

    ただし、ビジネスまたは本番の要件を満たすようにSQL Serverエージェントサービスのプロパティのいずれかを変更する場合は、SQLServerエージェントサービスを右クリックしてプロパティを選択することで変更できます。 以下に示すように。

    SQL Serverエージェントサービスに関連する利用可能なパラメーターはたくさんあり、この記事の範囲はmsdbデータベースに関連していますが、以下に示すように、[履歴]メニューをクリックして、それらを除外し、msdbデータベースに固有のオプションのみをカバーします。ジョブ履歴ログとエージェント履歴のサイズを構成できます。

    MSDBデータベースで頻繁に直面する問題

    SQL Serverの本番インスタンスでは、多くのSQL Serverエージェントジョブ、データベースメール、メンテナンスプラン、および完全/トランザクションログのバックアップが有効になります。に応じて。インスタンス内のデータベースの数または数。使用可能なSQLServerエージェントジョブの数、またはデータベースメールの使用量に応じて、SQL Serverは有効なすべての機能の履歴情報のログ記録を開始し、それによって MSDBのサイズを増やします。 データベース。適切に保守されていない場合、これはMSDBデータベースのパフォーマンスとそれに関連する操作に影響します。

    前に説明した機能と履歴データの保存に使用されるテーブルを確認して、これらのテーブルのサイズを管理する方法を理解しましょう。

    • バックアップ履歴
    • SQLServerエージェントのジョブ履歴
    • メンテナンスプラン
    • SQLServerデータベースのメール履歴
    • SSISパッケージ

    MSDBデータベース内のどのテーブルがより多くのスペースを占めるかを確認するには、上位テーブル別のディスク使用量レポートを使用できます。 これは、SQL ServerManagementStudioのSQLServerデフォルトレポートの一部として提供されます。

    SSMSを開き、 MSDBを右クリックします データベース>レポート >標準レポート >トップテーブル別のディスク使用量 ディスク使用量でソートされたテーブルのレポートを生成するには:

    トップテーブル別のディスク使用量をクリックします レポートを表示します。私のインスタンスは開発用のインスタンスであるため、巨大なテーブルはありませんが、このレポートでは、データベース内のすべてのテーブルのサイズを降順で並べ替えて表示できます。

    以下のクエリを使用して、データベース内のテーブルのサイズを取得することもできます。

    SELECT -- TOP(10)
    	  SCHEMA_NAME(o.[schema_id]) Schema_name
    	, o.name object_name
        , total_size = CAST(SUM(au.total_pages) * 8. / 1024 AS DECIMAL(18,2))
        , total_rows = SUM(CASE WHEN i.index_id IN (0, 1) AND au.[type] = 1 THEN p.[rows] END)
    FROM sys.objects o 
    JOIN sys.indexes i ON o.[object_id] = i.[object_id]
    JOIN sys.partitions p ON i.[object_id] = p.[object_id] AND i.index_id = p.index_id
    JOIN sys.allocation_units au ON p.[partition_id] = au.container_id
    WHERE i.is_disabled = 0
    AND i.is_hypothetical = 0
    AND o.Type in ('S','U','V')
    GROUP BY o.name, SCHEMA_NAME(o.[schema_id])
    ORDER BY 3 DESC
    

    どのテーブルがより多くのスペースを必要とするかがわかれば、関連するストアドプロシージャを使用して、それらのサイズを制御できます。

    バックアップ履歴

    DBAの主な責任は、すべての本番SQL Serverインスタンスで完全バックアップとトランザクションログが有効になっていて、データベースを特定の時点にリカバリできるようにすることです。

    SQL Serverは、バックアップの詳細と復元情報を次のMSDBデータベーステーブルに保存します。 :

    • バックアップファイル
    • backupfilegroup
    • backupmediafamily
    • backupmediaset
    • バックアップセット
    • restorefile
    • restorefilegroup
    • 復元履歴

    重要ないいえ。フルバックアップとトランザクションログバックアップで構成されたSQLServerインスタンス内のデータベースの場合、上記のテーブル全体のレコードがより速く増加する可能性があります。

    したがって、SQL Serverは、 MSDBに2つのシステムストアドプロシージャを提供します。 上記のテーブルのサイズを制御するデータベース:

    • sp_delete_backuphistory –上記の8つのテーブルのバックアップ履歴データを最も古い日付に基づいて削除します。 パラメータ。
    • sp_delete_database_backuphistory –データベース名に基づいて上記の8つのテーブルのバックアップ履歴データを削除します

    上記のシステムストアドプロシージャを実行するための構文:

    exec msdb.dbo.sp_delete_backuphistory @oldest_date = 'oldest_date'
    exec msdb.dbo.sp_delete_database_backuphistory @database_name = 'database_name'

    バックアップ履歴テーブル全体に巨大なレコードを含むデータベースで上記のストアドプロシージャのいずれかを実行すると、ブロックが発生したり、レコードの削除が非常に遅いことに気付く場合があります。これを解決するために、 backupsetに以下の欠落しているインデックスを作成します テーブル。ストアドプロシージャの実行プランを介して識別し、ストアドプロシージャをより高速に実行できます。

    IF NOT EXISTS (SELECT * FROM sys.indexes WHERE OBJECT_ID = OBJECT_ID('[dbo].[backupset]') AND name = 'IX_BackupSet_FinDate_MediaSet')
    CREATE NONCLUSTERED INDEX IX_BackupSet_FinDate_MediaSet ON backupset(backup_finish_date) 
    INCLUDE (media_set_id)
    GO
    

    SQLServerエージェントのジョブ履歴

    SQL Serverは、すべてのSQLServerエージェントジョブの履歴を msdb.dbo.sysjobhistoryに保存します。 テーブル。また、SQL Serverには、 msdb.dbo.sp_purge_jobhistoryという名前のシステムストアドプロシージャがあります。 sysjobhistoryを維持するのに役立ちます テーブルサイズは管理下にあります。

    sp_purge_jobhistoryを実行するための構文 ストアドプロシージャは次のようになります:

    exec msdb.dbo.sp_purge_jobhistory @job_name = 'job_name', @job_id = 'job_id', @oldest_date ='oldest_date'

    3つのパラメータはすべてオプションであり、 oldest_dateを渡して上記の手順を実行することをお勧めします。 パラメータ sysjobhistoryを維持する テーブルサイズは管理下にあります。

    メンテナンスプラン

    SQL Serverは、すべてのメンテナンスプランの詳細を次の表に保存します。

    • msdb.dbo.sysmaintplan_log
    • msdb.dbo.sysmaintplan_logdetail

    SQL Serverには、 msdb.dbo.sp_maintplan_delete_logという名前の組み込みのストアドプロシージャがあります。 これら2つのテーブルのサイズを管理するため。

    プロシージャを実行するための構文は次のとおりです。

    exec msdb.dbo.sp_maintplan_delete_log @plan_id = '', @subplan_id = '', @oldest_Time = 'oldest_datetime'

    3つのパラメーターはすべてオプションです。上記の手順を実行し、oldest_timeパラメータを渡して、上記の2つのテーブルのサイズを管理することをお勧めします。

    SQLServerデータベースのメール履歴

    SQL Serverは、すべてのデータベースメール履歴ログを以下のテーブルに保存します。

    • sysmail_mailitems
    • sysmail_log
    • sysmail_attachments
    • sysmail_attachments_transfer

    これらの履歴テーブルのサイズを管理するために、SQLServerは msdb.dbo.sysmail_delete_mailitems_spという名前の2つのシステムストアドプロシージャを提供しています。 およびmsdb.dbo.sysmail_delete_log_sp。

    これらのストアドプロシージャを実行するための構文は次のとおりです。

    exec msdb.dbo.sysmail_delete_mailitems_sp @sent_before = 'oldest_datetime', @sent_status = NULL
    exec msdb.dbo.sysmail_delete_log_sp @logged_before = 'oldest_datetime', @event_type = NULL

    どちらの手順でも、すべてのパラメーターはオプションです。ただし、 send_beforeを使用することをお勧めします またはlogged_befor e 保存期間に基づいて古いレコードを削除するためのパラメータ。

    いくつかのシナリオでは、データベースメールに関連するすべてのテーブルが巨大な場合、削除を実行します 手順 永遠に実行されます。この問題をより迅速に処理する方法は、 sysmail_attachmentsの外部キー制約を削除することです。 およびsysmail_send_retries テーブル、上記の4つのテーブルを切り捨て、 sysmail_attachmentsで2つの外部キーを再作成します。 およびsysmail_send_retries テーブル 以下に示すように:

    USE MSDB;
    
    ALTER TABLE [dbo].[sysmail_attachments] DROP [FK_sysmail_mailitems_mailitem_id];
    GO
    ALTER TABLE [dbo].[sysmail_send_retries] DROP [FK_mailitems_mailitem_id];
    GO
    
    TRUNCATE TABLE [dbo].[sysmail_attachments];
    TRUNCATE TABLE [dbo].[sysmail_send_retries];
    TRUNCATE TABLE [dbo].[sysmail_mailitems];
    TRUNCATE TABLE [dbo].[sysmail_log];
    
    ALTER TABLE [dbo].[sysmail_attachments]  WITH CHECK ADD  CONSTRAINT [FK_sysmail_mailitems_mailitem_id] FOREIGN KEY([mailitem_id])
    REFERENCES [dbo].[sysmail_mailitems] ([mailitem_id])
    ON DELETE CASCADE;
    ALTER TABLE [dbo].[sysmail_attachments] CHECK CONSTRAINT [FK_sysmail_mailitems_mailitem_id];
    GO
    
    ALTER TABLE [dbo].[sysmail_send_retries]  WITH CHECK ADD  CONSTRAINT [FK_mailitems_mailitem_id] FOREIGN KEY([mailitem_id])
    REFERENCES [dbo].[sysmail_mailitems] ([mailitem_id])
    ON DELETE CASCADE;
    ALTER TABLE [dbo].[sysmail_send_retries] CHECK CONSTRAINT [FK_mailitems_mailitem_id];
    GO
    

    SSISパッケージ

    SQL Serverは、すべての SSIS(*。dtsx)を格納します msdb.dbo.sysssispackagesのパッケージ テーブル。このテーブルは構成テーブルですが、ランダムなケースでは、テーブルに大量のSSISパッケージがダンプされている可能性があります。このテーブルのサイズが大きくなります。

    そのような場合、不要なパッケージがあるかどうかを識別し、それらのパッケージを削除して sysssispackages を保持する必要があります。 テーブルサイズは管理下にあります。

    結論

    SQL Serverには、すべてのテーブルを削除するタスクを処理するための組み込みのジョブがありません。 上で議論した。それでも、最も古い日付パラメータがあります 上記のすべての手順で利用できます。

    したがって、管理下にあるMSDBテーブルサイズを処理するための推奨アプローチ 日数に基づいて保持期間を定義し、新しいSQL Serverエージェントジョブを作成して、スケジュールに基づいて以下のスクリプトを実行します。

    declare @retention_date datetime = '2021-04-01'
    exec msdb.dbo.sp_delete_backuphistory @oldest_date = @retention_date;
    exec msdb.dbo.sp_purge_jobhistory @oldest_date = @retention_date;
    exec msdb.dbo.sp_maintplan_delete_log @oldest_Time = @retention_date;
    exec msdb.dbo.sysmail_delete_mailitems_sp @sent_before = @retention_date;
    exec msdb.dbo.sysmail_delete_log_sp @logged_before = @retention_date;
    

    結論

    MSDBでより速く成長できるテーブルのリストについて学びました データベースと、これらのテーブルのサイズを管理する方法。 MSDB を防ぐために定期的に実行する手順のリストを含む、便利なスクリプトを作成しました。 データベースも巨大なサイズに成長しています。この記事が自動化に役立ち、この情報がMSDBデータベースのメンテナンスから解放され、他のアクティビティに集中できることを願っています。


    1. LEFT JOINを使用してクエリを実行すると、カウントが0の行が返されません。

    2. 一時テーブルのpostgresqlスレッドセーフ

    3. SQLiteで昨日の日付を取得する方法

    4. 8589934592バイトの許容メモリサイズが使い果たされました