松本美穂と松本崇博が執筆した SQL Server 2012 自習書シリーズの「新機能編 No.2 AlwaysOn による可用性の向上」の HTML 版です。 日本マイクロソフトさんの Web サイトで Word または PDF 形式でダウンロードできますが、今回、HTML 版として公開する許可をいただきましたので、ここに掲載いたします。[2014年12月26日]
包含データベース(包含データベース)は、SQL Server 2012 から提供された新機能で、ログイン アカウントや照合順序に依存しないデータベースを作成できる機能です。これを利用すれば、ログイン アカウントとは完全に独立したデータベース(DB)ユーザーを作成できるようになるので、可用性グループでも役立ちます。
ここでは、まず包含データベースを利用しなかった場合にどういった問題が発生するのかを試してみましょう。今回作成した AGTestDB データベースは、包含データベースを利用していないので、これで試します。
1.まずは、SQL Server 認証用のログイン アカウントを作成するので、SQL Server の認証モードを混合モードへ設定します。認証モードを設定するには、次のように Management Studio でサーバー名を右クリックして[プロパティ]をクリックします。
[サーバーのプロパティ]ダイアログが表示されたら、[セキュリティ]ページを開いて、「SQL Server 認証モードと Windows 認証モード」をチェックして、[OK]ボタンをクリックします。ダイアログを閉じたら、SQL Server を再起動することで、変更が有効になります。
この操作は、SERVER1、SERVER2、SERVER3 で行ってください。
2.次に、プライマリ(SERVER1)へ接続して、ログイン アカウントとデータベース ユーザーを作成します。ログイン アカウントを作成するには、次のように[セキュリティ]フォルダーの[ログイン]フォルダーを右クリックして、「新しいログイン」をクリックします。
[ログイン - 新規作成]ダイアログが表示されたら、ログイン名に「testlogin1」など任意の名前を入力して、「SQL Server 認証」を選択、[パスワード]と[パスワードの確認入力]に「P@ssword」など任意のパスワードを設定します。
3.次に、[ユーザー マッピング]ページを開いて、「AGTestDB」データベースをチェックして、このログイン アカウントにマッピングされたデータベース ユーザーを作成します。
次に、「db_datareader」ロールをチェックして、[OK]ボタンをクリックします。これでデータベースに対する読み取り操作が可能になります。
4.次に、AGTestDB データベースを展開して、[セキュリティ]フォルダーの[ユーザー]フォルダーを展開すると、testlogin1 ユーザーが作成されていることを確認できます。
このユーザーのプロパティを開くと、[ログイン名]に testlogin1 ログイン アカウントが表示されて、ログイン アカウントにマッピングされたユーザーであることを確認できます。
5.次に、ツールバーの[データベース エンジン クエリ]ボタンをクリックして、testlogin1 ログイン アカウントで接続します。
[認証]で「SQL Server 認証」を選択、[ログイン]に「testlogin1」、パスワードに設定したパスワードを入力して、[接続]ボタンをクリックします。
6.接続完了後、次のように SELECT ステートメントを実行して、t1 テーブルのデータが参照できることを確認します。
7.次に、SERVER2(セカンダリ)へ接続して、AGTestDB データベースを展開し、[セキュリティ]フォルダーの[ユーザー]フォルダーを展開すると、testlogin1 ユーザーが作成されている(複製されている)ことを確認できます
しかし、ユーザーのプロパティを開くと、[ログイン名]が表示されない、マッピングの切れたユーザーとなっていることを確認できます。
8.次に、ツールバーの[データベース エンジン クエリ]ボタンをクリックして、testlogin1 ログイン アカウントで SERVER2 への接続を試みます。
しかし、結果はエラーとなります。
SERVER2 には、ログイン アカウントを作成していないため、ログインすることができません。
9.次に、SERVER2 へログイン アカウントを作成します。
[ログイン名]に「testlogin1」と入力して、「SQL Server 認証」を選択し、任意のパスワードを設定します。
10.次に、[ユーザー マッピング]ページを開いて、「AGTestDB」データベースをチェックして、[OK]ボタンをクリックします。
しかし、AGTestDB データベースは、セカンダリに設定されているデータベースなので、読み取り専用として設定されているので、データベースを更新できない主旨のエラーが返ります。
11.次に、[AGTestDB]データベースのチェックを外して、[OK]ボタンをクリックします。
今度は、「testlogin1 は既に存在します」というエラーが発生します。これは、先ほどのエラーになったときに、ログイン アカウントの作成については成功している(データベース ユーザーの作成は失敗している)ために発生しています。
12.次に、作成されたログイン アカウント(testlogin1)を確認します。
13.次に、もう一度、testlogin1 ログイン アカウントで SERVER2 への接続を試みます。
今度は接続できます。
14.接続後、USE ステートメントを実行して、AGTestDB データベースへ接続します。
結果は、エラーとなります。これは、SERVER2 上に作成した「testlogin1」ログイン アカウントと AGTestDB データベース内のデータベース ユーザー「testlogin1」のマッピングが切れているために発生しています。これでは、せっかく読み取り可能なセカンダリを作成していても、ユーザーがデータベースへ接続できないことになってしまいます。
15.マッピングの切れたユーザーは、次のように sp_change_users_login ストアド プロシージャを実行して確認することができます(このステートメントは、Administrator としてログインした状態で実行してください)。
16.マッピングの切れたユーザーは、Update_One を指定して sp_change_users_login ストアド プロシージャを実行することで、再マッピングする(マッピングを修復する)ことができるのですが、これも次のようにエラーとなります。
セカンダリ データベースは、読み取り専用に設定されるため、マッピング情報の更新(データベース内部のデータ更新)は許可されないのです。
したがって、このステートメントが実行できるのは、セカンダリがプライマリに役割変更されたときだけです。これでは、障害発生時に、(このステートメントが実行されるまで)ユーザーがログインできないことになってしまいます(ダウンタイムが長くなってしまいます)。また、このステートメントを実行しても、内部的な SID を新しいもの(SERVER2 側で作成したログイン アカウントの SecurityID)へ置き換えるだけなので、逆の役割変更があった場合(次に SERVER1 が再びプライマリになった場合)には、再度マッピングが切れたユーザー(SERVER1 上のログイン アカウントの SID と SERVER2 上の同じログイン アカウントの SID が異なるので、再度マッピングが切れる)が発生することにもなります。
したがって、sp_change_users_login ストアド プロシージャによるマッピング更新は、最良の解決策とは言えません。これを解決するための方法が、次の 2つです。
包含データベース(Contained Database)機能を利用すると、ログイン アカウントに依存しない(マッピングが不要な)データベース ユーザーを作成することができます(独立したデータベース ユーザーをデータベース内に含められることから Contained と名付けられています)。このようにデータベース ユーザーが独立していれば、可用性グループでの役割変更時にも問題なくそのユーザーを利用することができ、またデータベースの移行時(ハードウェア リプレイス時のデータベース移行時や、別のサーバーへデータベースを移動したい場合、開発機から本番機へデータベースを移動したい場合など)にも役立ちます。
それでは、包含データベースを利用して、可用性グループを構成してみましょう。
1.包含データベースを利用するには、まずは sp_configure を利用して、SQL Server の構成オプションで Contained Database Authentication(包含データベース認証)を有効化(1へ設定)します。これは次のように実行します。
このオプションは、可用性グループを構成するすべてのサーバー上で実行しておく必要があるので SERVER2 および SERVER3 でも実行しておきます。
2.次に、AGTestDB データベースを包含データベースへ設定します。包含データベースへ設定するには、次のようにデータベースのプロパティを開いて、[オプション]ページから[コンテインメントの種類]で「部分」を選択します。
次に、データベース内にユーザーを作成します。AGTestDB データベースを展開して、[セキュリティ]フォルダーの[ユーザー]を右クリックして、[新しいユーザー]をクリックします。
[データベース ユーザー - 新期]ダイアログが表示されたら、[ユーザーの種類]で「パスワードを持つユーザー」を選択して、[ユーザー名]に「testuser1」、[パスワード]と[パスワードの確認入力]に任意のパスワード(P@ssword など)を設定します。
3.次に、[メンバーシップ]ページを開いて、「db_datareader」ロールをチェックして、[OK]ボタンをクリックします。これで、データベース内のオブジェクトに対する読み取り操作が行えるようになります。
これで、データベースの中に包含されたデータベース ユーザーの作成が完了です。
4.次に、作成したユーザー(testuser1)で SERVER1 へ接続します。
[認証]で「SQL Server 認証」を選択、[ログイン]に「testuser1」、[パスワード]に設定したパスワード(P@ssword)を入力して[オプション]ボタンをクリックします。
5.次のように[接続プロパティ]タブが表示されたら、[データベースへの接続]へ「AGTestDB」と入力して[接続]ボタンをクリックします。
これで、testuser1 ユーザーとして AGTestDB データベースへ接続することができます。
6.接続完了後、t1 テーブルのデータを参照します。
ステータス バーには、接続しているユーザーと接続先のデータベース名が表示されるので、これで正しく接続できたことを確認できます。
7.次に、SERVER2 に対して、testuser1 で接続します。
[サーバー名]に「SERVER2」、[認証]で「SQL Server 認証」を選択、[ログイン]に「testuser1」、[パスワード]に設定したパスワード(P@ssword)を入力して[オプション]ボタンをクリックします。
8.[接続プロパティ]タブが表示されたら、[データベースへの接続]へ「AGTestDB」と入力して[接続]ボタンをクリックします。
9.接続完了後、t1 テーブルのデータを参照します。
何の問題もなくデータが参照できることを確認できます。
このように 包含データベースを利用すれば、データベース ユーザーがデータベース内に包含されるので、マッピングの切れたユーザーが発生することはありません。
包含データベースは、tempdb の照合順序に依存しない一時テーブルの作成ができることも大きなメリットです。従来のバージョンでは、CREATE TABLE ステートメントを利用して作成した一時テーブルの照合順序は tempdb の照合順序を継承するため、データベース移行時に、移行元と移行先で tempdb の照合順序が異なる場合に、照合順序の不一致が発生するという問題がありました。
この問題は、次のように 包含データベースではない通常のデータベースを作成することで確認することができます。
このステートメントでは、通常のデータベースを照合順序 Japanese_CS_AS で作成しているので、t1 テーブルの文字列データ型の列は、Japanese_CS_AS として作成されます。一方、tempdb の照合順序は Japanese_CI_AS(既定値)へ設定しているので、一時テーブル #t2 の文字列データ型の列は Japanese_CI_AS として作成されます。このように異なる照合順序の列がある場合に、この列を JOIN キーとして利用すると、次のようにエラーが発生してしまいます。
このように、包含データベース ではない通常のデータベースの場合には、移行元と移行先での tempdb の照合順序に注意する必要がありました。これに対して包含データベースでは、tempdb の照合順序に依存しない一時テーブルの作成が可能です。一時テーブルの照合順序は、包含データベース に設定された照合順序を継承するようになっているため、移行元と移行先で tempdb の照合順序が異なっている場合でも、データベースを問題なく動作させることが可能です。
このように、SQL Server 2012 では、包含データベースが提供されたことによって、データベースの移行(バックアップ/リストアやデタッチ/アタッチによるデータベース移動)が非常に簡単に行えるようになりました。これにより、ハードウェア リプレイス時のデータベース移行時や、別のサーバーへデータベースを移動したい場合、開発機から本番機へデータベースを移動したい場合などで大変役立ちます。
また、可用性グループを構成する場合にも、包含データベースを利用することで、データベース ユーザーを何の問題もなく利用できるようになるので、大変便利です。
第38回: SQL Server 2014 CTP2 の公開
第37回: SQL Server 2014 CTP1 の自習書をご覧ください
第36回: SQL Server 2014 CTP1 のクラスター化列ストア インデックスを試す
第35回: SQL Server 2014 CTP1 のインメモリ OLTP の基本操作を試す
第34回: GeoFlow for Excel 2013 のプレビュー版を試す
第33回:iPad と iPhone からの SQL Server 2012 Reporting Servicesのレポート閲覧
第32回:PASS Summit 2012 参加レポート
第31回:SQL Server 2012 Reporting Services 自習書のお知らせ
第30回:SQL Server 2012(RTM 版)の新機能 自習書をご覧ください
第29回:書籍「SQL Server 2012の教科書 開発編」のお知らせ
第26回:SQL Server 2012 の Power View 機能のご紹介
第25回:SQL Server 2012 の Data Quality Services
第24回:SQL Server 2012 自習書のご案内と初セミナー報告
第23回:Denali CTP1 が公開されました
第22回 チューニングに王道あらず
第21回 Microsoft TechEd 2010 終了しました
第20回 Microsoft TechEd Japan 2010 今年も登壇します
第19回 SQL Server 2008 R2 RTM の 日本語版が公開されました
第18回 「SQL Azure 入門」自習書のご案内
第17回 SQL Server 2008 自習書の追加ドキュメントのお知らせ
第16回 SQL Server 2008 R2 自習書とプレビュー セミナーのお知らせ
第15回 SQL Server 2008 R2 Reporting Services と新刊のお知らせ
第14回 TechEd 2009 のご報告と SQL Server 2008 R2 について
第13回 SQL Server 2008 R2 の CTP 版が公開されました
第12回 MVP Summit 2009 in Seattle へ参加