Amazon Relational Database Service (Amazon RDS) for SQL Server DB インスタンスでのエラーイベントを出力し、キャプチャしたいです。また、エラーイベントの発生時に通知を受信できるようにしたいです。
簡単な説明
SQL Serverはエラー処理を使用して、T-SQLコード内のオブジェクトに関する存在エラーとランタイムエラーを解決します。これらのエラーをトラブルシューティングするには、TRY...CATCH コンストラクトを使用します。次に、RAISERROR コマンドを使用してカスタマイズしたエラーを生成し、例外を発生させます。SQL サーバーのエラーログを監視して、関連する通知を受信するには、Amazon CloudWatch Logs を使用します。
解決策
TRY...CATCH コンストラクトと RAISERROR ステートメントを使用する
次の手順を実行します。
-
SQL Server Management Studio (SSMS) にログインします。
-
次の TRY...CATCH 構文を使用してエラーテスト用のコードブロックを定義します。
BEGIN TRY
--code to try
END TRY
BEGIN CATCH
--code to run if an error occurs
--is generated in try
END CATCH
注: statement_block は、BEGIN TRY と END TRY の間に記入したコードを実行時のエラーを監視します。ブロック内でエラーが発生すると、そのエラーは CATCH セッションに転送されます。次に、CATCH ブロック内のコードに応じてステートメントがアクションを実行します。問題に応じて、エラーを修正したり、エラーを報告したり、エラーを SQL Server エラーログに記録したりできます。
-
SQL Server エラーの発生時、そのエラーを出力するためのカスタムメッセージを作成します。監視するストアドプロシージャまたは SQL Server に次の RAISERROR ステートメントを追加します。
RAISERROR ( { msg_id | msg_str | @local_variable }
{ , severity, state }
[ , argument [ , ...n ] ] )
[ WITH option [ , ...n ] ]
TRY、CATCH コンストラクトと RAISERROR コマンドの例:
BEGIN TRY
SELECT 1/0
END TRY
BEGIN CATCH
DECLARE @Var VARCHAR(100)
SELECT ERROR_MESSAGE()
SELECT @Var = ERROR_MESSAGE()
RAISERROR(@Var, 16,1) WITH LOG
END CATCH
その結果、SQL Server ログには次のエラーメッセージが表示されます。
Error: 50000, Severity: 16, State: 1.
Divide by zero error encountered.
SQL Serverのエラーログを監視し、通知を送信する
SQL Server エージェントジョブを監視し、SQL Server エラーログにエラーを出力するスクリプトをジョブステップに追加します。その後、エラーログを使用すると通知を送信できます。
SQL Server エージェントジョブを編集するには、次の手順を実行します。
-
SSMS にログインします。
-
データ型には T-SQL を選択します。
-
データベース名を入力し、[コマンド] セクションに次の T-SQL を追加します。
DECLARE @name NVARCHAR(128)
select @name = name from msdb.dbo.sysjobs where job_id = $(ESCAPE_SQUOTE(JOBID));
-- Temporary table to store the data of the datafile with low free storage
DECLARE @jb TABLE ([step_id] int, [step_name] NVARCHAR(128), [message] NVARCHAR(4000), [run_status] int);
insert into @jb
select hist.step_id, hist.step_name, hist.message, hist.run_status
from msdb.dbo.sysjobhistory hist inner join
(select a.job_id
, convert(varchar(50),max(a.run_requested_date),112) as run_date
, replace(convert(varchar(50),max(a.run_requested_date),108), ':', '') as run_time
from msdb.dbo.sysjobs j inner join msdb.dbo.sysjobactivity a
on j.job_id = a.job_id
where j.name = @name
and a.run_requested_date is not null
group by a.job_id) ja
on hist.job_id = ja.job_id
and hist.run_date = ja.run_date
and hist.run_time >= ja.run_time
order by hist.step_id
declare @error int
declare @errormsg nvarchar(4000)
select @error = count(run_status) from @jb where run_status != 0
if @error > 0
begin
set @errormsg='Automatic message from RDS for SQL Server Agent - Job: "' + @name + '" succeed'
RAISERROR(@errormsg, -1,1) WITH LOG
end else
begin
set @errormsg='Automatic message from RDS for SQL Server Agent - Job: "' + @name + '" failed'
RAISERROR(@errormsg, 16,1) WITH LOG
end
-
上記のジョブステップを設定し、成功時と失敗時に次のジョブステップに進むようにします。詳細については、Microsoft のウェブサイトで「ジョブ ステップの成功または失敗のフローを設定する」を参照してください。成功時および失敗時のジョブステップは、前のコードを実行して正常に実行されたかどうかを確認します。次に、エージェントジョブは、ジョブが成功したか失敗したかを示すメッセージを SQL Server エラーログに出力します。
-
次の手順を実行して、SQL Server ジョブが正しく実行され、失敗したジョブの詳細が SQL Server エラーログで更新されていることを確認します。
EXEC rdsadmin.dbo.rds_read_error_log @index = 0, @type = 1;
詳細については、「エラーログとエージェントログの表示」を参照してください。
エラーログ内のジョブ詳細の更新例を次に示します。
Automatic message from RDS for SQL Server Agent - Job: "jobtest-new" succeed
Error: 50000, Severity: 16, State: 1.
Automatic message from RDS for SQL Server Agent - Job: "jobtest-new" failed
CloudWatch Logs で通知を設定する
CloudWatch で通知を設定する方法については、「SQL Server ログを Amazon CloudWatch Logs に発行する」を参照してください。
SQL Server ログを CloudWatch ログに発行した後、メトリクスフィルターを作成するとログを検索しやすくなります。メトリクスフィルターは、ログデータを数値の CloudWatch メトリクスに変換します。このメトリクスに対してアラームを設定できます。詳細については、「CloudWatch のフィルターパターンと一致する Amazon RDS for SQL Server のエラーおよび、エージェントログイベントに関する SNS 通知を受信する方法を教えてください」を参照してください。