

# Amazon RDS 用 SQL Server エージェントの使用
<a name="Appendix.SQLServer.CommonDBATasks.Agent"></a>

Amazon RDS では、Microsoft SQL Server の Enterprise、Standard、または Web エディションを実行している DB インスタンスの SQL Server エージェントを使用できます。SQL Server エージェントは、ジョブと呼ばれるスケジュールされた管理タスクを実行する Microsoft Windows サービスです。SQL Server エージェントを使用して T-SQL ジョブを実行し、SQL Server DB インスタンスでインデックスの再構築、データ破損の確認、およびデータの集計を行うことができます。

SQL Server DB インスタンスを作成すると、マスターユーザーが `SQLAgentUserRole` ロールに登録されます。

SQL Server エージェントは、指定したイベントに対応し、またはオンデマンドで、スケジュールに従ってジョブを実行できます。詳細については、Microsoft ドキュメントの [SQL Server エージェント](http://msdn.microsoft.com/en-us/library/ms189237)を参照してください。

**注記**  
DB インスタンスのメンテナンスおよびバックアップウィンドウ中に実行されるジョブをスケジュールすることは避けてください。AWS によって起動されたメンテナンスおよびバックアッププロセスによって、ジョブが中断されたり、ジョブがキャンセルされたりする可能性があります。  
マルチ AZ 配置では、ジョブのレプリケーション機能がオンになっているとき、SQL Server エージェントジョブは、プライマリホストからセカンダリホストにレプリケートされます。詳細については、「[SQL Server エージェントジョブレプリケーションをオンにする](#SQLServerAgent.Replicate)」を参照してください。  
マルチ AZ 配置は、SQL Server エージェントジョブの数が 10,000 に制限されています。制限の引き上げが必要な場合は、サポート に連絡して緩和をリクエストしてください。[AWS サポート センター](https://console.aws.amazon.com/support/home#/)のページを開き、必要に応じてサインインし、[**ケースの作成**] を選択します。**[Service Limit increase]** (サービス制限の緩和) を選択します。フォームに入力して送信します。

SQL Server Management Studio (SSMS) で個々の SQL Server エージェントジョブの履歴を表示するには、オブジェクトエクスプローラーを開き、ジョブを右クリックして、[**View History**] (履歴を表示) を選択します。

SQL Server エージェントは DB インスタンスのマネージドホストで実行されているため、一部のアクションはサポートされていません。
+ ActiveX、Windows コマンドシェル、または Windows PowerShell を使用した、レプリケーションジョブの実行やコマンドラインスクリプトの実行はサポートされません。
+ SQL Server エージェントを手動で起動、停止、または再起動することはできません。
+ SQL Server エージェントを使用した E メール通知は、DB インスタンスからは使用できません。
+ SQL Server エージェントのアラートとオペレータはサポートされていません。
+ SQL Server エージェントを使用したバックアップの作成はサポートされていません。Amazon RDS を使用して DB インスタンスをバックアップします。
+ RDS for SQL Server は、現在、SQL Server エージェントトークンの使用をサポートしていません。

## SQL Server エージェントジョブレプリケーションをオンにする
<a name="SQLServerAgent.Replicate"></a>

SQL Server エージェントジョブレプリケーションは、次のストアドプロシージャを使用して有効にできます。

```
EXECUTE msdb.dbo.rds_set_system_database_sync_objects @object_types = 'SQLAgentJob';
```

ストアドプロシージャは、Amazon RDS for SQL Server でサポートされているすべての SQL Server バージョンで実行できます。以下のカテゴリのジョブがレプリケートされます。
+ [未分類 (ローカル)]
+ [未分類 (マルチサーバー)]
+ [未分類]
+ データコレクター
+ データベースエンジンチューニングアドバイザー
+ データベースメンテナンス
+ フルテキスト

T-SQL ジョブステップを使用するジョブのみがレプリケートされます。SQL Server Integration Services (SSIS)、SQL Server Reporting Services (SSRS)、レプリケーション、PowerShell などのステップタイプのジョブはレプリケートされません。データベースメールとサーバーレベルのオブジェクトを使用するジョブはレプリケートされません。

**重要**  
プライマリホストは、レプリケーションの信頼できるソースです。ジョブのレプリケーションをオンにする前に、SQL Server エージェントのジョブがプライマリであることを確認してください。これを行わない場合、新しいジョブがセカンダリホスト上にあるときにこの機能をオンにすると、SQL Server エージェントのジョブが削除される可能性があります。

次の関数を使用して、レプリケーションがオンになっているかどうかを確認できます。

```
SELECT * from msdb.dbo.rds_fn_get_system_database_sync_objects();
```

 SQL Server エージェントジョブがレプリケートされている場合、T-SQL クエリは以下を返します。レプリケートしていない場合は、`object_class` に対して何も返しません。

![\[SQL Server エージェントジョブがレプリケート中\]](http://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/images/SQLAgentJob.png)


次の関数を使用して、オブジェクトが UTC 時間で最後に同期された時刻を調べることができます。

```
SELECT * from msdb.dbo.rds_fn_server_object_last_sync_time();
```

例えば、01:00 に SQL Server エージェントジョブを変更するとします。直近の同期時刻は 01:00 以降になると予想されます。これは、同期が行われたことを示します。

同期後、セカンダリノードで `date_created` と `date_modified` に返される値は一致することが期待されます。

![\[サーバーオブジェクトが前回同期された時刻は 01:21:23 でした\]](http://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/images/SQLAgentJob_last_sync_time.png)


`tempdb` レプリケーションも使用している場合は、`@object_type` パラメータで指定することで、SQL Agent ジョブと `tempdb` 設定の両方のレプリケーションを有効にできます。

```
EXECUTE msdb.dbo.rds_set_system_database_sync_objects @object_types = 'SQLAgentJob,TempDbFile';
```

`tempdb` レプリケーションの詳細については、「[マルチ AZ 配置の TempDB 設定](SQLServer.TempDB.MAZ.md)」を参照してください。

# SQL Server エージェントのロール
<a name="SQLServerAgent.AgentRoles"></a>

RDS for SQL Server は、ジョブを管理するためのさまざまなレベルのアクセス許可を持つ、以下の SQL Server エージェントのロールをサポートしています。
+ **SQLAgentUserRole**

  アクセス許可
  + 独自のジョブ、スケジュール、オペレーターを作成および管理する
  + 独自のジョブとスケジュールのプロパティを表示する
  + 他のユーザーが作成したジョブは表示または管理できない

  このロールは、独自のジョブを作成および管理する必要があるが、他のユーザーが作成したジョブへのアクセスを必要としないユーザーに適しています。
+ **SQLAgentReaderRole**

  アクセス許可
  + SQLAgentUserRole のすべてのアクセス許可
  + すべてのジョブとスケジュール (他のユーザーが作成したものを含む) を一覧表示する
  + すべてのジョブのプロパティを表示する
  + ジョブ履歴を確認する

  このロールは、すべてのジョブのステータスをモニタリングする必要があるが、ジョブを管理する必要がないユーザーに適しています。
+ **SQLAgentOperatorRole**

  アクセス許可
  + SQLAgentUserRole と SQLAgentReaderRole のすべてのアクセス許可
  + ジョブを実行、停止、または開始する
  + ジョブ履歴を管理する
  + ジョブとスケジュールを有効/無効にする
  + オペレーターとプロキシを表示する

  このロールは、最も包括的なアクセス許可を提供するものであり、すべてのジョブを完全に制御する必要があるユーザーに適しています。

SQL Server ログインにロールを割り当てるには、次のコマンドを使用します。

```
USE msdb;
EXEC sp_addrolemember 'SQLAgentOperatorRole', 'username';
```

## RDS for SQL Server での SQLAgentOperatorRole の管理
<a name="SQLServerAgent.AgentRoles.ManageSQLAgentOperatorRole"></a>

現在のジョブを表示するには、SQLAgentOperatorRole を SQL Server ログインに追加し、データベースから切断する前にそれを削除する必要があります。

SQL Server Management Studio で SQL Server エージェントツリーを視覚化するには、次の手順に従います。

**SQL Server Management Studio (SSMS) で SQL Server エージェントを表示する**

1. RDS マスター認証情報を使用して RDS SQL Server インスタンスにログインし、目的のユーザーに SQLAgentUserRole を付与します。

   ```
   USE msdb
   GO
   IF NOT EXISTS(SELECT name FROM sys.database_principals WHERE name = 'UserName')
   BEGIN
   CREATE USER UserName FROM LOGIN UserName
   END
   GO
   ALTER ROLE SQLAgentUserRole ADD MEMBER UserName
   GO
   GRANT ALTER ON ROLE::[SQLAgentOperatorRole] to UserName
   GO
   ```

   これらのコマンドは、`msdb` データベースにユーザーが存在しない場合に作成します。また、SQLAgentUserRole にユーザーを追加し、SQL Server エージェントツリーを SSMS で表示できるようにします。最後に、SQLAgentOperatorRole に対する変更アクセス許可をユーザーに付与します。これにより、ユーザーはロールに対して自身を追加または削除できます。

1. 上記のロールに自分自身を追加するには、ジョブを表示する必要があるユーザーを使用して RDS SQL Server インスタンスに接続し、次のスクリプトを実行します。

   ```
   use msdb
   go
   ALTER ROLE SQLAgentOperatorRole ADD MEMBER UserName
   GO
   ```

   次に、**[ジョブ]** フォルダを右クリックし、**[更新]** を選択します。

1. このアクションを実行すると、**[ジョブ]** タブに **[\$1]** (プラス) ボタンが表示されます。クリックして SQL Server エージェントジョブのリストを展開します。

1. 
**重要**  
RDS SQL Server インスタンスから切断する前に、SQLAgentOperatorRole から自分自身を削除する必要があります。

   SQLAgentOperatorRole からログインを削除するには、Management Studio を切断または終了する前に次のクエリを実行します。

   ```
   USE msdb
   GO
   ALTER ROLE SQLAgentOperatorRole DROP MEMBER UserName
   GO
   ```

詳細については、「[RDS SQL Server での SQLAgentOperatorRole の活用](https://aws.amazon.com/blogs/database/leveraging-sqlagentoperatorrole-in-rds-sql-server/)」を参照してください。

# SQLAgentUser ロールへのユーザーの追加
<a name="SQLServerAgent.AddUser"></a>

SQL Server エージェントにログインまたはユーザーを追加できるようにするには、マスターユーザーとしてログインし、次の操作を行ってください。

1. `CREATE LOGIN` コマンドを使用して、別のサーバーレベルログインを作成します。

1. `msdb` コマンドを使用して `CREATE USER` にユーザーを作成し、このユーザーを前の手順で作成したログインにリンクします。

1. `SQLAgentUserRole` システムストアドプロシージャを使用して、`sp_addrolemember` にユーザーを追加します。

例えば、マスターユーザー名が **admin** で、ユーザー名が **theirname**、パスワードが **theirpassword** のユーザーに SQL Server エージェントへのアクセスを許可するとします。その場合は、以下の手順を使用できます。

**SQLAgentUser ロールにユーザーを追加するには**

1. マスターユーザーとしてログインします。

1. 以下のコマンドを実行します。

   ```
   --Initially set context to master database
   USE [master];
   GO
   --Create a server-level login named theirname with password theirpassword
   CREATE LOGIN [theirname] WITH PASSWORD = 'theirpassword';
   GO
   --Set context to msdb database
   USE [msdb];
   GO
   --Create a database user named theirname and link it to server-level login theirname
   CREATE USER [theirname] FOR LOGIN [theirname];
   GO
   --Added database user theirname in msdb to SQLAgentUserRole in msdb
   EXEC sp_addrolemember [SQLAgentUserRole], [theirname];
   ```

# SQL Server エージェントジョブの削除
<a name="SQLServerAgent.DeleteJob"></a>

`sp_delete_job` ストアドプロシージャを使用して、Amazon RDS for Microsoft SQL Server の SQL Server エージェントジョブを削除します。

SSMS を使用して SQL Server エージェントジョブを削除することはできません。これを試みると、次のようなエラーメッセージが表示されます。

```
The EXECUTE permission was denied on the object 'xp_regread', database 'mssqlsystemresource', schema 'sys'.
```

マネージド型サービスとしての RDS では、Windows レジストリにアクセスする手順の実行が制限されています。SSMS を使用すると、RDS が承認されていないプロセス (`xp_regread`) の実行を試みます。

**注記**  
RDS for SQL Server では、sysadmin ロールのメンバーのみが、別のログインが所有するジョブを更新または削除できます。詳細については、「[RDS SQL Server での SQLAgentOperatorRole の活用](https://aws.amazon.com/blogs/database/leveraging-sqlagentoperatorrole-in-rds-sql-server/)」を参照してください。

**SQL Server エージェントジョブを削除するには**
+ 次の T-SQL ステートメントを実行します。

  ```
  EXEC msdb..sp_delete_job @job_name = 'job_name';
  ```