 TechNet Magazine March 2007
TechNet Magazine March 2007
MARCH 2007
SQL Server

特集 SQL Server チューンアップ

今月の TechNet Magazine は SQL Server 特集号です。今月号では、SQL Server に最高のパフォーマンスを発揮させる方法をより深く理解することができます。インデックスを適切な状態に管理して、クエリを高速に実行する方法を説明します。

SQL Server のクラスタ化によってどのように冗長性がもたらされ、稼働状態が確保されるかを説明します。また、個々の環境における高可用性の意義とその実現方法についても示します。最後に、テーブル分割のジレンマを完全に解消する方法について説明します。

Windows の管理

Mark Russinovich が今月も Windows Vista カーネルの詳細に迫ります。
特集
SQL Server インデックスの状態を診断する新しいツール

SQL Server のパフォーマンスを最適化するには、インデックスを監視して、正常な状態を維持する必要があります。この記事では、新しい動的管理ビューと動的管理関数を手がかりに、SQL Server の世界を覗いてみます。これにより、インデックス機能のしくみについての理解が深まり、潜在的なパフォーマンス上の問題を上手に検出できるようになります。

Randy Dyess SQL Server の高可用性を実現する

SQL Server 2005 には、データベースの可用性を向上させるレプリケーション、クラスタリング、ログ配布などのさまざまなオプションがあります。それぞれの環境に適したオプションを見つけるための参考になるように、SQL Server の各種構成オプションについて詳しく説明します。

Zach Nichter テーブル パーティションを使用してデータベースのメンテナンスを簡素化する

以前は、パーティションや大規模なテーブルの操作は手間のかかる面倒な作業でしたが、SQL Server 2005 では、テーブルのパーティション分割がはるかに簡素化されました。これにより、複数のパーティションの作成、移動、古いパーティションの削除、データのパーティション方法の変更を簡単に行うことができるようになりました。その詳細について説明します。

Noah Gomez SQL Server のクラスタリングのヒント

サーバー クラスタを利用するとフェールオーバー機能が提供されるため、重要な処理のための稼働状態を確保します。ただしクラスタの効果を得るためには、適切に実装する必要があります。クラスタの速度を向上させ、確実に起動し続けるようにする主要なヒントをいくつか示します。

Tom Moreau、PhD Windows の管理 Windows Vista カーネルの内部 : 第 2 部

先月に引き続き Windows Vista カーネルの新機能について詳しく説明します。今月号では、Windows Vista のメモリ管理において進歩した点を確認し、システムの起動、シャットダウン、および電源管理の領域について説明します。

Mark Russinovich
コラム
編集者から

Trophy Shelf

Joshua Trupin ツールボックス

IT プロのための新製品

Greg Steen ユーティリティ スポットライト

SyncToy

Jay Munro SQL に関する Q&A

サマータイム、サーバー メモリなど

Nancy Michell The Cable Guy

DHCPv6 プロトコル

Joseph Davies Windows Powershell

変数の機能

Don Jones 		Hey, Scripting Guy!

わずか 5 セントで OU に関する質問に回答する

Microsoft Scripting Guys Exchange Queue & A

トランザクション ログ、コマンドレット、リモート管理など

KC Lemson、Nino Bilic セキュリティ ウォッチ

EFS を展開する : 第 2 部

John Morello デスクトップ ファイル

PsTools 入門

Wes Miller Microsoft.com の内部事情

データベース ミラーリングの概要

Saleem Hakani フィールド ノート

PC ドクターの登場

Matt Hester Windows 秘話

ばかな方が賢く見えることもある

Raymond Chen


 SQL Server: インデックスの状態を診断する新しいツール
SQL Server Randy Dyess

インデックスの状態を診断する新しいツール
概要:
  • インデックスの断片化
  • インデックスの使用
  • インデックス操作の状況
この記事で使用しているコードのダウンロード: DyessSQLIndex2007_03.exe (151KB)

通常、SQL Server のパフォーマンス チューニングでは、データベース内のインデックスの微調整を最優先またはそれに近い優先順位で実行します。SQL Server クエリ オプティマイザで、クエリの実行中にインデックスを正しく利用するためには、有効なインデックスを作成することだけでなく、インデックスの状態にも注意を払う必要があります。
SQL Server™ 2005 で導入された一連の動的管理ビュー (DMV) および動的管理関数 (DMF) は、データベース管理者がインデックスの有効性を確認したり、パフォーマンスの問題を検出したりするのに役立ちます。
DMV と DMF を使用すると、サーバーの状態を調査して、サーバー インスタンスの状態やパフォーマンスの監視、および問題の診断に役立つ情報を取得することができます。以前のバージョンの SQL Server でデータベース管理を行っていた皆さんは、DMV と DMF が DBCC コマンドを置き換える存在であることにお気付きでしょう。DMV と DMF では、特定のシステム ストアド プロシージャを実行したり、多数のシステム テーブルのクエリを送信したり、SQL Profiler を使用してイベントをキャプチャしたりできます。
インデックスが正常に機能しているかどうかを調べるには、sys.dm_db_index_physical_stats、sys.dm_db_index_usage_stats、sys.dm_db_index_operational_stats の 3 つの DMV および DMF を使用すると便利です。これらの DMV および DMF により、インデックスの入出力とロックのパターンを確認し、クエリ オプティマイザがデータベース内で不要な競合を発生させない形でインデックスを利用しているかどうかを判断できます。

インデックスの断片化
DMF の sys.dm_db_index_physical_stats は、DBCC SHOWCONTIG ステートメントの代替機能であり、インデックスの断片化の状態を示します。ただし、DBCC SHOWCONTIG がインデックスを含むテーブルに共有ロック (S) を設定するのに対して、sys.dm_db_index_physical_stats はインテント共有ロック (IS) を設定するだけなので、関数実行中のテーブルのブロックが大幅に低減されます。
sys.dm_db_index_physical_stats を使用してインデックスの断片化を判定するには、関数の実行後に出力される 3 列のデータを確認します。インデックスの論理的な断片化 (ヒープのエクステントの断片化) は、avg_fragmentation 列の値から判断できます。論理的な断片化は、インデックスのリーフ レベルで順序が異なるページの割合で表されます。一方、エクステントの断片化は、インデックスのリーフ レベルで順序が異なるエクステントの割合で表されます。論理的な断片化やエクステントの断片化が発生すると、正しい順序でページを読み取るためにディスク ヘッドの位置をたびたび変更しなければならなくなり、入出力回数とディスク ヘッドの移動回数が増えるため、パフォーマンスが低下するおそれがあります。論理的な断片化もエクステントの断片化も、できる限りゼロに近くなるように工夫してください。
インデックスの内部断片化は、ページのゆとりの割合で表されます。インデックス ページにできるだけゆとりを持たせることはもちろん重要ですが、インデックス ページのゆとりとインデックス ページへの挿入数のバランスをとり、ページ分割数を絶対的な最小値に保つことも重要です。
インデックス ページのゆとりを確認するには、sys.dm_db_index_physical_stats の avg_page_space_used_in_percent 引数を調べます。この値が 100% に近づくように正しく構成するには、ページ分割数を監視しながらインデックスの fillfactor を調整します。インデックスの fillfactor の設定値が大きすぎると、ページ分割数が急増します。インデックスの fillfactor の調整は、時間と手間のかかる作業です。したがって、適切な計画の下に実行する必要があります。なお、ランダムな挿入が行われないインデックスでは、ページ分割数の増加を心配することなく fillfactor を 100 に設定できます。
AdventureWorks.HumanResources.Employee テーブルのすべてのインデックスの断片化のレベルを確認するには、次のようなステートメントを使用します。
SELECT *
FROM sys.dm_db_index_physical_stats (DB_ID('AdventureWorks')
,OBJECT_ID('HumanResources.Employee')
,NULL
-- NULL to view all indexes;
-- otherwise, input index number
,NULL -- NULL to view all partitions of an index
,'DETAILED') -- We want all information
この DMF を使用すると、再構築の必要なインデックス、再編成の必要なインデックス、およびメンテナンスの不要なインデックスを自動的に特定できます。この DMF の avg_page_space_used_in_percent 列と avg_fragmentation_in_percent 列の値は、許容される論理しきい値および密度のしきい値を超えるインデックスの断片化を表します。これらの値を調べると、インデックスに対して実行する処理を決定しやすくなります。
インデックスの状態によっては、図 1 の例で AdventureWorks サンプル データベース内にデータが返されない場合がありますが、この例はその他のデータベースに簡単に適用することができます。
Figure 1 ページのゆとりと断片化の確認 (Close Figure 1)
--Reorganize the following indexes in the AdventureWorks database
USE AdventureWorks
GO

SELECT OBJECT_NAME([object_id]) AS 'Table Name',
index_id AS 'Index ID'
FROM sys.dm_db_index_physical_stats (DB_ID('AdventureWorks')
,NULL -- NULL to view all tables
,NULL -- NULL to view all indexes; otherwise, input index number
,NULL -- NULL to view all partitions of an index
,'DETAILED') --We want all information
WHERE ((avg_fragmentation_in_percent > 10
AND avg_fragmentation_in_percent < 15) -- Logical fragmentation
OR (avg_page_space_used_in_percent < 75
AND avg_page_space_used_in_percent > 60)) --Page density
AND page_count > 8 -- We do not want indexes less than 1 extent in size
AND index_id NOT IN (0) --Only clustered and nonclustered indexes

--Rebuild the following indexes in the AdventureWorks database
USE AdventureWorks
GO

SELECT OBJECT_NAME([object_id]) AS 'Table Name',
index_id AS 'Index ID'
FROM sys.dm_db_index_physical_stats (DB_ID('AdventureWorks')
,NULL -- NULL to view all tables
,NULL -- NULL to view all indexes; otherwise, input index number
,NULL -- NULL to view all partitions of an index
,'DETAILED') --We want all information
WHERE ((avg_fragmentation_in_percent > 15) -- Logical fragmentation
OR (avg_page_space_used_in_percent < 60)) --Page density
AND page_count > 8 -- We do not want indexes less than 1 extent in size
AND index_id NOT IN (0) --Only clustered and nonclustered indexes
クエリの結果をテーブル変数に格納し、このテーブル変数をループして正しい ALTER INDEX ステートメントの動的文字列を構築する作業は、簡単に実行できます (図 2 を参照)。
Figure 2 動的な ALTER INDEX 文字列の構築 (Close Figure 2)
--Rebuild the following indexes in the AdventureWorks database
USE AdventureWorks
GO

--Table to hold results
DECLARE @tablevar TABLE(lngid INT IDENTITY(1,1), objectid INT,
index_id INT)

INSERT INTO @tablevar (objectid, index_id)
SELECT [object_id],index_id
FROM sys.dm_db_index_physical_stats (DB_ID('AdventureWorks')
,NULL -- NULL to view all tables
,NULL -- NULL to view all indexes; otherwise, input index number
,NULL -- NULL to view all partitions of an index
,'DETAILED') --We want all information
WHERE ((avg_fragmentation_in_percent > 15) -- Logical fragmentation
OR (avg_page_space_used_in_percent < 60)) --Page density
AND page_count > 8 -- We do not want indexes less than 1 extent in size
AND index_id NOT IN (0) --Only clustered and nonclustered indexes

SELECT 'ALTER INDEX ' + ind.[name] + ' ON ' + sc.[name] + '.'
+ OBJECT_NAME(objectid) + ' REBUILD'
FROM @tablevar tv
INNER JOIN sys.indexes ind
ON tv.objectid = ind.[object_id]
AND tv.index_id = ind.index_id
INNER JOIN sys.objects ob
ON tv.objectid = ob.[object_id]
INNER JOIN sys.schemas sc
ON sc.schema_id = ob.schema_id
インデックスの使用
sys.dm_db_index_physical_stats は、DBCC SHOWCONTIG ステートメントの代わりに使用してインデックスの状態を確認できる強力な動的管理関数ですが、テーブルに対して実行されるクエリでどのインデックスを使用するのがよいかを特定するというもっと複雑な問題に直面することがよくあります。通常、データベースの開発者や管理者は、クエリの実行中にクエリ オプティマイザが使用すると思われるテーブル上にインデックスを構築します。これまでの SQL Server のリリースでは、これらのインデックスが実際に使用されているかどうかを確認するのは、はるかに困難な作業でした。インデックスを削除してクエリのパフォーマンスが変化するかどうかを確認するか、クエリの実行計画をキャプチャして、インデックスの使用状況をスキャンする必要がありました。
新しい動的管理ビュー、sys.dm_db_index_usage_stats では、クエリ オプティマイザやテーブルに対して実行されるクエリでインデックスがどのように使用されているかを簡単に把握できます。このビューからインデックスの有用性を判断できるので、クエリ オプティマイザが使用していない任意のインデックスを削除することができます。インデックスが記憶域スペースを無駄に占有していないか、未使用のインデックスのメンテナンスによってデータベースのパフォーマンスが低減していないかと心配する必要がなくなりました。
シーク数とスキャン数がゼロのインデックスに対してこの DMV を実行し、その出力を調べることで、そのインデックスが前回 SQL Server を起動したときから使用されているかどうかを判定できます。ただし、多くの DMV および DMF には永続性がありません。DMV や DMF を使用してインデックスの使用状況を確認するときは、SQL Server を再起動すると値がゼロに戻ってしまう点に注意してください。インデックスは、前回サービスを開始したときから不要になっていた可能性もありますが、週末、月末、または四半期末のレポート クエリで必要になります。
前回 SQL Server サービスを再開してから使用されていないインスタンス内のすべてのインデックスを表示するには、次のステートメントを使用します。
SELECT DB_NAME(database_id),OBJECT_NAME([object_id])
FROM sys.dm_db_index_usage_stats
WHERE user_seeks = 0
AND user_scans = 0
AND user_lookups = 0
AND system_seeks = 0
AND system_scans = 0
AND system_lookups = 0

インデックス操作の状況
インデックス操作の状況を把握するには、DMF の sys.dm_db_index_operational_stats を使用すると非常に便利です。sys.dm_db_index_operational_stats では、データベース内の各インデックスについて、入出力、ロック、ラッチ、およびアクセス メソッドのアクティビティを表示できます。ここからインデックスの使用状況を把握し、過剰な入出力アクティビティやインデックス内の "ホット スポット" の存在によって発生するインデックス ロックの問題を診断できます。
この DMF によって出力されるラッチ待機情報は、READ および WRITE 操作でインデックスのリソースにアクセスするために必要な所要時間を割り出すために役立ちます。これにより、インデックスの保存に使用されるディスク サブシステムがインデックスの入出力アクティビティに対して適切であるかどうかを判断できます。また、インデックスのデザインと使用状況によってホット スポットが発生したかどうかも示します。ホット スポットでは、インデックスのページ内のアクティビティが非常に多いため、ページ内でデータの競合が発生します。このような競合が発生すると、通常、この領域に対する READ または WRITE の操作が大量にブロックされます。
図 3 に、AdventureWorks.HumanResources.Employee テーブルのすべてのインデックスのロック パターンと入出力パターンの確認方法を示します。
Figure 3 ロックと入出力のパターンの特定 (Close Figure 3)
SELECT page_latch_wait_count --page latch counts
,page_latch_wait_in_ms --page latch wait times
,row_lock_wait_in_ms --row lock wait times
,page_lock_wait_in_ms --page lock wait times
,row_lock_count --row lock counts
,page_lock_count --page lock counts
,page_io_latch_wait_count --I/O wait counts
,page_io_latch_wait_in_ms --I/O wait times
FROM sys.dm_db_index_operational_stats (DB_ID('AdventureWorks')
,OBJECT_ID('HumanResources.Employee')
,NULL -- NULL to view all indexes; otherwise, input index number
,NULL -- NULL to view all partitions of an index
)

その他の詳細
DVM と DMF には、ここで紹介した以外にもさまざまな使用方法があります。補足記事「参考資料」に挙げた SQL Server Books Online の記事をよく読み、DVM または DMF の出力結果から得られるさまざまな情報について理解を深めてください。
この記事では取り上げなかった DMF および DMV については、SQL Server クエリ最適化チームのブログ記事 (blogs.msdn.com/queryoptteam/570176.aspx) (英語) を参照してください。
参考資料
  • sys.dm_db_index_physical_stats
  • sys.dm_db_index_usage_stats
  • sys.dm_db_index_operational_stats

Randy Dyess は、SQL Server OLTP システムを専門分野とする Solid Quality Learning の指導者です。彼は、SQL Server 関連の書籍や記事を多数執筆しており、
© 2007 Microsoft Corporation and CMP Media, LLC. All rights reserved; 許可なしに一部または全体を複製することは禁止されています.


 SQL Server: SQL Server の高可用性を実現する
SQL Server Zach Nichter

SQL Server の高可用性を実現する
概要:
  • ミラーリング
  • データベース スナップショット
  • ログ配布
  • クラスタリング
  • レプリケーション
この記事で使用しているコードのダウンロード: NichterHA2007_03.exe (151KB)

高可用性は、データベース管理者なら必ず知っておく必要がある概念です。高可用性とは、システムの応答性とアクセシビリティを意味します。高可用性を秒単位の応答時間で示す場合もあれば、1 秒の数分の 1 単位で示す場合

もあります。かつて、私がコンサルティング業務を請け負ったある会社では、Web サーバーで SQL クエリを使用してラウンドトリップ応答時間をミリ秒単位で取得する必要がありました。そこでは、応答が制限時間を超えると、データベース システムが停止していると判断し、Web サーバーは次に使用可能なデータベース サーバーに再接続するようになっていました。
ユーザーがますます高速なアプリケーションを求めるようになっているので、高可用性と高速な応答時間の実現方法を理解することは、データ依存アプリケーションの計画を成功させるために有益です。
SQL Server™ 2005 には、可用性を向上させるレプリケーション、クラスタリング、データベース ミラーリング、データベース スナップショット、データベース ログ配布などのさまざまなオプションがあります。この記事では、これらの機能について説明し、個別の環境に適したオプションを選択する際の判断方法を示します。まずは、SQL Server 2005 の可用性オプションを示した図 1 をご覧ください。
Figure 1 高可用性オプション (Close Figure 1)

テクノロジの属性 | レプリケーション | データベース ミラーリング | クラスタリング | データベース スナップショット | ログ配布
高可用性オプション |  |  |  |  |
高いトランザクション要件に対応する |  |  |  |  |
リアルタイムのデータ可用性 |  |  |  |  |
データ イメージは読み取り専用 |  |  |  |  |
固有のハードウェア構成 |  |  |  |  |
低コスト |  |  |  |  |
データ復元機能 |  |  |  |  |
自動フェールオーバー |  |  |  |  |
実装および管理が複雑になる可能性がある |  |  |  |  |
パフォーマンスに関する検討事項 |  |  |  |  |

高可用性を定義する
高可用性アプリケーションを計画する際の最初の目標は、個別の環境における高可用性の意味を定義することです。組織によっては、高可用性とは、実稼動ハードウェアと同等の冗長ハードウェアを用意し、データとハードウェアのアップタイムおよび可用性を 99.995 以上確保しなければならないことを意味します。一方、データのみの高可用性を確保すればよく、フェールオーバーが必要になった場合も実稼動レベルのパフォーマンスをそれほど考慮しなくてもよい組織もあります。高可用性の定義は、状況に応じて適切なソリューションを選択するために重要です。
また、起こり得るシステム停止の種類を特定し、その停止がサービス レベル契約 (SLA) にどのような影響を及ぼすかを明示しておく必要もあります。可用性に影響する可能性がある停止には、計画的停止、計画外停止、パフォーマンス低下などがあります。
計画的停止は、通常、事前のユーザー通知のためにスケジュールされたメンテナンス ウィンドウが原因で生じるシステム停止です。計画外停止は、一般に、ハードウェアまたはソフトウェアの障害が原因でユーザーのデータ アクセスが停止する状態を指します。パフォーマンスの低下もシステム停止の原因となります。パフォーマンスが低下したかどうかは、通常、何らかの形式の SLA で企業や IT 部門との間で事前に合意されているエンドユーザーの応答時間によって判断されます。
システム停止の原因となり得る要素を特定する以外に、データのアクティビティ レベルや、常時オンラインである必要があるか、それとも時にはニアラインまたはオフラインでかまわないかも決める必要があります。また、可用性オプションを同じ敷地に置くか、遠隔地に置くかを決める必要があります。予算の制約も選択の要因になります。各可用性オプションを個別に検討していきましょう。

データベース ミラーリング
データベース ミラーリングの詳細を説明する前に、用語を定義しておきます。
プリンシパル は、トランザクション ログを継続的にミラー サーバーおよびデータベースに送信するデータベースが格納されるプライマリ実稼動サーバーです。
ミラー は、データベースのバックアップ コピーが格納されるセカンダリ サーバーです。ミラー コピーは、一貫してプリンシパル データベースと同期しています。
ロール は、個々のサーバーの用途 (プリンシパルまたはミラーのいずれであるか) を示します。
ウィットネス は、プリンシパル サーバーおよびミラー サーバーの機能の実行を監視するインスタンスであり、自動フェールオーバーを開始する機能があります。
パートナー は、プリンシパル サーバーまたはミラー サーバーのいずれかにすることができます。
一般的な環境では、プリンシパル データベースはプリンシパル インスタンス上でバックアップされ、そのバックアップがミラー インスタンス上で復元されます (図 2 を参照)。データベースの復元が完了したら、SQL Server Management Studio (SMSS) のプリンシパル データベースのプロパティ ウィンドウまたは T-SQL スクリプトを使用して、ミラーリングをプリンシパル サーバーに設定する必要があります。
Figure 2 Database mirroring architecture
Figure 2 Database mirroring architecture (画像を縮小するには、ここをクリックします)
Figure 2 Database mirroring architecture
Figure 2 Database mirroring architecture (画像を拡大するには、ここをクリックします)
ミラーリングの設定が完了し、ミラーリング セッションが確立されると、プリンシパル データベースとミラー データベースが同期されます。次に、プリンシパル データベースは、ミラー上で最後にバックアップが適用されて以後に発生したイベントのトランザクション ログを送信します。ミラーはログを受信するとすぐに適用を試行します。SQL Server 2005 Enterprise Edition を使用している場合、このプロセスはマルチスレッドで処理され、それ以外の場合はシングルスレッドで処理されます。ログがミラーに適用されるとデータベースは同期されたものと見なされ、ミラー セッションが切断されるまでその同期は維持されます。
クライアントが新しいトランザクションを実行すると、プリンシパル サーバーはプリンシパル データベースに対してトランザクションを実行し、その間にトランザクション ログの記録がプリンシパル データベースからミラー データベースの REDO ログまたはログ キューに配布されて、そこから取得したログがミラー データベースに適用されます。トランザクションの適用が完了し、ミラー データベース上でコミットされると、トランザクションがミラー上でコミットされたことを通知する応答がプリンシパルに送信されます。プリンシパルは、ミラーから確認応答を受信した後に新しいトランザクションの存在を確認します。
障害が発生した場合、ミラーは自動フェールオーバーを開始し、プリンシパル データベースが使用可能であるかどうかを判断して、ウィットネスでプロセスをサポートすることができます。障害が発生した場合、ミラー パートナーで発生している問題を解決するまでは、そのミラー パートナーをプリンシパル パートナーとして使用することはできません。ミラー パートナーの問題を解決した後、ミラー パートナー サーバーへの復帰が開始され、データベースが再同期されます。同期が完了したら、ミラーリング セッションを再開できます。
このミラーリング モードは、トランザクションの安全性オプションを有効にして同期トランザクション処理を行う高安全性モードですが、自動フェールオーバーを利用せず、すべてのフェールオーバーを手動で開始するため、ウィットネスは不要です。同期トランザクション処理を行う 2 つ目のミラーリング モードは、高可用性モードです。高可用性モードでは、トランザクションの安全性オプションを有効にすると共に、ウィットネスを使用して、障害が発生した場合に自動フェールオーバーが行われるようにする必要があります。
3 つ目のミラーリング モードは、高パフォーマンス モードです。高パフォーマンス モードでは、非同期処理をサポートするためにトランザクションの安全性を無効にし、トランザクション レコードがミラーに書き込まれるまで待機しなくてもプリンシパル パートナー上のトランザクションをコミットできるようにします。高パフォーマンス モードではウィットネスの構成は不要です。
ミラーリングでは、プリンシパルとミラーには SQL Server の同一エディションを使用する必要がありますが、ウィットネスのエディションは同じである必要はなく、SQL Server Express Edition を使用することもできます。また、プリンシパル データベースを完全復旧モードにすることが重要です。
ADO.NET 2.0 が SQL Server 2005 に統合されて、データベース ミラーリングがサポートされ、アプリケーションをミラー環境に透過的にフェールオーバーできるようになりました。これにより、プリンシパル データベースに接続できない場合に、新たにコーディングや構成を行わなくても、ADO.NET アプリケーションを自動フェールオーバーすることが可能です。構成は、2 つの環境間の共通ユーザーとフェールオーバー パートナーを接続文字列に指定する場合と同程度に簡単です。ミラー データベース環境のフェールオーバー パートナーを指定する ADO.NET 接続文字列の例を次に示します。
"Provider=SQLNCLI.1;Data Source=MirrorDB;Failover Partner=SQL03;
 Initial Catalog=AdventureWorks;
Persist Security Info=True;User ID=TestUser; Password=TestPswd; Pooling=True;
Connect Timeout=5;Application Name=ADOMirrorTest"
データベース ミラーリングはアプリケーションおよびデータの要件によっては有効なオプションですが、パフォーマンスの最適化に関して検討を要する事項がいくつかあります。たとえば、システムのトランザクション レートや変更されるデータ量がどの程度であるかを考える必要があります。データベース ミラーリングを検討する場合、データ量およびトランザクションの処理レートに対して、帯域幅とネットワーク速度が十分であるかどうかを判断することが不可欠です。また、リンクの飽和についても検討してください。この点は、ミラーが遠隔地に存在する場合に特に重要です。システムを事前に監視することは、ミラーリングの効率的な処理を妨げる環境上の制限の有無を確認するのに不可欠です。
データベース ミラーリングの特長は、低コストな選択肢であるということです。データベース ミラーリングのアーキテクチャでは、共有ディスクが不要であり、環境の運用に高度なスキルや専門性を必要としません。また、クラスタリングと異なり、データベース ミラーリングではパートナー同士で同じハードウェアを使用する必要がありません。さらに、ミラーリングは、データベースのプロパティ ウィンドウのミラーリング タブにあるセットアップ ウィザードを使って簡単に実装できます (図 3 を参照)。詳細については、go.microsoft.com/fwlink/?LinkId=80897 に掲載されているホワイトペーパーの記事「Database Mirroring Best Practices and Performance Considerations」(英語) を参照してください。
Figure 3 Mirroring setup wizard
Figure 3 Mirroring setup wizard (画像を縮小するには、ここをクリックします)
Figure 3 Mirroring setup wizard
Figure 3 Mirroring setup wizard (画像を拡大するには、ここをクリックします)

データベース スナップショット
データベース スナップショットは SQL Server 2005 Enterprise Edition で登場した新しいテクノロジですが、高可用性オプションが考慮されていません。データベース スナップショットは、他のテクノロジと併用した場合の復元またはレポート オプションとして使用してください。スナップショットは、特定時点のデータベースの読み取り専用ビューです。
スナップショットの作成には、次のように CREATE DATABASE コマンドを使用します。
CREATE DATABASE SnapDB_20061028_2030 ON
(NAME = SnapDB_Data, FILENAME =
    'C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Data\SnapDB_20061028_2030.snp')
AS SNAPSHOT OF SnapDB;
GO
データベース スナップショットを作成する際は、通常のデータベースで使用されるデータ ファイルではなく、スパース ファイルと呼ばれる 1 つまたは複数のファイルが使用されます。これらのスパース ファイルとは、基本的に、最初はデータが存在しない仮想の格納場所です。ソース データベースのデータが変更または削除された場合にのみ、スパース ファイルにデータが格納されます。スパース ファイルにデータが書き込まれるのは一度に 1 データ ページずつであり、データベース スナップショットには、そのスナップショットを取得して以後に変更されたデータのみが表示されます。それ以外のデータは、ソース データベースのデータ ページから取得されます。
データベース スナップショットのファイルは、スナップショット取得時のデータベース サイズで割り当てられます。割り当てられたサイズでは、実際のデータ サイズはわかりません。データ サイズを取得するには、次のような T-SQL ステートメントを実行します。
SELECT *
FROM fn_virtualfilestats(DB_ID(N'SnapDB_20061028_
    2030'), 1);
GO

スパース ファイルおよびソース データベースのデータの格納方法のため、データベース スナップショットにアクセスすると、元のデータベースのデータ ファイルのデータ ページとスナップショットのスパース ファイルのデータ ページが取得されます。スナップショットは、データ ページを共有する必要があるため、そのスナップショットの取得元のソース データベースが存在するサーバー上にのみ格納できます。このアーキテクチャでは、ソース データベースの I/O が軽減されないため、データベースの実態を表さないスナップショットは、レポート オプションとしては有効ではありません。
データベース ミラーリングとスナップショットの併用を検討してください。この場合、データのレポート、ミラー、スナップショット データベースの機能をプリンシパル データベースから物理的に切り離すことが可能です。SQL Server エージェントおよびカスタム スクリプトを使用してデータベース スナップショットをスケジューリングし、スナップショットが定期的に更新されるようにします。図 4 のサンプル スクリプトは、この機能を実行するストアド プロシージャを示しています。このスクリプトは、環境内の特定のデータベースのスナップショットの作成および削除を管理するジョブの内部で使用するように設計されています。これで、レポート データが実稼動データから切り離されるため、使用に耐えるレポート ソリューションになります。
Figure 4 スナップショットをスケジュールするストアド プロシージャ (Close Figure 4)
use msdb;
GO
set nocount on
GO

CREATE PROCEDURE usp_snaprefresh
     @database    sysname = NULL    --name of the database to snapshot
    ,@keepsnap    int        = 24   --# of hours to keep a snapshot
                                    --after it was created
                                    --use a value of '0' to keep all
                                    --existing snapshots
    ,@fileloc    sysname            --location for snapshot
        = 'C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Data\'
AS

DECLARE
     @dt            datetime        ,@cnt          int
    ,@databaseid    int             ,@snap         sysname
    ,@sql           nvarchar(1000)  ,@yy           varchar(4)
    ,@mm            varchar(2)      ,@dd           varchar(2)
    ,@h             varchar(2)      ,@m            varchar(2)
    ,@lname         sysname         ,@pname        sysname
    ,@file          sysname         ,@pos1         int
    ,@pos2          int

-- initialize variables
SELECT
     @dt = getdate()
    ,@cnt = 0, @pos1 = 0, @pos2 = 0
    ,@databaseid = db_id(@database)

-- check if valid database was provided
IF @databaseid IS NULL
BEGIN
    RAISERROR ('Missing database name. Rerun the procedure specifying a
       valid database name.',16,1)
    RETURN (0)
END

--determine if snapshots should be kept
IF @keepsnap <> 0
BEGIN
    -- determine if other snapshots exist for this server older than @
    -- keepsnap value hrs
    SELECT ROW_NUMBER() OVER(ORDER BY name DESC) AS [RowNum],
        name INTO #t1
    FROM master.sys.databases
    WHERE source_database_id = @databaseid
        AND create_date < dateadd(hh,-(@keepsnap),getdate())

    IF (SELECT max(RowNum) FROM #t1 where name is not null) > 0
    BEGIN
        WHILE @cnt <= (SELECT max(RowNum) FROM #t1)
        BEGIN
            SELECT @snap = name FROM #t1 WHERE RowNum = @cnt

            PRINT 'Dropping snapshot ''' + @snap + ''''

            SET @sql = 'DROP DATABASE ' + @snap

            EXEC(@sql)
            SELECT @cnt = @cnt + 1
        END
    END
END

-- break apart point in time date time information for file name
SELECT @yy = convert(varchar(4),year(@dt)),@mm = convert(varchar(2),
   month(@dt))
    ,@dd = convert(varchar(2), day(@dt)),@h = convert(varchar(2),
         datepart(hh,@dt))
    ,@m = convert(varchar(2), datepart(mi,@dt))

-- piece together the database snapshot name and the file name
SELECT @file = @database + '_' + @yy + @mm + @dd + '_' + @h + @m

-- identify logical file name of primary data file
SET @sql = 'SELECT name INTO tempdb..t1
FROM ' + @database + '.sys.database_files
WHERE file_id = 1'

EXEC(@sql)

--setting logical filename for the snap
SELECT @lname = name FROM tempdb..t1

-- making sure the file location ends with '\'
IF substring(@fileloc, len(@fileloc), 1) <> '\'
BEGIN
    SET @fileloc = @fileloc + '\'
END

-- build sql statement to be run
SET @sql = N'CREATE DATABASE ' + @file + ' ON
(NAME = ' + @lname + ', FILENAME = ''' + @fileloc + @file + '.snp'')
AS SNAPSHOT OF ' + @database

EXEC(@sql)

-- cleanup
DROP TABLE tempdb..t1;
GO
ただし、スナップショットはバックアップできませんし、ソース データベースなしでは存在し得ないものですから、データベース スナップショットは一時的な存在であるということを忘れないでください。スパース ファイルの容量が不足すると、スナップショットは破損したものと解釈されて削除されます。
また、データベース スナップショットを使用すると、ソース データベースのデータ ファイルからのスナップショット 1 つごとにデータ ページがスパース ファイルに書き込まれるため、ソース データベースのデータを変更するときにシステムのパフォーマンスが低下する場合があります。つまり、書き込み回数はデータベースが所有しているスナップショットの数の倍数になるということです。
読み取りアクセス許可はスナップショットの取得時にソース データベースによって定義され、変更はできません。スナップショットはデータ ページおよび同一のバッファ キャッシュをソース データベースと共有しているため、ソース データベースと同じインスタンスに存在する必要があります。
スナップショットをレポート ソリューションに使用することを検討するのは、ミラーリングの場合のみにしてください。それ以外の環境では、パフォーマンス上のメリットはありません。システム上で問題のある処理が実行されないかぎり、データベース スナップショットはデータを保持する最速の方法になる可能性があります。データベースをスナップショットの状態に戻したり、スナップショットから取得したデータでソース データベースのデータを置換することができます。
スナップショット データベースの命名標準を決める必要があります。私は originaldatabasename_date_time.snp という標準を使用しています。これで、ソース データベースを最初に指定し、次にスナップショットを取得した日付と時刻 (24 時間形式) を指定します。

ログ配布
ログ配布は、バックアップと復元を利用した低コストのソリューションを実現する、制限された高可用性オプションです。ログ配布では、トランザクション ログのバックアップをスケジュールされた間隔で実行して、セカンダリ データベースを最新の状態に保ちます。
SQL Server 2005 のログ配布では、ウィザードを使用して、セットアップ、スケジューリング、初期化、監視のプロセスを操作します (図 5 を参照)。このプロセスは単純で、数分で完了します。
Figure 5 Log shipping setup wizard
Figure 5 Log shipping setup wizard (画像を縮小するには、ここをクリックします)
Figure 5 Log shipping setup wizard
Figure 5 Log shipping setup wizard (画像を拡大するには、ここをクリックします)

プライマリ データベースを指定すると、スケジュールが作成され、バックアップ ファイルのファイル経過時間が決まります。次に、バックアップ ファイルのファイル共有を設定する必要があります。ファイル共有の設定が完了したら、セカンダリ データベース ファイルの場所を設定し、プライマリ データベースの復元を完了することによってデータベースを初期化する必要があります。バックアップ ファイルのコピー、トランザクション ログのバックアップの復元、および各手順に必要なアラートや遅延をスケジューリングすることも必要です。
設定が完了すると、ログ配布によりスケジュールされた間隔でデータベースのトランザクション ログが共有ネットワークの場所にバックアップされます。ファイルが共有に送信された後、設定されたスケジュールでセカンダリ データベースにバックアップが適用されます。
ログ配布は単純であるという利点から、さまざまな場面で有効です。これは、低コストで高トランザクション システムに対処する場合に適した高可用性オプションです。ログ配布に使用するセカンダリ データベースは読み取り専用モードで使用することが可能であるため、レポート データベースに便利です。ログ配布はオーバーヘッドが小さい代わりに、エラー処理時にアラート ポリシーが必要になります。
環境内でのログ配布の使用を検討する場合に考慮すべき点は、セットアップおよび管理が簡単であることと、専門的なスキルがほとんど不要であるということです。ログ配布はリアルタイムの高可用性ソリューションではありませんが、データベース ミラーリングと組み合わせてリアルタイム ソリューションを実現することが可能です。ログ配布の機能は、スケジュールと、バックアップ、ファイル コピー、復元などの操作によって制約されます。また、手動フェールオーバーが必要です。これらの理由から、ログ配布は時間要件が重視されない環境に適した単純なソリューションといえます。

SQL Server のクラスタリング
サーバー クラスタリングは OS レベルで動作し、ハードウェアの二重化や、クラスタのディスク リソースの共有によるアクセスを行います。クラスタリングは、エンドユーザーに対する侵入の可能性が低い代わりに高コストなオプションです。最低でも非クラスタ化インスタンスの数の 2 倍のハードウェアが必要になります。
クラスタリングの内容は非常に複雑なので、ここでは詳細には立ち入らず、全体的な概要を説明します。クラスタリングでは複数のサーバーを使用し、そのすべてに同一バージョンの OS (Windows® 2000 Advanced Edition または Datacenter Edition、あるいは Windows Server® 2003 Enterprise Edition または Datacenter Edition) をインストールする必要があります。Microsoft® クラスタ サービス (MSCS) もインストールする必要があります。MSCS は、サーバー間の共有リソースの所有権を処理し、IP アドレス、共有ディスク、およびネットワーク名を管理します。クラスタリングには、共有ディスク リソースも必要です。一般的な共有ディスク リソースの形態は、ストレージ エリア ネットワーク (SAN) または SCSI 接続ストレージです。
SQL Server インスタンスもリソースと見なされ、SQL Server 2005 Standard Edition および Enterprise Edition のいずれでもクラスタ構成にインストールできます。SQL Server 2005 Standard Edition および Enterprise Edition でサポートされる機能の一覧については、「SQL Server 2005 エディション別機能比較表」(microsoft.com/japan/sql/prodinfo/features/compare-features.mspx) を参照してください。
リソースをクラスタに設定すると、クラスタのセカンダリ ノードは、クラスタの 2 つのノード間のプライベート ネットワーク上に設定されたハートビートを使用して、プライマリ ノードとの定期的な通信を維持します。ハートビートは、プライマリ ノードで障害が発生しているかどうかを確認する間隔的なチェックポイントです。
プライマリ ノードで障害が発生した場合、リソースはセカンダリ ノードに移動し、論理サーバーの状態はそのまま残ります。これにより、クライアントは、ほんの一時の中断だけで通信を続けることができます。フェールオーバーの全プロセスは、クラスタ内のハードウェア、ソフトウェア、ネットワーク コンポーネントに応じて 5 ～ 30 秒前後で完了します。
クラスタリングは高コストで、システムの障害を解決するには専門的なスキルを要する複雑なテクノロジですが、何らかの自動フェールオーバー オプションを選択しているエンドユーザーに対してきわめてスムーズなフェールオーバーを提供します。個々のアプリケーションは多様であり、クラスタに対応していない場合や、互換性がない場合があるため、最悪の場合にはアプリケーションの再接続が必要になります。

レプリケーション
SQL Server 2005 では、レプリケーションも高可用性アーキテクチャに使用可能です。レプリケーションには、スナップショット、トランザクション、ピアツーピア、マージの 4 種類があります。ピアツーピアは、トランザクション レプリケーションの一形態なので、ここでは説明しません。
レプリケーションには、プライマリ データベースと全く同様に機能するセカンダリ サイトとセカンダリ データベースを用意して高可用性を実現するオプションがあります。それには、マージ レプリケーションを使用します。マージ レプリケーションでは、プライマリ データベースとセカンダリ データベースからトランザクションを取得し、2 つのデータベースの差分を相互にマージします。ご想像どおり、この構成では競合を解決する処理が必要です。
トランザクション レプリケーションの論理設計はデータベース ミラーリングとよく似ています。プライマリ データベースに適用するトランザクションをセカンダリ データベースに配布して、環境の整合性を確保します。配布されたトランザクションはセカンダリ データベースに適用され、次のトランザクションがシステム上で適用されるまで待機します。
スナップショット レプリケーションは、スケジュールされた間隔で実行され、コミットされるたびに個々のトランザクションを 2 つのシステムに適用するのではなく、セカンダリ データベースを一括更新するという点でログ配布とよく似ています。スナップショット レプリケーションとログ配布の利用方法はほぼ同じです。
レプリケーションには専門知識が必要であるため、専門のデータベース管理者が不在の環境では、これが大きな課題になります。レプリケーションのトラブルシューティングは複雑になる傾向があり、高可用性オプションとして使用する場合には設計も複雑になります。
レプリケーションは、高可用性ソリューションの要件を適切な方法で満たすことができます。このテクノロジでは、トランザクション レプリケーションを使用して、データベース ミラーリングの機能をレコード レベルで実現することが可能ですが、自動フェールオーバーのためのオプションはありません。十分なリソースと多少の工夫があれば、自動フェールオーバー ソリューションのスクリプトを作成することも無理ではありません。
データベース ミラーリングとは異なり、ソース データベースおよびターゲット データベースにクライアント アプリケーションから完全にアクセス可能です。レプリケーションは、スナップショット レプリケーションを使用したログ配布と同様の機能を果たします。
ただし、レプリケーションは実践証明済みのテクノロジであり、ドキュメントも整備されているという点も考慮に入れてください。レプリケーションを高可用性ソリューションとして使用するには短所もあり、パフォーマンスが問題になりますが、この問題はデータベース ミラーリングも同様です。レプリケーションを使用した高可用性ソリューションの設計は、管理が複雑になる傾向があります。必ずしも高度になるとはいえませんが、確実に複雑になります。また、データベース テーブルの構造が変更された場合や、レプリケーションの対象となるテーブルを追加する場合に、2 つのデータベースに変更を反映させるためにパブリケーションを中断して再定義する必要があるということも重大な課題です。

まとめ
個別の環境に適した高可用性ソリューションを構築するには、多少の創造性が必要だということがおわかりになったと思います。SQL Server 2005 高可用性テクノロジのそれぞれに長所と短所があり、どの方法が適しているかは状況によって異なります。
プライマリ Web データベースがセカンダリ データベース環境と離れた場所にある場合には、高パフォーマンス モードのログ配布、スナップショト レプリケーション、およびデータベース ミラーリングが適しています。セカンダリ データをリアルタイムに使用可能にする必要がない場合は特にこれらのオプションが有効です。
一方、セカンダリ データベースのリアルタイム データが必要な場合には、トランザクション レプリケーションまたはデータベース ミラーリングを使用すると、プライマリ サーバーのトランザクション レートが低い場合に負荷を分散して 2 つの環境間のリンクを高速化し、かつ飽和しなくなるようにすることができます。
これらのテクノロジの快適性も検討してください。いずれかのテクノロジを既に使用した経験があれば、なおよいでしょう。専門のデータベース管理者が不在な場合、レプリケーションのように変更が多く、トラブルシューティングが煩雑になりがちな複雑なテクノロジを使用しないで済む方法を検討してください。または、経験豊富な SQL Server コンサルタントに設計および実装の支援を依頼し、場合によっては、環境に適した新しい高可用性を管理するための人材トレーニングを委託することを検討してもよいでしょう。
求められる高可用性がデータの高可用率のみで、ダウンタイムが重大な問題とされる場合は、クラスタリングが適しています。
大事なことは、SQL Server 2005 には各種の環境に応じて高可用性を実装する新しいオプションが複数あるということです。1 つのオプションで事足りる場合もあるでしょうし、複数のテクノロジを組み合わせることも可能です。豊富な選択肢が用意されています。

Zach NichterSQL Server の専門家として 10 年以上の経験があります。これまでに DBA、チーム リーダー、マネージャ、コンサルタントなど、SQL Server に関する数々のサポートの役割を果たしてきました。現在は Levi Strauss & Co. の DBA 設計者として、主に SQL Server のパフォーマンス、監視、アーキテクチャ、およびその他の戦略的構想に携わっています。


 SQL Server: テーブル パーティションを使用してデータベースのメンテナンスを簡素化する
SQL Server Noah Gomez

テーブル パーティションを使用してデータベースのメンテナンスを簡素化する
概要:
  • パーティション テーブルを作成する
  • パーティションを追加およびマージする
  • パーティション インデックスを作成および管理する
この記事で使用しているコードのダウンロード: GomezPartitioning2007_03.exe (156KB)

以前は、データベース管理者は、数百万行のデータ量があるテーブルを管理する場合には複数のテーブルを作成せざるを得ませんでした。テーブルをパーティションに分割すると、管理者はそれらのテーブルの多くのクエリの実行中に
テーブルを結合して戻す必要があります。パーティションを結合するには、データが存在する場所を特定するパーティション ビューまたはラッパー ストアド プロシージャを作成し、データセットの取得に必要なパーティションのみを検索する別のストアド プロシージャを実行する必要があります。
この方法で機能は果たしますが、手間がかかります。複数のテーブルやインデックスの管理、およびテーブルの関連付けに使用する方法は、しばしば管理およびメンテナンス上の問題を引き起こします。また、複数のテーブルを作成してデータを分割すると、ストアド プロシージャ、メンテナンス ジョブ、データ変換サービス (DTS) ジョブ、アプリケーション コードなどのプロセスにパーティションの性質を認識させる必要があるため、柔軟性が低下します。そこで、コードを変更しなくてもこれらの擬似パーティションを追加または削除できるようにするために、通常、これらの要素は非動的な方法で作成され、結果として非効率的になります。
SQL Server™ 2005 Enterprise Edition および Developer Edition では、1 つのテーブルに格納されている膨大なデータを複数の小さいパーティションに分割して効率的に管理およびメンテナンスすることができます。単一のエントリポイントでデータ セグメントを作成できるため、従来の多くの管理上の問題が軽減されます。単一のエントリ ポイント (テーブル名またはインデックス名) を使用することで、複数のデータ セグメントがアプリケーション コードから隠蔽されるため、管理者や開発者はコード ベースを調整しなくても、必要に応じてパーティションを変更できます。
つまり、アプリケーションのコードを変更せずに、複数のパーティションの作成、移動、古いパーティションの削除、データのパーティション方法の変更を行うことができるということです。アプリケーション コードでは、同じベース テーブルまたはインデックス名を呼び出すだけです。また、個々のインデックスに格納されるデータ量が減り、これらのインデックスのメンテナンスにかかる時間も短縮されます。データを空のパーティションに読み込めば、読み込み速度も向上します。
技術的には、SQL Server 2005 では、すべてのテーブルがパーティションに分割され、すべてのテーブルに 1 つ以上のパーティションが存在します。SQL Server 2005 では、データベース管理者は個々のテーブルにパーティションを追加できます。テーブルおよびインデックスのパーティションは固定定義された低レベルのパーティションであり、列単位のパーティションは作成できませんが、単一エントリ ポイント (テーブル名またはインデックス名) を使用できるため、エントリ ポイントの背後にあるパーティションの数をアプリケーション コードが意識する必要はありません。パーティションは、ベース テーブル上およびベース テーブルに関連付けられたインデックス上に作成できます。

パーティション テーブルを作成する
既定の単一パーティションを超えて増加する機能を持つテーブルを作成するには、パーティション関数やパーティション スキームを使用します。これらのオブジェクトにより、ストレージ設計時にデータをセグメントに分割し、これらのセグメントの配置を制御することができます。たとえば、データの経過時間などの共通の識別情報に基づいて複数のドライブ配列にデータを分散させることができます。1 つの列に基づいてテーブルをパーティションに分割することができますが、各パーティションには、他のパーティションに配置できないデータを格納する必要があることに注意してください。
パーティション関数: テーブルをパーティションに分割する場合、まず、データをどのようなセグメントに分割するかを決めます。パーティション関数を使用して、データの各行を異なるパーティションにマップします。これらのデータの各行は、text、ntext、image、xml、timestamp、varchar(max)、nvarchar(max)、varbinary(max)、別名データ型、共通言語ランタイム (CLR) ユーザー定義データ型以外の任意のデータ型の列によってマップ可能です。ただし、パーティション関数はデータ行を 1 つのテーブル パーティションのみに配置できるようにする必要があります。つまり、1 つのデータ行が一度に複数のパーティションに所属できないようにします。
テーブルをパーティションに分割するには、対象テーブルにパーティション列を作成する必要があります。パーティション列は、作成済みのテーブルのテーブル スキーマに配置できます。または、テーブルを変更して、後から列を追加することもできます。列には NULL 値を使用できますが、NULL 値が格納されているすべての行は、既定でテーブルの一番左のパーティションに配置されます。これを避けるには、パーティション関数を作成するときに、NULL 値がテーブルの一番右のパーティションに配置されるように指定します。左のパーティションを使用するか、右のパーティションを使用するかは、パーティション スキーマを変更してパーティションを追加する場合や、既存のパーティションを削除する場合のための設計上の重要な選択になります。
パーティション関数を作成する際、LEFT または RIGHT のいずれかのパーティション関数を選択できます。LEFT パーティションと RIGHT パーティションの違いは、パーティション スキーム内での境界値の配置です。LEFT パーティション (既定値) には、パーティションの境界値が含まれますが、RIGHT パーティションでは、境界値は次のパーティションに配置されます。
この概念をもう少しよく理解するために、次の単純な LEFT および RIGHT パーティションを見てみましょう。
CREATE PARTITION FUNCTION Left_Partition (int) AS RANGE LEFT
FOR VALUES (1,10,100)

CREATE PARTITION FUNCTION Right_Partition (int) AS RANGE RIGHT
FOR VALUES (1,10,100)
最初の関数 (Left_Partition) では、値 1、10、および 100 がそれぞれ 1 番目、2 番目、および 3 番目のパーティションに配置されます。2 番目の関数 (Right_Partition) では、値はそれぞれ 2 番目、3 番目、および 4 番目のパーティションに配置されます。
パーティション テーブルを作成する際は、パーティションをなるべく均等に取得することが重要です。それにより、パーティションに必要な領域を把握しやすくなります。LEFT および RIGHT を使用すると、データの配置が決まり、これによりパーティションのサイズと、そのパーティションに作成したインデックスのサイズも決まります。
データの値を配置するパーティション番号を指定するには、次のように $PARTITION 関数を使用します。
SELECT $PARTITION.Left_Partition (10)
SELECT $PARTITION.Right_Partition (10)
最初の SELECT ステートメントの結果は 2、2 番目の SELECT ステートメントの結果は 3 です。
パーティション スキーム: 関数を作成してデータの分割方法を決めたら、個々のパーティションをディスク サブシステム上のどこに作成するかを決める必要があります。パーティション スキームを使用してディスク レイアウトを作成します。パーティション スキームでは、ファイル グループを利用して各パーティションをディスク サブシステムに配置することによって、個々のパーティションのディスク ストレージを管理します。パーティション スキームを構成して、すべてのパーティションを 1 つのファイル グループに配置するか、すべてのパーティションを異なるファイル グループに配置するか、または複数のパーティションでファイル グループを共有することができます。後者の方法を選択すると、データベース管理者はディスク I/O をきわめて柔軟に分散できます。
図 1 は、1 つまたは複数のファイル グループをパーティション スキームに割り当てる方法を示しています。パーティション スキームで使用するファイル グループは、パーティション スキームを作成する前にデータベースに存在している必要があります。
Figure 1 ファイル グループをパーティション スキームに割り当てる (Close Figure 1)
--Place all partitions into the PRIMARY filegroup
CREATE PARTITION SCHEME Primary_Left_Scheme
AS PARTITION Left_Partition
--Partition must currently exist in database
      ALL TO ([PRIMARY])

--Place all partitions into the different filegroups
CREATE PARTITION SCHEME Different_Left_Scheme
AS PARTITION Left_Partition
--Partition must currently exist in database
      TO (Filegroup1, Filegroup2, Filegroup3, Filegroup4)
--Filegroups must currently exist in database

--Place multiple partitions into the different filegroups
CREATE PARTITION SCHEME Multiple_Left_Scheme
AS PARTITION Left_Partition
--Partition must currently exist in database
      TO (Filegroup1, Filegroup2, Filegroup1, Filegroup2)
--Filegroups must currently exist in database
図 1 のようなサンプル パーティション関数を作成し、パーティション スキームを使用してテーブルを作成する場合、個々のデータ行を新しくパーティション分割したテーブルのどこに配置するかを指定できます。これらのデータ行をパーティション テーブルに挿入した後で、データ行の分布を表示できます。この操作を実行するコードは図 2 のようになります。
Figure 2 データ行を配置して分布を表示する (Close Figure 2)
--Prepare database
IF OBJECT_ID('Partitioned_Table') IS NOT NULL
DROP TABLE Partitioned_Table
GO

IF EXISTS(SELECT [name] FROM sys.partition_schemes
WHERE [name] = 'Primary_Left_Scheme')
DROP PARTITION SCHEME Primary_Left_Scheme
GO

IF EXISTS(SELECT [name] FROM sys.partition_functions
WHERE [name] = 'Left_Partition')
DROP PARTITION FUNCTION Left_Partition
GO

--Create partitioned table
CREATE PARTITION FUNCTION Left_Partition (int) AS RANGE LEFT
FOR VALUES (1,10,100)

--Place all partitions into the PRIMARY filegroup
CREATE PARTITION SCHEME Primary_Left_Scheme
AS PARTITION Left_Partition
      ALL TO ([PRIMARY])

CREATE TABLE Partitioned_Table
(
col1 INT
,col2 VARCHAR(15)
) ON Primary_Left_Scheme (col1)

--Determine where values will be placed (this is not required)
--You should try to do this before executing the code
SELECT $PARTITION.Left_Partition (1)
SELECT $PARTITION.Left_Partition (2)
SELECT $PARTITION.Left_Partition (3)
SELECT $PARTITION.Left_Partition (4)
SELECT $PARTITION.Left_Partition (10)
SELECT $PARTITION.Left_Partition (11)
SELECT $PARTITION.Left_Partition (12)
SELECT $PARTITION.Left_Partition (13)
SELECT $PARTITION.Left_Partition (14)
SELECT $PARTITION.Left_Partition (100)
SELECT $PARTITION.Left_Partition (101)
SELECT $PARTITION.Left_Partition (102)
SELECT $PARTITION.Left_Partition (103)
SELECT $PARTITION.Left_Partition (104)

--Insert data into partitioned table
INSERT INTO Partitioned_Table VALUES (1,'Description')
INSERT INTO Partitioned_Table VALUES (2,'Description')
INSERT INTO Partitioned_Table VALUES (3,'Description')
INSERT INTO Partitioned_Table VALUES (4,'Description')
INSERT INTO Partitioned_Table VALUES (10,'Description')
INSERT INTO Partitioned_Table VALUES (11,'Description')
INSERT INTO Partitioned_Table VALUES (12,'Description')
INSERT INTO Partitioned_Table VALUES (13,'Description')
INSERT INTO Partitioned_Table VALUES (14,'Description')
INSERT INTO Partitioned_Table VALUES (100,'Description')
INSERT INTO Partitioned_Table VALUES (101,'Description')
INSERT INTO Partitioned_Table VALUES (102,'Description')
INSERT INTO Partitioned_Table VALUES (103,'Description')
INSERT INTO Partitioned_Table VALUES (104,'Description')

--View the distribution of data in the partitions
SELECT ps.partition_number
,ps.row_count
FROM sys.dm_db_partition_stats ps
INNER JOIN sys.partitions p
ON ps.partition_id = p.partition_id
AND p.[object_id] = OBJECT_ID('Partitioned_Table')

パーティション テーブルを変更する
事前に入念な計画を立てても、パーティション テーブルを作成および設定した後で調整が必要になる場合があります。たとえば、パーティション スキームは予定どおりに機能しても、新しいデータが蓄積してきたために新しいパーティションを追加する必要が出てきたり、一度に大量のパーティション データを削除する必要が生じることがあります。パーティション テーブルおよび基になるパーティションの構造は、テーブルを作成してデータが格納された後でも変更できるようになっています。
パーティションの追加: 多くのパーティション計画では、後から新しいパーティションを追加できる機能を採り入れます。追加のタイミングを特定の日付や増分する ID 列の値によって設定することができますが、事前に計画していなかった場合は、後日になってから新しいパーティションをパーティション テーブルに追加することが可能です。図 2 で作成したテーブルの場合を考えてみましょう。このテーブルに新しいパーティションを追加して 500 より大きい値を格納するには、次のようにします。
--Determine where values live before new partition
SELECT $PARTITION.Left_Partition (501)  --should return a value of 4

--Create new partition
ALTER PARTITION FUNCTION Left_Partition ()
SPLIT RANGE(500)

--Determine where values live after new partition
SELECT $PARTITION.Left_Partition (501)  --should return a value of 5
パーティションを追加する機能があれば、柔軟性が大幅に向上します。図 3 は、関数の左側にパーティションを追加する方法を示しています。この場合、最初にパーティション スキームを作成したときに作成したファイル グループは使い尽くしているため、新しいパーティションを配置するパーティション スキームを指定する必要があります。すべてのパーティションに PRIMARY ファイル グループを使用する場合でも、パーティション スキームを指定して、新しいパーティションの PRIMARY ファイル グループを再使用する必要があります。
Figure 3 関数の左側にパーティションを追加する (Close Figure 3)
--Determine where values live after new partition
SELECT $PARTITION.Left_Partition (5)   --should return a value of 2
SELECT $PARTITION.Left_Partition (1)   --should return a value of 1
SELECT $PARTITION.Left_Partition (10)  --should return a value of 2

--Add new filegroups to the partitioning scheme
ALTER PARTITION SCHEME Primary_Left_Scheme
NEXT USED [PRIMARY]

--Create new partition
ALTER PARTITION FUNCTION Left_Partition ()
SPLIT RANGE(5)

--Determine where values live after new partition
SELECT $PARTITION.Left_Partition (5)   --should return a value of 2
SELECT $PARTITION.Left_Partition (1)   --should return a value of 1
SELECT $PARTITION.Left_Partition (10)  --should return a value of 3
2 つのパーティションのマージ: SQL Server では、データを保持したまま、テーブルからパーティションを削除できます。この機能を利用して、古いアクティブ データをアーカイブ データにマージしたり、使用するパーティションの数を減らすことができるため、パーティション テーブルの管理が容易になります。また、この機能を使用してパーティションをマージし、ファイル グループ間でデータを移動して、特定のドライブ配列のディスク領域を解放することも可能です。図 4 のコードは、同一ファイル グループ上のパーティション間でデータを移動する方法を示しています。
Figure 4 パーティション間でデータを移動する (Close Figure 4)
--Prepare database
IF OBJECT_ID('multiple_partition') IS NOT NULL
DROP TABLE multiple_partition
GO

IF EXISTS(SELECT [name] FROM sys.partition_schemes
WHERE [name] = 'Primary_Left_Scheme')
DROP PARTITION SCHEME Primary_Left_Scheme
GO

IF EXISTS(SELECT [name] FROM sys.partition_functions
WHERE [name] = 'Left_Partition')
DROP PARTITION FUNCTION Left_Partition
GO

--Create partitioned table
CREATE PARTITION FUNCTION Left_Partition (int) AS RANGE LEFT
FOR VALUES (1,10,100)

--Place all partitions into the PRIMARY filegroup
CREATE PARTITION SCHEME Primary_Left_Scheme
AS PARTITION Left_Partition
--Partition must currently exist in database
      ALL TO ([PRIMARY])

CREATE TABLE multiple_partition
(
col1 INT PRIMARY KEY CLUSTERED
,col2 VARCHAR(15)
) ON Primary_Left_Scheme (col1)

INSERT INTO multiple_partition VALUES (1,'Description')
INSERT INTO multiple_partition VALUES (2,'Description')
INSERT INTO multiple_partition VALUES (3,'Description')
INSERT INTO multiple_partition VALUES (4,'Description')
INSERT INTO multiple_partition VALUES (10,'Description')
INSERT INTO multiple_partition VALUES (11,'Description')
INSERT INTO multiple_partition VALUES (12,'Description')
INSERT INTO multiple_partition VALUES (13,'Description')
INSERT INTO multiple_partition VALUES (14,'Description')
INSERT INTO multiple_partition VALUES (100,'Description')
INSERT INTO multiple_partition VALUES (101,'Description')
INSERT INTO multiple_partition VALUES (102,'Description')
INSERT INTO multiple_partition VALUES (103,'Description')
INSERT INTO multiple_partition VALUES (104,'Description')

--Verify partitions
SELECT OBJECT_NAME(ps.[object_id])
,ps.partition_number
,ps.row_count
FROM sys.dm_db_partition_stats ps
INNER JOIN sys.partitions p
ON ps.partition_id = p.partition_id
AND p.[object_id] = OBJECT_ID('multiple_partition')

--Check where data would be placed
SELECT $PARTITION.Left_Partition (1)
SELECT $PARTITION.Left_Partition (10)
SELECT $PARTITION.Left_Partition (100)
SELECT $PARTITION.Left_Partition (101)

--Merge two partitions
ALTER PARTITION FUNCTION Left_Partition()
MERGE RANGE (10)

--Verify partitions
SELECT OBJECT_NAME(ps.[object_id])
,ps.partition_number
,ps.row_count
FROM sys.dm_db_partition_stats ps
INNER JOIN sys.partitions p
ON ps.partition_id = p.partition_id
AND p.[object_id] = OBJECT_ID('multiple_partition')

--Check where data would be placed
SELECT $PARTITION.Left_Partition (1)
SELECT $PARTITION.Left_Partition (10)
SELECT $PARTITION.Left_Partition (100)
SELECT $PARTITION.Left_Partition (101)
パーティション テーブルへの単一パーティション テーブルの移動: 読み込みルーチンでは、多くの場合、データ テーブルに移動する前に大量のデータをデータベースに読み込んで、変更や集計を行う必要があります。SQL Server 2005 のパーティション機能では、単一のパーティション テーブルを複数のパーティションを持つテーブルに移動できます。これにより、データを単一の読み込みテーブルに読み込んでデータを変更し、テーブル全体を既存のテーブルに移動する際に、個々のデータ行を移動するためのオーバーヘッドが生じません。パーティションのこの層では、基になるパーティション構造の変更は行わず、パーティション テーブルの変更を行います。図 5 は、この機能の実装方法を示しています。
Figure 5 テーブル全体を既存のテーブルに移動する (Close Figure 5)
--Prepare database
IF OBJECT_ID(‘multiple_partition’) IS NOT NULL
DROP TABLE multiple_partition
GO

IF OBJECT_ID(‘single_partition’) IS NOT NULL
DROP TABLE single_partition
GO

IF EXISTS(SELECT [name] FROM sys.partition_schemes
WHERE [name] = ‘Primary_Left_Scheme’)
DROP PARTITION SCHEME Primary_Left_Scheme
GO

IF EXISTS(SELECT [name] FROM sys.partition_functions
WHERE [name] = ‘Left_Partition’)
DROP PARTITION FUNCTION Left_Partition
GO

--Create single partition table
CREATE TABLE single_partition
(
col1 INT PRIMARY KEY CLUSTERED
,col2 VARCHAR(15)
)

--Table must have a CHECK Constraint
ALTER TABLE single_partition
WITH CHECK
ADD CONSTRAINT CK_single_partition
    CHECK (col1 > 100)

INSERT INTO single_partition VALUES (101,’Description’)
INSERT INTO single_partition VALUES (102,’Description’)
INSERT INTO single_partition VALUES (103,’Description’)
INSERT INTO single_partition VALUES (104,’Description’)

--Create partitioned table
CREATE PARTITION FUNCTION Left_Partition (int) AS RANGE LEFT
FOR VALUES (1,10,100)

--Place all partitions into the PRIMARY filegroup
CREATE PARTITION SCHEME Primary_Left_Scheme
AS PARTITION Left_Partition
--Partition must currently exist in database
      ALL TO ([PRIMARY])

CREATE TABLE multiple_partition
(
col1 INT PRIMARY KEY CLUSTERED
,col2 VARCHAR(15)
) ON Primary_Left_Scheme (col1)

INSERT INTO multiple_partition VALUES (1,’Description’)
INSERT INTO multiple_partition VALUES (2,’Description’)
INSERT INTO multiple_partition VALUES (3,’Description’)
INSERT INTO multiple_partition VALUES (4,’Description’)
INSERT INTO multiple_partition VALUES (10,’Description’)
INSERT INTO multiple_partition VALUES (11,’Description’)
INSERT INTO multiple_partition VALUES (12,’Description’)
INSERT INTO multiple_partition VALUES (13,’Description’)
INSERT INTO multiple_partition VALUES (14,’Description’)
INSERT INTO multiple_partition VALUES (100,’Description’)

--Verify partitions
SELECT OBJECT_NAME(ps.[object_id])
,ps.partition_number
,ps.row_count
FROM sys.dm_db_partition_stats ps
INNER JOIN sys.partitions p
ON ps.partition_id = p.partition_id
AND p.[object_id] IN (OBJECT_ID(‘multiple_partition’), OBJECT_
      ID(‘single_partition’))

--Move the single table into the partitioned table
ALTER TABLE single_partition SWITCH TO multiple_partition PARTITION 4

--Verify partitions
SELECT OBJECT_NAME(ps.[object_id])
,ps.partition_number
,ps.row_count
FROM sys.dm_db_partition_stats ps
INNER JOIN sys.partitions p
ON ps.partition_id = p.partition_id
AND p.[object_id] IN (OBJECT_ID(‘multiple_partition’), OBJECT_ID(‘single_partition’))
テーブル間のパーティションの移動: 古いデータを別のアーカイブ テーブルに移動するのは一般的な管理作業です。アーカイブ プロセスでは、通常、一連のステートメントを使用して、リソースの使用状況をトランザクション ログに追加できるようにします。しかし、大量のデータをアーカイブするには、パーティションの所有権を別のテーブルに切り替えた方がトランザクション ログのオーバーヘッドが生じず、作業も単純です。この機能を使って、データベース管理者は、古いデータをアクティブなテーブルからアーカイブ テーブルに移動できます。実際にデータを移動するわけではないので、個々のデータ行を移動する場合よりはるかに短時間で処理されます。図 6 は、この機能の実装方法を示しています。
Figure 6 古いデータをアーカイブ テーブルに移動する (Close Figure 6)
--Prepare database
IF OBJECT_ID('active_data') IS NOT NULL
DROP TABLE active_data
GO

IF OBJECT_ID('archive_data') IS NOT NULL
DROP TABLE archive_data
GO

IF EXISTS(SELECT [name] FROM sys.partition_schemes
WHERE [name] = 'Active_Scheme')
DROP PARTITION SCHEME Active_Scheme
GO

IF EXISTS(SELECT [name] FROM sys.partition_functions
WHERE [name] = 'Active_Partition')
DROP PARTITION FUNCTION Active_Partition
GO

IF EXISTS(SELECT [name] FROM sys.partition_schemes
WHERE [name] = 'Archive_Scheme')
DROP PARTITION SCHEME Archive_Scheme
GO

IF EXISTS(SELECT [name] FROM sys.partition_functions
WHERE [name] = 'Archive_Partition')
DROP PARTITION FUNCTION Archive_Partition
GO

--Create active function
CREATE PARTITION FUNCTION Active_Partition (int) AS RANGE LEFT
FOR VALUES (1,10,100)

--Create archive function
CREATE PARTITION FUNCTION Archive_Partition (int) AS RANGE LEFT
FOR VALUES (100,200,300)

--Place all partitions into the PRIMARY filegroup
CREATE PARTITION SCHEME Active_Scheme
AS PARTITION Active_Partition
--Partition must currently exist in database
      ALL TO ([PRIMARY])

--Place all partitions into the PRIMARY filegroup
CREATE PARTITION SCHEME Archive_Scheme
AS PARTITION Archive_Partition
--Partition must currently exist in database
      ALL TO ([PRIMARY])

CREATE TABLE active_data
(
col1 INT PRIMARY KEY CLUSTERED
,col2 VARCHAR(15)
) ON Active_Scheme (col1)

CREATE TABLE archive_data
(
col1 INT PRIMARY KEY CLUSTERED
,col2 VARCHAR(15)
) ON Archive_Scheme (col1)

INSERT INTO active_data VALUES (1,'Description')
INSERT INTO active_data VALUES (2,'Description')
INSERT INTO active_data VALUES (3,'Description')
INSERT INTO active_data VALUES (4,'Description')
INSERT INTO active_data VALUES (10,'Description')
INSERT INTO active_data VALUES (11,'Description')
INSERT INTO active_data VALUES (12,'Description')
INSERT INTO active_data VALUES (13,'Description')
INSERT INTO active_data VALUES (14,'Description')
INSERT INTO active_data VALUES (100,'Description')

INSERT INTO archive_data VALUES (200,'Description')
INSERT INTO archive_data VALUES (300,'Description')
INSERT INTO archive_data VALUES (400,'Description')

--Verify partitions
SELECT OBJECT_NAME(ps.[object_id])
,ps.partition_number
,ps.row_count
FROM sys.dm_db_partition_stats ps
INNER JOIN sys.partitions p
ON ps.partition_id = p.partition_id
AND p.[object_id] IN (OBJECT_ID('active_data'),OBJECT_ID('archive_
      data'))

--Switch ownership of partition to another table
ALTER TABLE active_data SWITCH PARTITION 3 TO archive_data PARTITION 1

--Verify partitions
SELECT OBJECT_NAME(ps.[object_id])
,ps.partition_number
,ps.row_count
FROM sys.dm_db_partition_stats ps
INNER JOIN sys.partitions p
ON ps.partition_id = p.partition_id
AND p.[object_id] IN (OBJECT_ID('active_data'),OBJECT_ID('archive_
      data'))
単一のパーティションを使用して新しいテーブルを作成する: 単一のパーティションを既存のパーティション テーブルからパーティションが存在しない空のテーブルに移動することができます。この機能により、データベース管理者は、単一パーティション上でインデックスをメンテナンスしたり、削除プロセスをログに記録することなく、大量のデータを簡単に削除することができます。図 7 は、空のテーブルにパーティションを移動し、その新しいテーブルを使用してデータを削除する方法を示しています。
Figure 7 データを移動および削除する (Close Figure 7)
--Prepare database
IF OBJECT_ID('active_data') IS NOT NULL
DROP TABLE active_data
GO

IF OBJECT_ID('archive_data') IS NOT NULL
DROP TABLE archive_data
GO

IF EXISTS(SELECT [name] FROM sys.partition_schemes
WHERE [name] = 'Active_Scheme')
DROP PARTITION SCHEME Active_Scheme
GO

IF EXISTS(SELECT [name] FROM sys.partition_functions
WHERE [name] = 'Active_Partition')
DROP PARTITION FUNCTION Active_Partition
GO

--Create active function
CREATE PARTITION FUNCTION Active_Partition (int) AS RANGE LEFT
FOR VALUES (1,10,100)

--Place all partitions into the PRIMARY filegroup
CREATE PARTITION SCHEME Active_Scheme
AS PARTITION Active_Partition
--Partition must currently exist in database
      ALL TO ([PRIMARY])

CREATE TABLE active_data
(
col1 INT PRIMARY KEY CLUSTERED
,col2 VARCHAR(15)
) ON Active_Scheme (col1)

CREATE TABLE archive_data
(
col1 INT PRIMARY KEY CLUSTERED
,col2 VARCHAR(15)
)

INSERT INTO active_data VALUES (1,'Description')
INSERT INTO active_data VALUES (2,'Description')
INSERT INTO active_data VALUES (3,'Description')
INSERT INTO active_data VALUES (4,'Description')
INSERT INTO active_data VALUES (10,'Description')
INSERT INTO active_data VALUES (11,'Description')
INSERT INTO active_data VALUES (12,'Description')
INSERT INTO active_data VALUES (13,'Description')
INSERT INTO active_data VALUES (14,'Description')
INSERT INTO active_data VALUES (100,'Description')

--Verify partitions
SELECT OBJECT_NAME(ps.[object_id])
,ps.partition_number
,ps.row_count
FROM sys.dm_db_partition_stats ps
INNER JOIN sys.partitions p
ON ps.partition_id = p.partition_id
AND p.[object_id] IN (OBJECT_ID('active_data'),OBJECT_ID('archive_
      data'))

--Switch ownership of partition to another table
ALTER TABLE active_data SWITCH PARTITION 3 TO archive_data

--Verify partitions
SELECT OBJECT_NAME(ps.[object_id])
,ps.partition_number
,ps.row_count
FROM sys.dm_db_partition_stats ps
INNER JOIN sys.partitions p
ON ps.partition_id = p.partition_id
AND p.[object_id] IN (OBJECT_ID('active_data'),OBJECT_ID('archive_
      data'))

--Drop all archive data without logging
DROP TABLE archive_data
GO

--Verify partitions
SELECT OBJECT_NAME(ps.[object_id])
,ps.partition_number
,ps.row_count
FROM sys.dm_db_partition_stats ps
INNER JOIN sys.partitions p
ON ps.partition_id = p.partition_id
AND p.[object_id] IN (OBJECT_ID('active_data'),OBJECT_ID('archive_
      data'))

パーティション インデックス
テーブルのデータをパーティションに分割する機能が使用できれば、通常はパーティション インデックスの作成機能も使用できます。この機能を使用して、データベース管理者は、テーブル全体のデータではなく、分割されたデータに基づいてインデックス構造を設計することができます。パーティション インデックスを作成すると、パーティション インデックス上に個別の B ツリーが作成されます。インデックスを分割すると、作成するインデックスが小さくなり、データを変更、追加、削除する際のストレージ エンジンによるメンテナンスが容易になるという効果があります。小さいインデックスをデータベース管理者が個別に管理することができるため、膨大なデータセットのメンテナンスが容易になります。
パーティション インデックスの作成: パーティション インデックスを作成する際、固定インデックスまたは非固定インデックスを作成できます。固定インデックスの場合、パーティション データとの直接的な関係を使用してインデックスを作成します。非固定インデックスの場合は別のパーティション スキーマを選択します。
推奨されるのは固定インデックスです。パーティション テーブルを作成後、インデックスを作成するときに別のパーティション スキームを指定しなければ、自動的に固定インデックスになります。固定インデックスを使用すると、テーブルにパーティションを追加する際の柔軟性が向上し、パーティションの所有権を他のテーブルに切り替えることができます。これらの機能があれば、たいていの場合、パーティション テーブルを作成し、インデックスにテーブルのパーティション スキーマを使用するだけでパーティションの目標は果たされるでしょう。
インデックスのデータがテーブルのデータに固定されていないテーブルに対して、インデックスを作成することができます。データがパーティション テーブルに存在する場合、データを多様な方法で結合できます (クエリ オプティマイザを使用して、パーティション データを他のパーティション データと効率的に結合することが可能です)。非パーティション テーブルでも同様の機能を使用可能であり、パーティション インデックスを (単一のパーティション テーブルに対して) 作成すれば、インデックスのメンテナンスが容易になります。
図 8 のコードは、パーティションに分割された非クラスタ化インデックスをパーティション テーブルに作成します。非クラスタ化インデックスは、テーブルに固定され、テーブルのパーティション列を非クラスタ化インデックス キーとして使用します。
Figure 8 パーティション テーブルに対する、パーティションに分割された非クラスタ化インデックス (Close Figure 8)
--Prepare database
IF OBJECT_ID('multiple_partition') IS NOT NULL
DROP TABLE multiple_partition
GO

IF EXISTS(SELECT [name] FROM sys.partition_schemes
WHERE [name] = 'Primary_Left_Scheme')
DROP PARTITION SCHEME Primary_Left_Scheme
GO

IF EXISTS(SELECT [name] FROM sys.partition_functions
WHERE [name] = 'Left_Partition')
DROP PARTITION FUNCTION Left_Partition
GO

--Create partitioned table
CREATE PARTITION FUNCTION Left_Partition (int) AS RANGE LEFT
FOR VALUES (1,10,100)

--Place all partitions into the PRIMARY filegroup
CREATE PARTITION SCHEME Primary_Left_Scheme
AS PARTITION Left_Partition
--Partition must currently exist in database
    ALL TO ([PRIMARY])

CREATE TABLE multiple_partition
(
col1 INT
,col2 VARCHAR(15)
) ON Primary_Left_Scheme (col1)

--Create partitioned non-clustered index
CREATE NONCLUSTERED INDEX cl_multiple_partition ON multiple_
      partition(col1)

INSERT INTO multiple_partition VALUES (1,'Description')
INSERT INTO multiple_partition VALUES (2,'Description')
INSERT INTO multiple_partition VALUES (3,'Description')
INSERT INTO multiple_partition VALUES (4,'Description')
INSERT INTO multiple_partition VALUES (10,'Description')
INSERT INTO multiple_partition VALUES (11,'Description')
INSERT INTO multiple_partition VALUES (12,'Description')
INSERT INTO multiple_partition VALUES (13,'Description')
INSERT INTO multiple_partition VALUES (14,'Description')
INSERT INTO multiple_partition VALUES (100,'Description')
INSERT INTO multiple_partition VALUES (101,'Description')
INSERT INTO multiple_partition VALUES (102,'Description')
INSERT INTO multiple_partition VALUES (103,'Description')
INSERT INTO multiple_partition VALUES (104,'Description')

--Verify partitions
SELECT OBJECT_NAME(ps.[object_id])
,ps.partition_number
,ps.row_count
FROM sys.dm_db_partition_stats ps
INNER JOIN sys.partitions p
ON ps.partition_id = p.partition_id
AND p.[object_id] = OBJECT_ID('multiple_partition')

--Verify index partitions
SELECT partition_id, index_id FROM sys.partitions pt
WHERE pt.[object_id] = OBJECT_ID('multiple_partition')
図 9 のコードは、固定されていない非クラスタ化インデックスをパーティション テーブルに作成します。この非クラスタ化インデックスは、別の列をインデックス キーに使用し、そのキーを他のパーティション テーブルに対する照合結合に使用できます。
Figure 9 パーティション テーブルに対する、固定されていない非クラスタ化インデックス (Close Figure 9)
--Prepare database
IF OBJECT_ID('multiple_partition') IS NOT NULL
DROP TABLE multiple_partition
GO

IF EXISTS(SELECT [name] FROM sys.partition_schemes
WHERE [name] = 'Primary_Left_Scheme')
DROP PARTITION SCHEME Primary_Left_Scheme
GO

IF EXISTS(SELECT [name] FROM sys.partition_schemes
WHERE [name] = 'Index_primary_Left_Scheme')
DROP PARTITION SCHEME Index_primary_Left_Scheme
GO

IF EXISTS(SELECT [name] FROM sys.partition_functions
WHERE [name] = 'Left_Partition')
DROP PARTITION FUNCTION Left_Partition
GO

IF EXISTS(SELECT [name] FROM sys.partition_functions
WHERE [name] = 'Index_Left_Partition')
DROP PARTITION FUNCTION Index_Left_Partition
GO

--Create partitioned index function
CREATE PARTITION FUNCTION Index_Left_Partition (int) AS RANGE LEFT
FOR VALUES (10,50,100)

--Create partitioned table
CREATE PARTITION FUNCTION Left_Partition (int) AS RANGE LEFT
FOR VALUES (1,10,100)

--Place all index partitions into the PRIMARY filegroup
CREATE PARTITION SCHEME Index_primary_Left_Scheme
AS PARTITION Index_Left_Partition
--Partition must currently exist in database
      ALL TO ([PRIMARY])

--Place all partitions into the PRIMARY filegroup
CREATE PARTITION SCHEME Primary_Left_Scheme
AS PARTITION Left_Partition
--Partition must currently exist in database
      ALL TO ([PRIMARY])

CREATE TABLE multiple_partition
(
col1 INT
,col2 INT
) ON Primary_Left_Scheme (col1)

--Create non-aligned partitioned nonclustered index
CREATE NONCLUSTERED INDEX cl_multiple_partition ON multiple_
     partition(col2)
ON Index_primary_Left_Scheme (col2)

INSERT INTO multiple_partition VALUES (1,10)
INSERT INTO multiple_partition VALUES (2,10)
INSERT INTO multiple_partition VALUES (3,10)
INSERT INTO multiple_partition VALUES (4,10)
INSERT INTO multiple_partition VALUES (10,50)
INSERT INTO multiple_partition VALUES (11,50)
INSERT INTO multiple_partition VALUES (12,50)
INSERT INTO multiple_partition VALUES (13,50)
INSERT INTO multiple_partition VALUES (14,50)
INSERT INTO multiple_partition VALUES (100,100)
INSERT INTO multiple_partition VALUES (101,100)
INSERT INTO multiple_partition VALUES (102,100)
INSERT INTO multiple_partition VALUES (103,100)
INSERT INTO multiple_partition VALUES (104,100)

--Verify row count on partitioned data
SELECT OBJECT_NAME(ps.[object_id])
,ps.partition_number
,ps.row_count
FROM sys.dm_db_partition_stats ps
INNER JOIN sys.partitions p
ON ps.partition_id = p.partition_id
AND p.[object_id] = OBJECT_ID('multiple_partition')
AND p.index_id = 0

--Verify row count on partitioned index
--Row counts will not match those found in the data partitions
SELECT OBJECT_NAME(ps.[object_id])
,ps.partition_number
,ps.row_count
FROM sys.dm_db_partition_stats ps
INNER JOIN sys.partitions p
ON ps.partition_id = p.partition_id
AND p.[object_id] = OBJECT_ID('multiple_partition')
AND p.index_id <> 0
パーティション インデックスのメンテナンス: 以前には、数百万行あるいは数十億行のデータが存在する大規模なテーブルのインデックスをメンテナンスする作業は手間がかかりすぎて、データベース管理者はそれに忙殺されていました。インデックスの再構築時にデータがロックされることが原因で、メンテナンスを行わないまま放置されることも珍しくありませんでした。SQL Server 2005 では、データベース管理者は、ベース テーブルを長時間ロックすることなく、インデックスをオンラインでメンテナンスできます。とはいえ、この方法でも、ユーザーがデータにアクセスしている最中にインデックスをメンテナンスするため、リソースの使用率が原因でシステムのパフォーマンスが低下する可能性があります。そこで、よりよい方策として、インデックスを小さいセグメントに分割し、その細分化されたパーティションに対するインデックスをメンテナンスするという方法があります。たとえば、1 つのインデックス パーティションをメンテナンスするには、図 8 で示したコードの最後に次のコード スニペットを追加するだけでよいのです。
ALTER INDEX cl_multiple_partition
ON multiple_partition
REBUILD Partition = 2
単一のインデックス パーティションに対するインデックスのメンテナンスはオフラインで行う必要があり、インデックスのメンテナンス中にはテーブル ロックが発生する可能性があります。これを回避するには、単一のパーティションを別のパーティションに移動し、インデックスのメンテナンスを行ってからパーティションをメイン テーブルに戻すという方法があります。この方法では、パーティションをテーブルに戻してクラスタ化インデックスを更新する際にパフォーマンスの問題が生じますが、テーブル全体がロックされ、システム リソースが減ることに比べたら、大した問題ではありません。

まとめ
これまで見てきたように、SQL Server 2005 のテーブル パーティションを利用すれば、アプリケーション コードや SQL Server プロセスを変更することなく、大規模なテーブルのデータの格納およびメンテナンスの柔軟性を向上させることができます。これらの機能を備えた SQL Server は、エンタープライズ レベルの基幹データベース向けの強力なプラットフォームになります。

Noah GomezVerizon のシニア SQL Server 開発 DBA を務め、VLDB および大規模アプリケーションを専門にしています。Professional Association for SQL Server (PASS) の会員でもあり、Verizon DBA チームの一員として、2003 年に Winter Corp. Top Ten Grand Prize を受賞した数テラバイト規模の VLDB にも携わりました。


 SQL Server: SQL Server のクラスタリングのヒント
SQL Server Tom Moreau (PhD)

SQL Server のクラスタリングのヒント
概要:
  • クラスタで SQL Server を実行する
  • ハードウェアとソフトウェアの要件
  • 単一ノードのクラスタリング
  • 費用対効果の優れたオプション

サーバー クラスタを使用すると、複数の物理的サーバー (ノードとも呼ばれます) を接続して、サーバーが互いにフェールオーバー パートナーとなるように構成できます。クラスタよって提供される冗長性により、重要な処理のための稼働状態をより長く
することができます。私は SQL Server™ を 13 年使用してきて多くのクラスタを実装しましたが、どの案件にもそれぞれ独自の問題点がありました。この経験によって、皆さんがクラスタリングを簡単にうまく行うための多くのヒントを集めることができました。
サーバー クラスタでは、Windows Server® ファミリの Enterprise Edition の組み込みクラスタリング機能を利用します。ちなみに、クラスタリングについては、Windows Server 2003 は Windows 2000 Advanced Server よりもはるかに優れています。クラスタリングによって得られる利点を最大化するためには、適切なハードウェアが必要であり、それにはある程度の出費が伴います。何台かのサーバーを共有ディスクと一緒にざっとまとめるだけでは不十分です。というのも、個々のハードウェア コンポーネントが、以前はハードウェア互換性リストと呼ばれていた Windows® カタログに記載されているという事実に頼ることはできないためです。全体としてのシステムが Windows カタログに記載されている必要があります。ただし心配は要りません。認定された低コストのクラスタ ソリューションが利用可能です。図 1 に、典型的なクラスタ構成を示します。
Figure 1 A typical cluster
Figure 1 A typical cluster (画像を縮小するには、ここをクリックします)
Figure 1 A typical cluster
Figure 1 A typical cluster (画像を拡大するには、ここをクリックします)
もちろん、クラスタリングはハードウェアだけではありません。正しいエディションの SQL Server 2005 を選択する必要があります。Enterprise Edition では、クラスタリングの他にも、CPU をさらに活用する機能、分散および更新可能なパーティション ビュー、組み込みのログ配布、インデックス付きビューの自動使用などの便利な機能も有効にできます。Enterprise Edition のライセンスを既に所有しているのであれば、従来型クラスタの構成に必要な 2 ～ 8 台のサーバーが手元にあってもなくても、クラスタリングを検討すべきです (単一ノード クラスタについては、この後すぐにご紹介します)。SQL Server 2005 Standard Edition をお持ちの場合は、2 ノード クラスタを設置できます。
Windows Server 2003 の Enterprise Edition と Datacenter Edition にはクラスタリングが組み込まれているため、クラスタ アドミニストレータを実行してクラスタをセットアップするだけです。すべてのノードはまとめて追加することも、1 台ずつ追加することもできます。同様に、SQL Server のインストール時には、独立した非クラスタ サーバーにインストールするか、クラスタの仮想インスタンスにインストールするかを選択できます。仮想インスタンスへのインストールを選択する場合、インストールするノードは全ノードか、複数か、1 つだけかを選んでインストールできます。
最後に、クラスタリングの真の目的である高可用性を実現するためには、適切な複数の管理者を決めて、何か不具合が発生したときに従う手順を作成し、その手順に習熟しておく必要があります。クラスタリングはハードウェア障害に対する優れた保険ではありますが、睡眠不足の DBA が真夜中に重要なテーブルを削除するといったユーザー エラーを防いではくれません。

単一ノード クラスタ
現時点で必要なのが単一サーバーであっても、単一ノード クラスタの作成を検討してください。後でクラスタにアップグレードするという選択肢が増え、再構築をしなくて済みます。ただし、選択したハードウェアが Windows カタログのクラスタ部分に記載されていることを必ず確認しておいてください。
高可用性だけが、後でノードを追加するという選択肢が必要となる理由ではありません。お使いのサーバーに必要な容量がないとわかったときに何が起こるかを考えてみましょう。この場合、移行を行うことになり、時間と労力を要します。単一ノード クラスタを用意していれば、移行は簡単であり、ダウンタイムもかなり少なくて済みます。新しいノードをクラスタに追加し、SQL Server プログラムとサービス パックを新しいノードに追加し、新しいノードにフェールオーバーします。そして、サービス パック後の更新プログラムを追加して、最後に古いノードを削除します。ダウンタイムは、フェールオーバーにかかる時間と更新プログラムがあればその更新にかかる時間のみです。

ノードを追加する
クラスタ内のすべてのノードは同じでなければならないため、追加のノードの入手は後まわしにせずに、なるべく早く行うのがよいでしょう。時間がたちすぎると、そのノードの生産が終了する可能性があります。あるプロジェクトで、SQL Server 2000 クラスタのあるノードを再構築する必要がありました。OS とネットワークの管理者に基本的なマシンの構築を処理してもらい、それから私が、そのマシンをクラスタに追加して SQL Server ノードとして準備することにしました。新しいノードへのフェールオーバーを行うまでは、すべてが順調でした。フェールオーバーはすぐに失敗し、私は非常に落胆しました。長い話を短くまとめると、クラスタ サービスと SQL Server サービスのアカウントを両方のノードへ追加するなど、新しいクラスタの構築に関する詳細な文書を用意していたにもかかわらず、作業はその文書に従って行われていませんでした。管理者はこれらのサービス アカウントを再構築されたノードに追加しておらず、再構築前に設定されていた特権がすべてなくなってしまいました。
この問題の原因究明には長い時間がかかりました。ある日、ローカル グループのメンバシップを確認してみようと思い付きました。2 つのアカウントを追加すると、フェールオーバーは順調に進みました。このとき、私は次のように思いました。ノードの再構築は頻繁に行うことではなく、行う場合は非常時です。文書を用意しておいたにもかかわらず、使用されませんでした。それら 2 つのアカウントを追加し、必要なその他のカスタマイズを行う短いスクリプトを書くだけで、セキュリティ関連の作業を自動化しておくこともできたはずです。ただし、SQL Server 2005 では状況が改善されています。インストーラにより、SQL Server サービス アカウント用のドメイン レベルのグループを設定することが求められます。
もちろん、このことから私はさらに考えました。CLUSTER.EXE を呼び出してノードを Microsoft® Cluster Server (MSCS) クラスタに追加するスクリプトを作成すると、あとはスクリプトにノードの名前を渡すだけで、残りの作業を処理してくれます。非常時には、自動化はまさにあなたの味方です。

N+1 クラスタ
ノードをクラスタに追加する理由が、あるノードの置き換えではない場合があります。クラスタには SQL Server インスタンスをさらに追加できますが、その各インスタンスは独立したディスク リソースを必要とします。複数のインスタンスを 1 つのノードで実行できますが、CPU と RAM を共有することになり、パフォーマンスが低下するおそれがあります。理想的には、1 つのノードでは 1 つのインスタンスのみを実行すべきです。フェールオーバー時に確実にそうさせるにはどうすればよいでしょうか。これは簡単です。ある 1 つのノードでは何もサービスを実行せず、それ以外の各ノードでは 1 つの SQL Server インスタンスを実行するというのが答えです。実際、これが N+1 クラスタの定義なのです。つまり、N 個のインスタンスを N+1 個のノードで実行するということです。余分なノードはバックアップ用です。

SQL Server のアップグレード
SQL Server のクラスタ化されたインスタンスのアップグレードは、気弱な人には向かない仕事です。なんといっても、クラスタ化は稼働状態を維持するために行われているからです。ただし SQL Server 2005 には多くの機能拡張があります。これらの機能拡張を利用することで、アップグレードを行う際に短いダウンタイムで処理できます。
どのような選択肢があるでしょうか。最初に最も多く費用のかかるソリューションについて見てみましょう。このソリューションでは、クラスタ全体を新たに作成します。そのためには新しいサーバーと、おそらく新しいストレージ エリア ネットワーク (SAN) が必要です。既存のネットワーク スイッチは引き続き使うことができますが、再利用できるのはそれくらいでしょう。このアプローチが安価ではないのは明らかですが、メリットもあります。ディスク容量の増加やディスク スピードの改善の速度はさらに高まっており、古いハードウェアより新しいハードウェアの方が、概してパフォーマンスはかなり優れています。したがって、新しいハードウェアを使用することだけでもパフォーマンスが向上します。問題に先回りして対処するには、機器のリースを利用する方法もあるでしょう。
ハードウェアを用意したら、新しい仮想 SQL Server をこのセットアップに作成し、実稼働データベースをコピーして、カットオーバーの日までにバグを修正する時間を十分に残しつつ新しいシステムを試すことができます。また、既存のサーバーのログインを作成するスクリプトを必ず作成しておきます (support.microsoft.com/kb/246133 を確認してください。致命的なエラーに備えて、ログイン ビルド スクリプトを更新しておくのも良いアイデアです)。
データベースが非常に小さくユーザーが接続していない時間が一定期間ある場合を除き、ダウンタイムを最小限にするにはログ配布を使用する必要があるでしょう。カットオーバーの直前までログ配布を行うことができます。そして、ユーザーを切断して最終ログを切り取って配布し、アプリケーションが新しいインスタンスを指し示すようにします (ログ配布に代わる興味深い機能については、後述のデータベース ミラーリングに関するセクションを参照してください)。DNS エイリアスを使用する場合は、アプリケーションが新しいインスタンスを指し示す必要すらないでしょう。代わりに DNS エイリアスを更新するだけです。この方法では、移行を途中まで行ってから元に戻す必要が生じたときに、元のシステムがそのまま残っているのが利点であるといえます。
より費用のかからない方法を選ぶことができますが、その場合は事前の計画がさらに必要となります。クラスタは 1 つ以上の SQL Server インスタンスをサポートできますがが、各インスタンスには専用のディスク リソースが必要です。SAN を切り分けて使用する場合、将来のアップグレードに備えて LUN を 1 つ取っておきます。アップグレードを行うには、SQL Server プログラムをこのディスク リソースにインストールします。システムをテストして準備が整ったら現在の SQL Server をシャットダウンし、ディスク リソースを古い SQL Server グループから移動して、依存関係を更新します。その後で新しい SQL Server インスタンスをオンラインにします。古いインスタンスからデータベースをアタッチすると、SQL Server が起動します (前もってすべてのバックアップを取ってありますね?)。
これがより費用のかからない方法ですが、リスクもあります。何らかの問題が発生した場合は、新しいインスタンスからデータベースをデタッチできず、元に戻すことができません。仕方なくバックアップから復元することになり、深刻なダウンタイムが発生するおそれがあります。
代替手段は、十分な空き容量があることを前提として、2 つの SQL Server インスタンスを SAN に配置することです。運用環境のバックアップ (およびログ配布) を新しいインスタンスに復元し、上述の手順とほぼ同様に進めます。ただし、今度は代替システムがあります。移行が完了したら、古いインスタンスから SAN リソースを解放できます。この場合の追加費用は、追加のディスク費用のみです。

負荷分散
よくある誤解を正すことから始めましょう。MSCS クラスタリングを使用するは、高可用性のためであって、負荷分散のためではありません。また SQL Server には、自動負荷分散機能は組み込まれていません。負荷分散は、お使いのアプリケーションの物理的設計によって行われる必要があります。これはどういうことでしょうか。
テーブルが大きくなるにつれて、特にテーブルのスキャンが伴うと、パフォーマンスの低下が想定されます。何百万行、数十億行ともなると、パーティション ビューを使用するのが従来型のソリューションです。パーティション ビューは、UNION ALL で結合される同一のスキーマを持つテーブルから構成されます。また、CHECK 制約が適用され、メンバ テーブルを区別することで、パーティション ビュー間でデータが重複しないようにします。CHECK 制約で使用される列がプライマリ キーの一部でもある場合、ビューは更新可能です。
メンバ テーブルが独自のファイルグループにある場合、それらのファイルグループのファイルが独立した物理ドライブにあるときは、より良いディスク パフォーマンスが得られる可能性があります。テーブルは別個のデータベースに置くことができます。ただし SQL Server 2005 では、すべてのデータが同じデータベースにある限りテーブルのパーティション分割を使用でき、実装はさらに簡単です。
ですが、テーブルのパーティション分割または (ローカルの) パーティション ビューで最善の設定を行ってもまだスピードが遅いとします。SQL Server 2000 または SQL Server 2005 をお持ちであれば、分散パーティション ビューを使用できます。主な違いは、メンバ テーブルを SQL Server の別のインスタンスに配置でき、それらのインスタンスを N+1 クラスタにインストールできることです。これが良いアイデアなのはなぜでしょうか。パーティション ビューでは、どれか 1 つのメンバ テーブルがオフラインになると、ビュー全体がオフラインになります。このようなメンバをクラスタ化すると、パフォーマンスのサポートに必要な信頼性が得られ、負荷分散が行われます。

クラスタが本当に必要な場合とは
おそらく皆さんの周りには、あまっているけれどもクラスタの Windows カタログには記載されていないものがあると思います。それらのサーバーが利用できるのに、クラスタをサポートするためだけに新しいサーバーを購入するのはもったいないことです。
データベース ミラーリングは、クラスタの魅力的な代替手段となる場合があります。ミラーリングには 3 つの要素が必要であり、プリンシパルと呼ばれるミラー化するデータベースを格納するインスタンス、ミラーと呼ばれるバックアップ サーバー、そして自動フェールオーバーを行う場合はミラーリング監視サーバーと呼ばれる 3 番目のサーバーが必要になります。簡単に言うと、プリンシパル上のデータベースのトランザクションが、ミラーでは再度実行されます。プリンシパルがダウンした場合、ミラーリング監視サーバーがあれば、データベースはミラーに自動的にフェールオーバー可能です。ミラーリングは、お使いのアプリケーション データベースごとにセットアップする必要があり、システム データベースのミラーリングはできません。
ミラーは、クラスタとは違い、SQL Server の独立したインスタンスであり、遠く離れた場所に配置できます。ミラーのキャッシュは、プリンシパルから複製されたトランザクションの結果発生する更新処理によって設定されます。もちろんミラーでは、プリンシパルからのミラー トランザクションの受信以外に行われる動作はないと想定されます。ミラーでは SQL Server が既に実行されているため、フェールオーバーは通常、クラスタよりも高速に行われます。ミラーでは少なくとも部分的にはキャッシュが行われているため、初期パフォーマンスはクラスタのシナリオで想定されるパフォーマンスほど悪くはありません。また、ミラー データベースのフェールオーバー時は、プリンシパルとミラーの役割が入れ替わります。
データベース ミラーリングの不利な点は、全ディスク容量がクラスタの 2 倍必要なことです。また、データ消失が発生しない同期モードを使用する場合、CPU パワーもさらに必要となります。何度も言いますが、高可用性は安価ではありません。

組み合わせたアプローチ
ミラーは、プリンシパルから遠く離れたリモートに配置できるため、障害回復計画では良い選択肢となります。クラスタを防御の第一線とすることは可能ですが、クラスタリングとミラーリングの両方を使用するとどうなるでしょうか。クラスタのフェールオーバーでは、ミラーリング構成の一部としてミラーリング監視サーバーがある場合、クラスタ化 SQL Server がオンラインに戻る間、ミラーがプリンシパルとなります。ただし、新しいプリンシパルから新しい (クラスタ化) ミラーへのフェールオーバーは自動的には行われないことに注意してください。そのため、クラスタと組み合わせて使用する場合は、ミラー データベースへの自動フェールオーバーは有効にしない方がよいでしょう。
障害回復だけが、ミラーリングを使用する理由ではありません。ミラーリングは、サービス パックや修正プログラムをプリンシパルに適用する必要がある場合にも便利です。この場合、ミラーへのフェールオーバーを手動で行うことができます。サービス パックまたは修正プログラムの適用中、古いプリンシパル サーバーは一時的にオフラインとなり、新しいプリンシパルで発生するトランザクションがコミットされるとそれがキューに送られ、新しいミラー (古いプリンシパル) に返送されるのを待ちます。サービス パックまたは修正プログラムのインストールが完了したら、同期化が行われ、2 つのサーバーは最終的に完全に同期します。次に、プリンシパルとミラーの役割を切り替えます。ダウンタイムは、フェールオーバーとフェールバックの数秒でした。この方法を使用してお使いの SQL Server を別のサーバーに移行することができます。その場合は、フェールバックを行いません。

仮想サーバーによる柔軟性
仮想化を使用すると、1 つ以上のオペレーティング システムを、1 台の物理サーバー上で同時に実行できます。仮想化ソフトウェアによってソフトウェアをクラスタ化できるため、クラスタの概念に新たな機能の層が追加されます。この場合、ホストを実行しているサーバーでエラーが発生すると、そのサーバーとそのゲスト OS がバックアップ ノードにフェールオーバーされます。これが、ゲスト サーバーの移行を行う非常に簡単な方法となります。その上、ゲスト OS はクラスタ対応である必要がありません。したがって、クラスタで Microsoft Virtual Server 2005 を実行し、ゲストである Windows Server 2003 の内部で SQL Server Workgroup Edition を実行することもできます。間接的であるにせよ、本質的には Workgroup Edition をクラスタ化していることになります (図 2 を参照)。
Figure 2 Using a virtual server
Figure 2 Using a virtual server (画像を縮小するには、ここをクリックします)
Figure 2 Using a virtual server
Figure 2 Using a virtual server (画像を拡大するには、ここをクリックします)

管理
SQL Server の実装を担当している場合、サーバーが常に利用可能であるようにする必要がありますが、サーバー クラスタリングはこの実現のために役立ちます。この記事では、クラスタリングの利用を開始するための得がたいヒントを示し、補足記事の「クラスタリングに関する資料」では役に立つ情報源を紹介しています。
クラスタリングに関する資料
この記事で使用されている方法や SQL Server クラスタのセットアップに必要なさまざまな製品に関する詳細については、次のリソースを参照してください。
  • SQL Server 2005 Failover Clustering
  • SQL Server 2000 Failover Clustering
  • クラスタ サービス
  • Microsoft Cluster Server Administrator’s Guide
  • Microsoft Virtual Server 2005 R2

Tom Moreau (PhD)は、BSc、PhD、MCSE、MCDBA を持つ SQL Server データベースの管理、設計、および実装を専門に扱う独立コンサルタントであり、トロント地区に拠点を置いています。1993 年から SQL Server を使用しており、2001 年に MVP となりました。記事の執筆や SQL Server に関する記事を 100 件以上執筆しているのに加え、共同執筆した書籍もあります。SQL Server MVP である Geoff Hiten による有益な情報提供に感謝します。


 Windows の管理: Windows Vista カーネルの内部 : 第 2 部
Windows の管理 Mark Russinovich

Windows Vista カーネルの内部 : 第 2 部
概要:
  • メモリ管理
  • 起動とシャットダウン
  • 電源管理

先月、この 3 部シリーズの初回の記事では、プロセスと I/O の領域における Windows Vista カーネルの機能拡張を紹介しました。
今回は、Windows Vista のメモリ管理において進歩した点の他に、システムの起動、シャットダウン、および電源管理の主な改善点について説明します (第 1 部)。
Windows® のどのリリースでもスケーラビリティとパフォーマンスが向上していますが、もちろんこれは Windows Vista™ にも当てはまります。Windows Vista のメモリ マネージャでは、ロックフリー同期テクノロジの広範囲に及ぶ使用、細かい単位でのロック、強化されたデータ構造のパッキング、大容量のページング I/O、最新の GPU メモリ アーキテクチャのサポート、ハードウェア変換ルック アサイド バッファの効率的な使用などの数多くの機能が強化されています。さらに、Windows Vista のメモリ管理では、さまざまな負荷の要求に応じて動的にアドレス スペースを割り当てることができます。
新しいテクノロジを採用した 4 つのパフォーマンス向上機能 SuperFetch、ReadyBoost、ReadyBoot、ReadyDrive が、Windows Vista オペレーティング システムで初めて登場しました。これらの機能については後述します。

動的なカーネル アドレス スペース
Windows と Windows 上で実行されるアプリケーションは、32 ビット プロセッサのアドレス スペース制限に制約されてきました。Windows カーネルは、既定で 2 GB、つまり 32 ビット仮想アドレス スペースの半分に制限されており、残りの半分は、現在 CPU でスレッドが実行しているプロセス用に予約されています。その半分のスペースで、カーネルは、カーネル自体、デバイス ドライバ、ファイル システム キャッシュ、カーネル スタック、セッション単位のコード データ構造、およびデバイス ドライバによって割り当てられた非ページ バッファ (ロック済み物理メモリ) とページ バッファをマップする必要があります。Windows Vista までは、こうしたさまざまな目的に割り当てるアドレス スペースの量をメモリ マネージャが起動時に決定していましたが、柔軟性が低いために、他の領域に使用可能なスペースが大量にあっても 1 つの領域だけがいっぱいになる場合がありました。領域を使い切ると、アプリケーションに障害が発生し、デバイス ドライバの I/O 操作が完了しなくなるおそれがあります。
32 ビットの Windows Vista では、メモリ マネージャが、カーネルのアドレス スペースを動的に管理し、負荷に応じてさまざまな用途にスペースの割り当てや割り当ての解除を行います。こうして、ページ バッファの保存に使用される仮想メモリ容量は、デバイス ドライバからさらに要求されると大きくなり、ドライバがメモリを解放すると小さくなります。したがって、Windows Vista では幅広い負荷に対応できますが、32 ビット バージョンの次期 Windows Server® (コードネーム "Longhorn") でも同様に、より多くのターミナル サーバー ユーザーを同時に処理することができます。
もちろん、64 ビット Windows Vista システムでは、アドレス スペースの制限は今や現実的な制限でなくなっているので、システムが最大限に構成されているときでも特別な処理は必要ありません。

メモリの優先順位
Windows Vista には、前回の記事で説明した I/O 優先順位が追加されているだけでなく、メモリの優先順位も実装されています。Windows でメモリの優先順位がどのように使用されるかを理解するには、メモリ マネージャがスタンバイ リストと呼ばれるメモリ キャッシュをどのように実装しているかを把握する必要があります。Windows Vista より前の Windows のすべてのバージョンでは、プロセスが所有する物理ページ (一般にサイズが 4 KB) はシステムによって再利用され、メモリ マネージャは、そのページをスタンバイ リストの末尾に配置していました。プロセスが再びそのページへのアクセスを要求した場合、メモリ マネージャは、スタンバイ リストからページを取り出して、それをプロセスにもう一度割り当てていました。また、プロセスが物理メモリの新しいページを要求したときに使用可能な空きメモリがなかった場合、メモリ マネージャは、スタンバイ リストの先頭のページをプロセスに使用させていました。この方式では、スタンバイ状態のすべてのページは基本的に同等に扱われ、スタンバイ リストに配置してページを並べ替えるのに時間がかかっていました。
Windows Vista では、メモリの全ページが 0 ～ 7 の優先順位を持つので、メモリ マネージャは、スタンバイ リストを 8 つのリストに分割します。各リストには、特定の優先順位のページが格納されます。メモリ マネージャがスタンバイ リストからページを取り出す場合は、優先順位の低いリストから先にページを取り出します。通常、ページの優先順位には、最初に割り当てを行ったスレッドの優先順位が反映されます (ページが共有されている場合は、共有スレッドのうち最高のメモリの優先順位が反映されます)。スレッドは、そのスレッドが属するプロセスからページ優先順位の値を継承します。メモリ マネージャは、プロセスのメモリ アクセスを予想したときにディスクから推測で読み取るページには、低い優先順位を使用します。
既定では、プロセスのページ優先順位の値は 5 ですが、各種の関数を使用すると、アプリケーションやシステムでプロセスおよびスレッドのページ優先順位の値を変更できます。メモリの優先順位の本当の力は、ページの相対的な優先順位がマクロレベルで理解されるときにのみ発揮されます。そこで SuperFetch の出番です。

SuperFetch
メモリ マネージャで大きく変更されたのは、物理メモリの管理方法です。Windows の前のバージョンで採用されていたスタンバイ リスト管理には、2 つの制限があります。まず、ページの優先順位付けは、プロセスの最近の動作だけに依存し、プロセスの今後のメモリ要求を予測しません。2 つ目に、優先順位付けに使用されるデータは、任意の時点でプロセスが所有するページのリストに限られます。こうした欠点のせいで、"アフター ランチ症候群"、つまり、しばらくの間コンピュータから離れると、メモリを大量に使用するシステム アプリケーション (ウイルス対策スキャンやディスクの最適化など) が実行されている、ということになる場合があります。このようなアプリケーションは、ユーザーが使用していたアプリケーションでメモリにキャッシュしたコードやデータを、メモリを大量に使用する動作で強制的に上書きしてしまいます。ユーザーが戻ると、元のアプリケーションのデータやコードをディスクから呼び出す必要があるので、動作が遅くなっていることがわかります。
Windows XP では、プリフェッチ (前取り出し) をサポートするようになりました。このため、大量のディスク I/O を実行して前回のブートやアプリケーションの起動に基づいて予想されるコードやファイル システム データをメモリにプリロードすることによってブートおよびアプリケーション起動のパフォーマンスが向上しています。Windows Vista は、SuperFetch (履歴情報と事前対応型のメモリ管理により、"最も長い時間アクセスされていない" ものを重視するメモリ管理方式) でさらに高度になっています。
SuperFetch は、サービス ホスト プロセス (%SystemRoot%\System32\Svchost.exe) 内で実行される Windows サービスとして %SystemRoot%\System32\Sysmain.dll 内に実装されています。この方式では、メモリ マネージャのサポートを利用します。その結果、ページ使用状況履歴を取得したり、データやコードをディスク上のファイルまたはページング ファイルからスタンバイ リストにプリロードして、ページに優先順位を割り当てるようメモリ マネージャに指示することができます。SuperFetch サービスでは、基本的にページ追跡の範囲を、一度メモリ内に存在したデータやコードで、しかもメモリ マネージャが新しいデータやコードのスペースを確保するために再利用したデータやコードにまで拡大しています。また、この情報をアプリケーションの起動の最適化に使用される標準のプリフェッチ ファイルと共に、%SystemRoot%\Prefetch ディレクトリに拡張子が .db のシナリオ ファイルとして保存します。メモリの使用状況に関するこの詳しい情報を活かして、SuperFetch では、物理メモリが使用可能になったときにデータやコードをプリロードできます。
メモリが解放されるとき (たとえば、アプリケーションが終了するか、メモリを解放するとき) には必ず、SuperFetch からの依頼でメモリ マネージャが最近追い出されたデータやコードを取得します。この処理は、ユーザーや他のアクティブなアプリケーションがプリロードの影響を受けないように、最低優先順位の I/O によって毎秒数ページの割合で行われます。したがって、ユーザーがコンピュータから離れて食事に行き、その間に、実行していたアプリケーションのコードやデータが、メモリを大量に使用するバックグラウンド タスクによってメモリから追い出されても、多くの場合、SuperFetch でユーザーが戻る前にそうしたコードやデータのすべてまたは大部分をメモリに戻すことができます。SuperFetch では、休止状態、スタンバイ、ユーザーの簡易切り替え (FUS)、およびアプリケーションの起動のためといった特定のシナリオもサポートしています。たとえば、システムが休止状態になると、SuperFetch は、後で再開したときに前回の休止状態に基づいてアクセスが予想されるデータやコードを休止状態ファイルに保存します。対照的に、Windows XP を再開する場合、以前にキャッシュされたデータは参照時にもう一度ディスクから読み取る必要があります。
SuperFetch が使用可能なメモリにどのように影響するかを把握するには、補足記事の「SuperFetch の詳細」を参照してください。
SuperFetch の詳細
Windows Vista システムをしばらく使用した後でも、タスク マネージャの [パフォーマンス] ページにある物理メモリの空き領域カウンタの数値が低いことがわかります。この理由は、SuperFetch と標準の Windows のキャッシュで、使用可能なすべての物理メモリを利用してディスク データをキャッシュするためです。たとえば、初めて起動したときにすぐにタスク マネージャを実行すると、キャッシュ メモリの数値が大きくなるにつれて空きメモリの値が小さくなることに気付きます。または、メモリを大量に必要とするプログラム (大量のメモリを割り当てた後にメモリを解放する "RAM オプティマイザ" のフリーウェアなど) を実行して終了するか、単に非常に大きいファイルをコピーすると、空きメモリの数値が大きくなり、物理メモリ使用量のグラフは、割り当てが解除されたメモリをシステムが再利用するにつれて下降します。ただし、時間の経過と共に、強制的にメモリ外に追い出されたデータがもう一度キャッシュに読み込まれるので、キャッシュされたメモリの数値が大きくなり、空きメモリの数値は小さくなります。
Watching memory
Watching memory (画像を縮小するには、ここをクリックします)
Watching memory
Watching memory (画像を拡大するには、ここをクリックします)

ReadyBoost
CPU とメモリの速度はハード ディスクの速度を大幅に上回っているので、ディスクはシステム パフォーマンスの一般的なボトルネックです。ランダムなディスク I/O が特に不経済な理由は、ディスク ヘッドのシーク時間の約 10 ミリ秒が、現在の 3 GHz プロセッサにとっては無限に長い時間となっているためです。RAM はディスク データをキャッシュするのに理想的ですが、比較的高価です。ただし、フラッシュ メモリは一般により安価で、一般的なハード ディスクよりも最大 10 倍を超える速さでランダムに読み取ることができます。したがって、Windows Vista には、フラッシュ メモリ ストレージ デバイスを利用する ReadyBoost という機能が用意されています。このデバイス上には、メモリとディスクの間に論理的に介在する中間キャッシュ層が作成されます。
ReadyBoost は、サービス ホスト プロセス内で実行される、%SystemRoot%\System32\Emdmgmt.dll に実装されたサービス、およびボリューム フィルタ ドライバ %SystemRoot%\System32\Drivers\Ecache.sys から構成されます (Emd は、開発時の ReadyBoost の旧称である External Memory Device (外部メモリ デバイス) の略です)。USB キーのようなフラッシュ デバイスをシステムに挿入すると、ReadyBoost サービスは、そのデバイスを調べてパフォーマンス特性を判別し、テスト結果を HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\Currentversion\Emdmgmt に保存します (図 1 参照)。
Figure 1 ReadyBoost device test results in the registry
Figure 1 ReadyBoost device test results in the registry (画像を縮小するには、ここをクリックします)
Figure 1 ReadyBoost device test results in the registry
Figure 1 ReadyBoost device test results in the registry (画像を拡大するには、ここをクリックします)
キャッシュ用のデバイスをまだ使用しておらず、新しいデバイスのサイズが 256 MB ～ 32 GB、4 KB のランダム読み取りの転送速度が 2.5 MB/s 以上、512 KB のランダム書き込みの転送速度が 1.75 MB/s 以上の場合、最大 4 GB のディスク キャッシュ専用ストレージにするかどうかをたずねるメッセージが表示されます (ReadyBoost は NTFS を使用できますが、FAT32 の制限に対応するために最大キャッシュ サイズが 4 GB に制限されています)。同意すると、ReadyBoost がデバイスのルートに ReadyBoost.sfcache という名前のキャッシュ ファイルを作成し、バックグラウンドで事前にキャッシュに読み込むよう SuperFetch に依頼します。
ReadyBoost サービスがキャッシュを初期化したら、Ecache.sys デバイス ドライバがローカル ハード ディスク ボリューム (C:\ など) に対するすべての読み取りと書き込みをインターセプトし、作成されたキャッシュ ファイルに書き込まれるすべてのデータをコピーします。Ecache.sys が、通常 2:1 の圧縮比になるようにデータを圧縮するので、4 GB のキャッシュ ファイルには通常 8 GB のデータが格納されます。このドライバは、ランダムに生成されるブート単位のセッション キーによる Advanced Encryption Standard (AES) 暗号化を利用して、書き込む各ブロックを暗号化します。このため、キャッシュ デバイスをシステムから取り外してもデータのプライバシーが保たれます。
ReadyBoost はキャッシュからランダムに読み取ることができるとわかると、キャッシュから読み取りますが、順次読み取りアクセスはハード ディスクの方がフラッシュ メモリより優れているため、順次アクセスの読み取りパターンの場合は、データがキャッシュにあっても直接ディスクにアクセスするようにします。

ReadyBoot
Windows Vista では、メモリが 512 MB 未満のシステムの場合 Windows XP と同じ起動時のプリフェッチを使用しますが、システムに 700 MB 以上のメモリが搭載されている場合は、RAM 内のキャッシュを利用してブート プロセスを最適化します。キャッシュのサイズは、使用可能な RAM の合計によって異なりますが、適度なキャッシュを作成可能であり、かつシステムのスムーズな起動に必要なメモリを確保できる大きさとなります。
毎回ブート後に、ReadyBoost サービス (説明したばかりの ReadyBoost 機能を実装する同じサービス) では、CPU の空き時間を利用して、次回のブートに備えて起動時のキャッシュ計画を計算します。また、直前の 5 回のブートにおけるファイル トレース情報を分析して、アクセスされたファイルとそのディスク上の格納場所を特定します。さらに、処理されたトレースを %SystemRoot%\Prefetch\Readyboot に .fx ファイルとして格納し、HKLM\System\CurrentControlSet\Services\Ecache\Parameters の、.fx ファイルが参照する内部のディスク ボリュームの名前が付いた REG_BINARY 値にキャッシュ計画を保存します。
キャッシュは、ReadyBoost キャッシュ (Ecache.sys) を実装する同じデバイス ドライバによって実装されますが、キャッシュの生成は、システム起動時に ReadyBoost サービスによって行われます。ブート キャッシュは ReadyBoost キャッシュと同様に圧縮されますが、ReadyBoost と ReadyBoot のキャッシュ管理におけるもう 1 つの違いは、ReadyBoot モードでは ReadyBoost サービスの更新以外にキャッシュが変更されることはなく、起動中に読み取り/書き込みが行われたデータは反映されない点です。ReadyBoost サービスは、ブート開始 90 秒後にキャッシュを削除するか、他のメモリの要求のためにキャッシュが必要な場合は、キャッシュの統計情報を HKLM\System\CurrentControlSet\Services\Ecache\Parameters\ReadyBootStats に記録します (図 2 参照)。マイクロソフトのパフォーマンス テストでは、ReadyBoot のパフォーマンスは従来の Windows XP プリフェッチャを約 20 パーセント上回っていることが示されています。
Figure 2 ReadyBoot Performance statistics
Figure 2 ReadyBoot Performance statistics (画像を縮小するには、ここをクリックします)
Figure 2 ReadyBoot Performance statistics
Figure 2 ReadyBoot Performance statistics (画像を拡大するには、ここをクリックします)

ReadyDrive
ReadyDrive は、H-HDD という新しいハイブリッド ハード ディスク ドライブを利用する、Windows Vista の機能です。H-HDD とは、不揮発フラッシュ メモリ (別名 NVRAM) が組み込まれたディスクのことです。一般的な H-HDD には、50 MB ～ 512 MB のキャッシュが搭載されていますが、Windows Vista のキャッシュ上限は 2 TB です。
Windows Vista では、ATA-8 コマンドを使用して、フラッシュ メモリに保持されるディスク データを定義します。たとえば、Windows Vista では、システムのシャットダウン時に、迅速に再起動できるようにブート データがキャッシュに保存されます。システムが休止状態になるときは、その後で迅速に再開できるように、休止状態ファイル データの一部もキャッシュに保存されます。ディスクが停止していてもキャッシュは有効になっているので、Windows では、システムがバッテリ電源で動作しているときにディスクが回転しないようにするために、フラッシュ メモリをディスク書込みキャッシュとして使用できます。ディスクのスピンドルを停止したままにすると、通常の使用状態でディスク ドライブに消費される電力よりも大幅に節約できます。

ブート構成データベース
Windows Vista では、起動とシャットダウンのいくつかの点が強化されました。起動は、システムと OS の起動構成を保存するためのブート構成データベース (BCD)、システム起動プロセスの新しいフローと構成、新しいログオン アーキテクチャ、および遅延自動起動サービスのサポートの導入によって改善されました。Windows Vista のシャットダウンに関する変更点には、Windows サービスのプレシャットダウン通知、Windows サービス シャットダウンの順序設定、および OS が電源の状態遷移を管理する方法の大幅な変更があります。
起動プロセスに対する最も目立つ変更点の 1 つは、システム ボリュームのルートから Boot.ini がなくなったことです。これは、Windows の旧バージョンでは Boot.ini テキスト ファイルに保存されていたブート構成が、Vista では BCD に保存されるためです。Windows Vista が BCD を使用する理由の 1 つは、現在 Windows でサポートされている 2 つのブート アーキテクチャ、つまり、マスタ ブート レコード (MBR) と拡張ファームウェア インターフェイス (EFI) を統合するためです。MBR は、一般に x86 と x64 デスクトップ システムで使用されていますが、EFI は Itanium ベースのシステムで使用されています (ただし、近い将来デスクトップ パソコンには EFI サポートが付属するようになりそうです)。BCD によりファームウェアが抽象化されることに加え、他にも Unicode 文字列や代替プレブート実行可能ファイルのサポートなど、Boot.ini を上回る利点を備えています。
BCD は、実際にはレジストリ API を介したアクセスによって Windows レジストリに読み込まれる、ディスク上のレジストリ ハイブに格納されます。パソコン上では、BCD は Windows によりシステム ボリュームの \Boot\Bcd に格納されます。EFI システムでは、BCD は EFI システム パーティションにあります。このハイブが読み込まれると HKLM\Bcd00000000 の下に設定されますが、その内部形式は公開されていないので、その値を編集するには、%SystemRoot%\System32\Bcdedit.exe のようなツールを使用する必要があります。BCD を操作するためのインターフェイスは、Windows Management Instrumentation (WMI) を介してスクリプトやカスタム エディタからも利用できますし、Windows システム構成ユーティリティ (%SystemRoot%\System32\Msconfig.exe) を使用して、カーネル デバッグ オプションのような基本パラメータを編集したり追加することができます。
BCD では、OS ブート オプションや OS ブート ローダーへのパスのような OS 固有の設定から、既定の OS の選択やブート メニュー タイムアウトのようなプラットフォーム全体にわたるブート設定を分離しています。たとえば、図 3 は、コマンド ライン オプションを指定せずに Bcdedit を実行すると、一番上の Windows ブート マネージャ セクションにプラットフォーム設定が表示され、続いて Windows ブート ローダー セクションに OS 固有の設定が表示されることを示しています。
Figure 3 Settings displayed in BCDEdit
Figure 3 Settings displayed in BCDEdit (画像を縮小するには、ここをクリックします)
Figure 3 Settings displayed in BCDEdit
Figure 3 Settings displayed in BCDEdit (画像を拡大するには、ここをクリックします)
Windows Vista インストールを起動すると、この新しい方式では、Windows の旧バージョンのオペレーティング システム ローダー (Ntldr) で処理されていたタスクが \BootMgr および %SystemRoot%\System32\Winload.exe という 2 種類の実行可能ファイルに分割されます。Bootmgr は BCD を読み取って OS ブート メニューを表示し、Winload.exe はオペレーティング システムの読み込みを処理します。クリーン ブートを実行している場合、Winload.exe はブート開始デバイス ドライバとコア オペレーティング システム ファイル (Ntoskrnl.exe など) を読み込み、オペレーティング システムに制御を渡します。システムが休止状態から再開している場合は、%SystemRoot%\System32\Winresume.exe を実行して、休止状態データをメモリに読み込み、OS を再開します。
Bootmgr では、プレブート実行可能ファイルの追加もサポートしています。Windows Vista には、RAM の状態を確認するためのオプションとして構成済みの Windows メモリ診断ツール (\Boot\Memtest.exe) が付属していますが、サードパーティが、Bootmgr のブート メニューに表示されるオプションとして独自のプレブート実行可能ファイルを追加できます。

起動プロセス
Windows の旧バージョンでは、各種システム プロセス間の関係がわかりやすくありませんでした。たとえば、システムの起動時に、対話型ログオン マネージャ (%SystemRoot%\System32\Winlogon.exe) はローカル セキュリティ機関サブシステム サービス (Lsass.exe) とサービス コントロール マネージャ (Services.exe) を起動します。さらに、Windows では、セッションという名前空間コンテナを使用して、さまざまなログオン セッションで実行しているプロセスを分離します。しかし、Windows Vista より前では、コンソールにログオンするユーザーは、システム プロセスで使用されるセッションであるセッション 0 を共用していたため、セキュリティの問題が生じるおそれがありました。そのような問題が生じるのは、たとえば、セッション 0 で実行する品質の悪い Windows サービスが対話型コンソールにユーザー インターフェイスを表示する場合です。このとき、マルウェアはシャッター攻撃のような技術でウィンドウを攻撃して管理者特権を獲得できます。
こうした問題に対処するために、Windows Vista のいくつかのシステム プロセスはアーキテクチャが変更されました。セッション マネージャ (Smss.exe) は、Windows の旧バージョンのように起動時に作成される最初のユーザー モード プロセスですが、Windows Vista では、セッション マネージャは、それ自体の 2 つ目のインスタンスを起動してシステム プロセス専用のセッション 0 を構成します。セッション 0 用のセッション マネージャ プロセスは、Windows スタートアップ アプリケーション (Wininit.exe) と、セッション 0 用の Windows サブシステム プロセス (Csrss.exe) を起動した後、終了します。Windows スタートアップ アプリケーションは、サービス コントロール マネージャ、ローカルセキュリティ権限サブシステム、およびコンピュータのターミナル サーバー接続を管理する新しいプロセスであるローカル セッション マネージャ (Lsm.exe) を起動して続行します。
ユーザーがシステムにログオンすると、最初のセッション マネージャが、それ自体の新しいインスタンスを作成して新しいセッションを構成します。新しい Smss.exe プロセスは、新たなセッション用の Windows サブシステム プロセスと Winlogon プロセスを起動します。第 1 のセッション マネージャ自体のコピーを使用して新しいセッションを初期化しても、クライアント システムには何のメリットもありません。しかし、ターミナル サーバーとして動作する Windows Server "Longhorn" システムでは、複数のコピーが同時に実行して複数のユーザーが迅速にログオンできます。
この新しいアーキテクチャでは、Windows サービスなどのシステム プロセスは、セッション 0 に分離されます。セッション 0 で実行する Windows サービスがユーザー インターフェイスを表示すると、対話型サービス検出サービス (%SystemRoot%\System32\UI0Detect.exe) は、それ自体のインスタンスをユーザーのセキュリティ コンテキストで起動し、図 4 に示すメッセージを表示して、ログオンしているすべての管理者に通知します。ユーザーが [メッセージを表示する] ボタンをクリックすると、デスクトップが Windows サービス デスクトップに切り替わるので、ユーザーはそのサービスのユーザー インターフェイスとやりとりした後、元のデスクトップに戻ることができます。起動時の処理の詳細については、補足記事の「起動プロセスの関係の表示」を参照してください。
Figure 4 Service has displayed a window
Figure 4 Service has displayed a window (画像を縮小するには、ここをクリックします)
Figure 4 Service has displayed a window
Figure 4 Service has displayed a window (画像を拡大するには、ここをクリックします)
起動プロセスの関係の表示
Sysinternals (microsoft.com/technet/sysinternals) (英語) の Process Explorer を使用すると、Windows Vista のプロセス起動ツリーを確認できます。
スクリーンショットには、セッション列が含まれていますが、この列は、Process Explorer の列ダイアログ ボックスを介して追加できます。強調表示されているプロセスは、最初の Smss.exe です。その下にセッション 0 の Csrss.exe と Wininit.exe があります。これらが左揃えになっているのは、その親プロセス (セッション 0 を構成した Smss.exe のインスタンス) が終了したためです。Wininit には、Services.exe、Lsass.exe、および Lsm.exe という 3 つの子があります。
セッション 1 (リモート デスクトップ接続を介して私がログインしているセッション) で実行しているプロセスが識別されています。また、Process Explorer は、それ自体と同じアカウントで実行しているプロセスを青の強調色で表示しています。最後に、コンソールにログインしているユーザーのために、セッション 2 が初期化され、新たなログオン セッションを作成できるようにしています。そのセッションでは、Winlogon が実行中であり、LogonUI を使用して新しいコンソール ユーザーに "ログオンするには Ctrl + Alt + Del を押してください。" という操作を要求しています。また、Logonui.exe がユーザーの資格情報の入力を求めています。
Startup process and session information
Startup process and session information (画像を縮小するには、ここをクリックします)
Startup process and session information
Startup process and session information (画像を拡大するには、ここをクリックします)

資格情報プロバイダ
Windows Vista ではログオン アーキテクチャも変更されています。Windows の旧バージョンでは、Winlogon プロセスが、レジストリで指定された GINA (Graphical Identification and Authentication) DLL を読み込み、ユーザーに資格情報の入力を求めるログオン UI を表示します。残念ながら、GINA モデルでは、GINA は 1 つしか構成できないこと、サードパーティが完全な GINA を作成するのは困難であること、および非標準のユーザー インターフェイスを持つ独自の GINA では Windows ユーザー エクスペリエンスが変わってしまうことなどの制限があります。
Windows Vista では、GINA に代わる新しい資格情報プロバイダ アーキテクチャを採用しています。Winlogon は、ログオン ユーザー インターフェイス ホスト (Logonui.exe) という別のプロセスを起動します。このプロセスは、HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\Currentversion\Authentication\Credential Providers に構成されている資格情報プロバイダを読み込みます。Logonui は、複数の資格情報プロバイダを同時にホストすることができます。ちなみに、Windows Vista には対話型プロバイダ (Authui.dll) とスマートカード プロバイダ (Smart-cardcredentialprovider.dll) が付属しています。ユーザー エクスペリエンスを統一するために、LogonUI はエンド ユーザーに表示されるユーザー インターフェイスを管理しますが、LogonUI を使用することにより、資格情報プロバイダがテキスト、アイコン、編集コントロールのようなカスタム要素を指定することもできます。

遅延自動起動サービス
Windows システムの起動直後に Windows システムにログオンしたことがある方なら、デスクトップが完全に構成され、シェルやアプリケーションとやりとりができるようになるまでに時間がかかるのを経験したことがあると思います。ログオン中には、サービス コントロール マネージャが、起動時にアクティブにする自動起動サービスとして構成された多くの Windows サービスを開始しています。多くのサービスでは、ユーザーのログオン操作と競合する、CPU やディスクを大量に使用する初期化を実行します。これに対応するために、Windows Vista では、遅延自動起動という新たな種類のサービス開始機能が導入されています。この機能は、サービスが Windows の起動直後にアクティブでなくてもよい場合に使用されます。
サービス コントロール マネージャは、自動開始サービスによるサービスの開始が完了した後に遅延自動起動として構成されたサービスを開始し、THREAD_PRIORITY_LOWEST にそれぞれの最初のスレッドの優先順位を設定します。この優先順位レベルにより、スレッドが実行するすべてのディスク I/O が最低の I/O 優先順位になります。サービスが初期化を完了したら、サービス コントロール マネージャがその優先順位を標準の値に設定します。遅延起動の組み合わせ、CPU とメモリの低優先順位、およびバックグラウンドのディスク優先順位のおかげで、ユーザーのログオンが邪魔されにくくなります。Background Intelligent Transfer、Windows Update クライアント、Windows Media® Center をはじめとする、数多くの Windows サービスでは、この新たな種類のサービス開始機能を使用すると、ブート後のログオンのパフォーマンスを向上できるようになります。

シャットダウン
Windows サービスの開発者を悩ませる問題は、Windows のシャットダウン時のクリーンアップの実行に、既定で最大 20 秒しかないことです。Windows Vista より前のバージョンの Windows では、バグの多いサービスのせいでシャットダウンが無期限に停滞する場合があるため、すべてのサービスの終了を待つクリーン シャットダウンをサポートしていませんでした。ネットワーク関連のシャットダウン操作を必要とするサービスや大量のデータをディスクに保存するサービスのような一部のサービスは、より多くの時間がかかる可能性があるので、Windows Vista では、サービスがプレシャットダウン通知を要求できます。
Windows Vista がシャットダウンする場合は、最初にサービス コントロール マネージャが、プレシャットダウン通知を要求しているそれぞれのサービスに通知します。次に、こうしたサービスが終了するのを無期限に待ちますが、サービスにバグがあるために問い合わせに応じない場合、サービス コントロール マネージャは 3 分後に待つのをやめて先に進みます。そうしたサービスがすべて終了するか、タイムアウト期間が経過したら、サービス コントロール マネージャは、従来のスタイルのサービスについて、残りのサービスのシャットダウンを続行します。グループ ポリシーと Windows Update サービスは、Windows Vista の新規インストールの際にプレシャットダウン通知を登録します。
グループ ポリシーと Windows Update サービスでは、もう 1 つの Windows Vista サービス機能であるシャットダウンの順序設定も使用します。開始時のサービスの依存関係は、これまでも指定可能でした。つまり、サービス コントロール マネージャが、そうした依存関係を満たす順序でサービスを開始するように対応していました。しかし、Windows Vista まで、シャットダウン時のサービスの依存関係は指定することができませんでした。プレシャットダウン通知に備えて登録を実行するサービスでは、それ自体を、HKLM\System\CurrentControlSet\Control\PreshutdownOrder に格納されているリストに挿入することもできるようになったので、サービス コントロール マネージャはその順序に従ってサービスを停止します。こうしたサービスの詳細については、補足記事の「遅延自動起動とプレシャットダウン サービスの識別」を参照してください。

電源管理
スリープと休止状態はシャットダウンの別の形ですが、Windows 2000 で Windows NT® ベースの一連の Windows オペレーティング システムに電源管理が導入されて以降、ドライバやアプリケーションのバグだらけの電源管理は、外回りの多いビジネスマンにとってわざわいのもとになっていました。多くのユーザーは、出かける前にラップトップ システムのふたを閉じたときにシステムが中断または休止していると思っていましたが、着いた先ではキャリング バッグが熱を帯び、バッテリ切れで、データが失われた状態になるだけでした。これは、Windows では必ずデバイス ドライバやアプリケーションに電源の状態の変更を打診しますが、応答しないドライバやアプリケーションが 1 つでもあると中断や休止ができなくなることがあったためです。
Windows Vista では、カーネルの電源マネージャが、ドライバやアプリケーションが準備できるように、これまでどおり電源の状態の変更をドライバやアプリケーションに通知しますが、許可は求めなくなりました。さらに、電源マネージャは変更通知に対するアプリケーションの応答を、Windows の旧バージョンのように 2 分ではなく、最大 20 秒しか待ちません。その結果、Windows Vista ユーザーは、システムの休止や中断がより確実に行われることを体験できます。

次回のトピック
前述のように、今回は 3 部シリーズの第 2 回目をお届けしました。第 1 部では、Windows Vista カーネルの I/O とプロセスの強化点について説明しました。今回は、Windows Vista のメモリ管理、起動、およびシャットダウンにおける機能拡張について説明しました。次回は、信頼性とセキュリティの領域におけるカーネルの変更点を説明してこのシリーズを締めくくります。
遅延自動起動とプレシャットダウン サービスの識別
組み込みの SC コマンドは、遅延自動起動サービスとして構成されているサービスを表示するように Windows Vista では更新されています。
Using SC to display start type
Using SC to display start type (画像を縮小するには、ここをクリックします)
Using SC to display start type
Using SC to display start type (画像を拡大するには、ここをクリックします)
残念ながら、SC コマンドではプレシャットダウン通知を要求したサービスはレポートされませんが、Sysinternals の PsService ユーティリティを使用すると、サービスがプレシャットダウン通知を受け入れるかどうかを確認できます。
Viewing pre-shutdown status
Viewing pre-shutdown status (画像を縮小するには、ここをクリックします)
Viewing pre-shutdown status
Viewing pre-shutdown status (画像を拡大するには、ここをクリックします)

Mark Russinovich は、Microsoft の Platform and Services Division に所属するテクニカル フェローです。また、『Microsoft Windows Internals』(英語) (Microsoft Press、2004) の共同執筆者であり、IT カンファレンスや開発者向けカンファレンスで頻繁に講演を行っています。彼は、共同で設立した Winternals Software 社の Microsoft による先ごろの買収に伴い、Microsoft に入社しましたが、Sysinternals の設立者でもあり、同社では Process Explorer、Filemon、および Regmon の各ユーティリティを発表しています。


 編集者から: トロフィー棚
編集者から
トロフィー棚
Joshua Trupin

私は生まれてこの方一度も勝負に勝ったことのないまま、約 30 年間過ごしてきました 。スピードくじを引けば、いつもさくらんぼ 2 個としかめ面です。キャンディーの包みを開ければ、「残念でした。またどうぞ」と書かれています。私は決勝戦のフットボール賭博でニューヨークのチームに賭けています。
この悲惨な過去の実績を考えれば、私が何かに勝利したときに激しい興奮を覚えても不思議はないでしょう。TechNet Magazine は、このたび Society for Technical Communication (STC) から 4 つの賞を受賞しました。私たちは、どんな問題にも心血を注いでいるので、その労力が認められたことは喜ばしいかぎりです。この場を借りて、スタッフや著者のみなさまのご助力に謝意を表します。
2006 年 3 月号と 4 月号では、Active Directory に関する明快でわかりやすいジグソー パズル ポスター形式のガイドをお届けしました。あの号は大好評で、今でも欲しいという要望が日々寄せられています。そのポスターが、STC から Excellence for Software Guides (優秀ソフトウェア ガイド賞) を受賞しました。
また、2 つの記事が高い評価を受けました。2006 年 8 月の「Playing with Exchange in a Sandbox」(英語)(Greg Taylor、Simon Shepherd 共著) と 2006 年 5 月および 6 月の「Deconstructing Common Security Myths」(英語)(Jesper Johansson、Steve Riley 共著) が Merit from the STC (STC 功労賞) を受賞しました。
TechNet Magazine も Award of Excellence for Scholarly & Professional Journals (優秀学術/専門誌賞) を受賞しました。このような評価を受けたこと、および共に職務に励んだチーム一同をこの上なく誇りに思います。
ご心配には及びません。私たちはこの栄誉に安住するつもりはありません。今号では、Mark Russinovich が Windows Vista のカーネル変更の詳細について説明します。この情報はデスクトップの展開やサポート サービスに携わる情報技術者にとって長期的な価値がある重要情報です。また、今月は、SQL Server の詳細についても、インデックス メタデータ、テーブルのパーティション分割、高可用性オプション、クラスタ化のヒントなど全般にわたって説明します。
TechNet Magazine の広場に休息はありません (締め切りがあるものですから)。でも、時には場所を変えて気晴らしをしています。2007 年 6 月 4 ～ 8 日にはオーランドで Microsoft TechoEd が開催されます (microsoft.com/teched をご覧ください)。受賞した TechNet Magazine の編集者や著者たちとの歓談にお越しください。懸賞や楽しい企画を用意してお待ちしています。あなたにも受賞のチャンスがあります。-JOSHUA TRUPIN
次のマイクロソフト技術支援スタッフに心より感謝します。Vijay Bharadwaj、Paul Bowden、Elden Christensen、Manish Karla、Michael Murgolo、Rajeev Nagar、John Peng、Mark Russinovich、Abraham Samuel、Mark Scurrell、Jim Truher、George Walters、Buck Woody

Joshua Trupin


 ツールボックス: IT プロフェッショナル向けの新製品
ツールボックス
IT プロフェッショナル向けの新製品
Greg Steen

ネットワークの同期を管理する
ViceVersa Pro
www.tgrmn.com

1 台のコンピュータから成るインフラストラクチャでない限り、自分の環境のファイルをあちこちに移動しなければならないことがよくあります。ログ ファイルからアプリケーション リリース、さらにデータベース バックアップに至るまで、データは常にネットワーク中を移動しています。また、さまざまな環境を同期した状態に保つために、コピーする必要がある項目を把握しておくことが重要です。ほとんどの IT プロフェッショナルの場合、各種環境のこうしたファイルを手動で移動する方法は選択肢にありません。この方法は、環境の同期が取れなくなることがあるため、好ましくないことは言うまでもありません。
TGRMN Software 社の ViceVersa Pro では、そうしたタスクの自動化やスケジュール設定を容易に行うことができます。このアプリケーションには、4 種類のコピー モードが用意されています。Basic Synchronization では、同期元から同期先に対する同期が行われ、Advanced Synchronization モードでは、ファイル追跡機能を使用してファイルとディレクトリの双方向の同期が行われます。その他に Backup (各自のソースをミラーする) および Consolidation という 2 つのモードがあります。
Backup モードでは、ソースがターゲットにミラーされ、そのターゲットに対してファイルの追加や削除が行われますが、ファイルのレプリケーションを選択することもできます。その場合は、ファイルがターゲットにコピーされるだけです。予期せずにファイルを削除するユーザーがいる場合に、この機能が非常に役立つことがわかります。双方向の同期は、その名が示すとおり競合や削除の追跡機能を加えた状態で実行されます。次の同期の前にソースとターゲットのファイルが変更されると、競合が発生していることが示されるので、その問題を手動で調整できます。Consolidation モードでの同期は、双方向の同期と似ていますが、競合や削除の情報は追跡されません。
Protect against copy errors and data loss
Protect against copy errors and data loss (画像を縮小するには、ここをクリックします)
Protect against copy errors and data loss
Protect against copy errors and data loss (画像を拡大するには、ここをクリックします)
ViceVersa Pro では、Backup モードでファイル圧縮やファイル暗号化の統合機能を使用してログ配布タスクを支援できます。このアプリケーションは、ソース ファイルを標準の gzip 形式に圧縮します。この圧縮ファイルは、パスワードで保護できます。
ViceVersa Pro には優れたファイル比較機能も組み込まれていますが、必要に応じて、外部のファイル比較プログラムを使用するように ViceVersa Pro を設定することもできます。グローバルな環境に対応するために、ViceVersa Pro では、Unicode 文字および 256 文字 (バイト) より長いパスを処理できます。このアプリケーションは、インターネット時刻との同期にも対応しているので、ローカルの NTP コンピュータまたは外部の NTP サーバー (ViceVersa Pro を使用している環境からの要求の送信が許可されている場合) を参照するように設定できます。
帯域幅の使用率が懸念材料になる場合があります。特に、トラフィックが VPN または WAN 全体を流れている場合にそれが考えられます。そのような場合は、ViceVersa Pro を使用すると、アプリケーションが各同期タスクで使用する帯域幅の量を抑制できます。このようにすれば、コピー先またはコピー元のサーバーから実稼働レベルの応答を確実に得られるようになります。または、CPU 使用率の最大しきい値の上限を設定して、アプリケーション実行時のサーバーの可用性を確保することもできます。
ViceVersa Pro では、安全なコピー アルゴリズムを使用してコピー エラーやデータの消失が発生しないようにしています。このアプリケーションは、データの整合性を確保するために巡回冗長検査 (CRC) による検証も実行します。また、リアルタイム モード (同期フォルダに対してファイルを追加または削除するときにファイルを同期) を含めて、あらゆる間隔で実行するよう同期タスクのスケジュールを設定できます。
ViceVersa Pro のもう 1 つの優れた機能は、操作を実行する前に UI でプレビューできる点です。この機能により、必要なファイルを確実にコピーできるようになります。したがって、システム ディレクトリに数ギガバイトのログ ファイルが生成されることはありません。
一般に、低価格でフル装備の同期ツールを探している場合は、ViceVersa Pro がニーズを満たす可能性があります。
価格 : 59.95 ドル (1 ユーザーごと)

システムのディスクを管理する
Partition Manager 8.0 Professional Edition
www.partition-manager.com/corporate/professional
システムのディスクの管理に役立つアプリケーションを探している場合、Paragon Software Group 社の Partition Manager 8.0 Professional Edition は間違いなく検討に値します。
このアプリケーションのコア機能として、Windows® ベースのアプリケーションの直観的なウィザード型のインターフェイスを備えているので、FAT16/32、NTFS、Ext2/3、または HPFS のフォーマットにかかわらずハード ディスク パーティションの作成、削除、表示の変更、フォーマットを容易に行うことができます。また、既存のパーティションのサイズを変更したり、あるディスクから別のディスクにパーティションを移動することもできます。
さらに高度な機能として、FAT16/32 から NTFS、Ext2 から Ext3 およびその逆など、ファイル システムの間の変換を行うことができます。ディスクをまたがってパーティションをコピーすると、パーティションのサイズが自動的にディスクのサイズに変更されます。そのため、すべてのファイルを手動でコピーしなくてもシステムのデータ ドライブを容易に拡張できます。バージョン 8.0 の役に立つ機能の 1 つに "ホット リサイズ" 機能があります。この機能では、Windows を再起動せずにアクティブな NTFS パーティションのサイズを大きくすることができます。
Increase the size of an active NTFS partition £ without rebooting
Increase the size of an active NTFS partition £ without rebooting (画像を縮小するには、ここをクリックします)
Increase the size of an active NTFS partition £ without rebooting
Increase the size of an active NTFS partition £ without rebooting (画像を拡大するには、ここをクリックします)
Pro Edition のもう 1 つの役立つ機能とは、ダイナミック ディスクを Windows 2000、Windows XP、および Windows Server® 2003 のクライアントのベーシック ディスクに変換できることです。Partition Manager は、FireWire 接続や USB 接続のドライブと同様に少なくとも 500 GB (Paragon のテスト時の制限であり、物理的な制限ではない) までディスクをサポートします。また、Partition Manager は、PATA (IDE)、SATA、および SCSI のハード ディスクに対応しています。
Partition Manager では、致命的なディスク障害が発生した後のシステムの復元に役立つ修復 CD-ROM (または DVD やフロッピー ディスク) を作成できます。また、誤ってパーティションを削除してもシステムがアクティブであれば、インターフェイスを介してパーティションの削除を取り消すことができます。さらに、ディスクのクラスタ サイズを変更できるので、パフォーマンスを微調整が簡単です。このアプリケーションには "仮想プレ実行" ビューが用意されており、このビューで、ディスクに変更を物理的にコミットする前に該当するディスクの変更を評価することもできます。
また、Partition Manager 8.0 でシステムのハード ドライブをアップグレードすることもできます。このアプリケーションを使用すると、パーティションまたはハード ディスク イメージ全体を、コピー先のパーティション サイズに合わせて新しいディスクにコピーできます。
最後に、Partition Manager には、99 パーセントまでいっぱいになっているドライブを最適化できるディスク デフラグ ツールも組み込まれています。ですが、ドライブがこのような状態になる前に措置を講じることができれば一番よいのですが。
価格 : 99.95 ドル (Professional Edition)

SQL エディタにオートコンプリートを追加する
SQL Prompt: IntelliSense for SQL
www.red-gate.com/products/SQL_Prompt/index.htm

すべてのデータベースは、論理的な名前付け規則に基づいて標準化された形式で作成され構造化されていると考えたくなりますが、残念ながら、そうではありません。システム管理者またはデータベース管理者の仕事をしていると、クエリを作成または実行するときにテーブル構造を頻繁に参照しなければならないことがわかります。開発者となると、なおさらです。
SQL Server™ Management Studio for SQL Server 2005 では、インターフェイスのツリー ビュー セクションにオブジェクト ブラウザを組み込むことで操作が非常に楽になりましたが、それでも筆者は Visual Studio® IDE: IntelliSense® の使い慣れた機能が必要だと考えます。幸運なことに、Red-Gate Software が提供している SQL Prompt によって、Microsoft SQL Server エディタでオートコンプリート機能を使用できます。
このアプリケーションはタスク バーで動作し、ユーザーがエディタで作業を開始したタイミングを検出します。最初に、SQL Prompt は、すべてのオブジェクト データにアクセスしてキャッシュすることができるように、データベースの接続情報についてたずねます。これによりパフォーマンスが向上し、オーバーヘッドが削減されますが、データベース インスタンスのオブジェクトを絶えず変更している場合、プロンプト リストの変更を確認するには、キャッシュのクリア (2 回クリックするだけ) を忘れないようにする必要があります。
Visual Studio IDE、Enterprise Manager、Query Analyzer、および SQL Server Management Studio の他に、SQL Prompt は、UltraEdit や EditPlus 2 とも直接統合されます。設定 UI の [Options] タブで、候補一覧をトリガするのに必要な SQL キーワード (FROM、JOIN、EXEC など) を示すことができます。SQL JOINS で SQL Prompt をトリガすると、同じ名前の参照セットまたはフィールドがあると仮定して、ON ステートメントが表示されます。ここでも、コード スニペット挿入用のテキスト ショートカットを設定できます。たとえば、このアプリケーションでは、"ssf" の後に Tab キーを押すと "SELECT * FROM" と表示されます。また、SQL キーワードを入力するときに自動的に大文字に変更させることもできます。この機能やコード スニペットで確実に時間を節約できます。
設定 UI の [Candidates] タブで、完全修飾列名を SQL Prompt で使用するかどうかの設定、所有者/スキーマ情報の接頭辞の付加、自分の名前への角かっこの付加、および候補一覧に表示する SQL 機能の種類の設定を行うことができます。SQL を使用する場合は、自分の七つ道具にこのツールを追加できます。
SQL Prompt はバージョン 3.0 のリリースまで無料のままで、このドキュメントの執筆時点では、最終ベータ版の状態でした。バージョン 3.0 の価格は、まだ公開されていません。
価格 : 無料

ページ サイズを計算する
Atomic Web Page Size Calculator
www.info-pack.com/pagesize
エンド ユーザーの帯域幅がますます広くなっている中で、そうしたエンド ユーザーにより迅速に Web コンテンツを提供するために新しいテクノロジが役に立っていますが、それでもページ サイズは重要です。そのようなバイト数のために、高トラフィック サイトの場合は帯域幅のコストが相当なものになります。
Info-pack.com 社の Atomic Page Size Calculator ユーティリティでは、Web サイト ページのページの重みを低コストで簡単に確認できます。サイズに問題のあるページの URL を入力するだけで、Atomic Page Size Calculator はページを取得し、外部から参照される画像 (プライマリ ドメインの Web ログには表示されないことがある項目) を含むすべての要素の大きさを計算します。
Keep an eye on bandwidth cost
Keep an eye on bandwidth cost (画像を縮小するには、ここをクリックします)
Keep an eye on bandwidth cost
Keep an eye on bandwidth cost (画像を拡大するには、ここをクリックします)
Atomic Page Size Calculator は、ページ、画像、および JavaScript ファイルをサポートするので、ページ上のほとんどのリソースに関するデータを取得できるはずです。また、Atomic Page Size Calculator では、リソースの "破損" を示す 404 エラーを検出時の通知も行います。URL の大きさに関する情報を入手したら、[Report] ボタンをクリックすると、サイズの分析結果、およびさまざまな接続速度でその URL をダウンロードするのにかかる時間の評価が表示されます。
このアプリケーションで同時に複数の URL を処理できれば最高なのですが、それは今後のリリースでということになりそうです。開発チームのページのページ サイズを迅速に確認する方法を探しているのであれば、このアプリケーションが最適かもしれません。
価格 : 19.95 ドル (直販)

ツールボックスにご意見、ご要望をお送りください。
ここで取り上げてほしいおすすめのツールやユーティリティがございましたら作者 tntools@microsoft.com まで英語でご連絡ください。
Greg Steen は技術プロフェッショナルであり、企業家でもあります。また、新製品のファンとも言えます。彼は IT プロフェッショナルが行う操作や開発を容易にする新しいツールや方法をいつも探しています。


 ユーティリティ スポットライト: SyncToy
ユーティリティ スポットライト
SyncToy
Jay Munro
この記事で使用しているコードのダウンロード: SynctToy (971KB)

情報技術者、ネットワーク管理者、ヘルプ デスク担当者に共通の頭痛の種 は、バックアップを忘れてコンピュータのデータを紛失したユーザーからの問い合わせです。ローカルだけでなく、ネットワーク上にもデータを保存しているような賢明なユーザーでさえ、困難に遭遇する可能性があります。そんなとき、SyncToy が役立ちます。
元々、カメラ、コンピュータ、外部ドライブ間でデジタル写真を同期するために作られた SyncToy は、ほぼあらゆる種類のファイルのバックアップに使用できる柔軟性と信頼性に優れた手段です。SyncToy は Windows Vista™、Windows® XP、Windows Server® 2003 上で動作し、ローカル ドライブ、外部ドライブ、USB ドライブでも、ネットワークやワークグループの共有でも使用できます。
SyncToy では、ユーザーが左右のディレクトリを指定するペア フォルダ アーキテクチャを採用しています。フォルダ ペアはいくつでも作成可能で、ボタン クリック 1 つで 1 つのペアまたはすべてのペアを同期できます。フォルダ ペアを作成するには、簡単な 4 ステップのウィザードに従って、左右のフォルダのパスを入力または貼り付けするか、フォルダの場所を参照します。SyncToy は、UNC ファイル命名規則 (\\MyServer\Joe_smith\backup\ など) と、ローカル ドライブのマッピングおよびパス (E:\doc_backup) を認識します。パスを入力したら、フォルダを照合する際の SyncToy の動作を 5 つのうちから 1 つ選択します。
[Sync] 2 つのディレクトリ内で新規作成および更新されたファイルをコピーします。フォルダ内のファイルの名前を変更するか、ファイルを削除すると、その操作がもう一方のフォルダに複製されます。
[Echo] 新規作成および更新されたファイルをコピーし、左のフォルダから右のフォルダに対してのみ削除および名前変更を実行します。
[Subscribe] 左のフォルダにファイルが存在する場合にのみ、更新されたファイルを右のフォルダから左のフォルダにコピーします。左のフォルダが変更されても、右のフォルダには複製されません。
[Contribute] 左のフォルダで新規作成および更新されたファイルを右のフォルダにコピーし、削除は無視します。
[Combine] 一方のフォルダのみに存在するファイルを他方にコピーして、複数のマシンの同期を維持します。どちらかのフォルダで削除または名前が変更されたファイルは、変更または複製されません。
操作を選択したら、フォルダ ペアの表示名を選択して完了です。SyncToy では、現在、フォルダ ペアの作成後にパスの編集や名前の変更はできません。間違えた場合は、フォルダ ペアを選択し [Delete] をクリックして再作成する必要があります。処理対象に含めるファイルやサブディレクトリを選択するオプションや、上書きしたファイルをごみ箱に保存するかどうかを指定するオプション (既定では保存する) などを設定できます。
Synchronizing files with SyncToy
Synchronizing files with SyncToy (画像を縮小するには、ここをクリックします)
Synchronizing files with SyncToy
Synchronizing files with SyncToy (画像を拡大するには、ここをクリックします)

メイン SyncToy ダイアログ ボックスの左側に、フォルダ ペアと、選択したペアのパス、オプション、アクションが表示されます。[All Folder Pairs] オプションを選択すると、すべてのフォルダ ペアが表示され、選択したペアに対して [Preview] または [Run All] を実行できます。お察しのとおり、[Preview] を実行すると、同期が行われた場合と同様の動作をしますが、実際には変更は一切行われません。これは、無人同期をスケジュールする場合に有効な機能です。プレビューではレポートが表示されます。このレポートを見れば、操作を実際に行った場合にどのような結果になるかがわかります。問題がなければ、[Run] をクリックします。
スケジューリング機能は組み込まれていませんが、ヘルプ ファイルに Windows Vista のスケジューラを使用した場合と Windows XP のスケジューラを使用した場合の手順が詳細に記載されています。技術者以外のユーザーがこの設定を行う場合はサポートが必要かもしれませんが、一度設定すれば、フォルダ ペア、アクション、オプションのすべての変更は SyncToy が自動的に処理します。
すべての Power Toys と同様、SyncToy も正規の市販ソフトウェアと同じ標準に従って作成されていますが、Microsoft ではサポートしておらず、コミュニティのフォーラムやドキュメントによってサポートされています。これは自力でお試しください。ヘルプ ファイルはあらゆるユーザー レベルを対象に記述されており、機能についても詳しく説明しています。ユーザー インターフェイスは直感的であり、基本的な機能は一目でわかるようになっています。
SyncToy をダウンロードして、ユーザーにファイルのバックアップ方法を教えてあげてください。これで、心置きなく眠れるようになることでしょう。

Jay MunroMicrosoft の Windows ユーザー アシスタンス チームで Internet Explorer を担当しています。以前は、PC Magazine 研究所のプロジェクト リーダーでした。


 SQL に関する Q&amp;A: サマータイム、サーバー メモリ、その他
SQL に関する Q&A
サマータイム、サーバー メモリ、その他
Nancy Michell

サマータイム
質問 - 米国では 2005 年エネルギー政策法 (Energy Policy Act of 2005) に準拠してサマータイム (DST) への変更が予定されていますが、SQL Server™ を更新する必要がありますか。
回答 - 必要ありません。現時点では、DST に変更できるようにするために必要な SQL Server 専用の更新プログラムはありません。時間に関連するデータについて、SQL Server は基盤となるオペレーティング システムに依存します。つまり、OS が正しい日付と時刻を報告していれば、SQL Server もその同じ値を報告し、使用します。DST への変更が予定されていますが、この変更に準拠するには、support.microsoft.com/kb/928388 にある概要のとおり Windows® を更新する必要があります。この更新は、DST 変更に準拠するために Windows Vista™ より前のすべての Windows オペレーティング システムで必要です (Vista にはこの変更が既に含まれています)。これには SQL Server を実行しているオペレーティング システムも含まれます (オーストラリアでも変更が発生しています。support.microsoft.com/kb/912475 を参照してください)。

Windows Vista に接続する
質問 - Windows Vista をインストールしたら、自分のシステムにある SQL Server 2005 に接続できません。私はローカル管理者ですが、以前は問題なくこの接続を行うことができました。どうしてでしょうか。
回答 - これは、Service Pack 2 (SP2) が適用されていない SQL Server 2005 と Windows Vista の組み合わせの場合に予期される動作です。Windows Vista には新しいセキュリティ モデルのユーザー アカウント制御が搭載されています。このモデルにより、ローカル管理者グループ内のあなたのメンバシップがトラップされ、管理者権限が必要な操作を確認するダイアログ ボックスが表示されます。[許可] ボタンをクリックすると、あなたの管理者トークンを含む資格情報がアプリケーションに送信されます。SQL Server Management Studio (SSMS) の場合、ダイアログ ボックスは表示されません。ツールを実行するだけであれば管理アクセス許可は必要ないためです。問題は、SQL Server 2005 システム管理者ロールには、オペレーティング システムのローカル管理者グループが既定で含まれていることです。あなたのアカウントでは、過去にこれを使用して SQL Server にアクセスしていたのです。Windows Vista ではこの許可は送信されないため、アクセスが許可されません。
Windows Vista では SP2 を適用していない SQL Server 2005 の実行はサポートされていないこと、また SP2 にはあなたのアカウントを追加するためのツールがあることに注意する必要があります。SP2 をまだインストールしていない場合でも、修正はとても簡単です。あなたの個人用 Windows ユーザー アカウントを SQL Server (あなたの場合はシステム管理者のロール) に追加する必要があります。追加するには、SQL Server Management Studio を右クリックして [管理者として実行] を選択します。SQL Server に接続してあなたの Windows アカウントをシステム管理者のロールに追加します。この設定の動作の詳細については、SQL Server Books Online を参照してください。

ビューを使用したトランザクションのレプリケーション
質問 - 使用している公開ビューを更新すると、トランザクションがレプリケートされることは知っています。このビューのベース テーブルを更新しても、トランザクションはレプリケートされますか。また、使用している公開テーブルのビューを作成してベース テーブルではなくこのビューを更新すると、トランザクションはレプリケートされますか。
回答 - ベース テーブルはパブリケーション内のアーティクルとして構成されている (つまり、ベース テーブルをレプリケーション向けにも構成している) と仮定しますが、ベース テーブルへの更新はすべてレプリケートされます。
ビューのレプリケート時は、既定では、ビューの一部としてレプリケートされるのは、ビューのスキーマ部分またはビューの背後にあるコードのみです。ビューの基になるデータはレプリケートされません (インデックス付きビューを使用していない場合)。したがって、レプリケートを行わなくても、ビューの更新時 (この場合は、ビューをターゲットとしてデータ操作言語 (DML) のステートメントを実行することを指します) はいつでも基になるテーブルのデータを更新しているだけであり、ビューは更新していません。ビューは、物理記憶域を持たないクエリ ステートメントの単なる論理記憶域です (ここでも、インデックス付きビューを使用していない場合)。

最大サーバー メモリ
質問 - 5GB の RAM を搭載し、Windows Server® 2003 と SQL Server 2000 を実行するコンピュータを所有しています。たとえば、/3GB スイッチを使用してユーザー モードの仮想アドレス空間を拡大し、/PAE スイッチで Windows カーネルの物理アドレス拡張 (PAE) バージョンを読み込み、そしてアドレス ウィンドウ化拡張 (AWE) の Enabled を 1 に設定するとします (そして、メモリ内のページのロックを有効にします)。AWE を有効にすると、最大サーバー メモリのオプションでデータ キャッシュのサイズだけが構成されますか。または、すべてのバッファ キャッシュ (データ、プロセス、セッションなど) のサイズが構成されますか。AWE でマッピングしたメモリを利用できるのはデータ キャッシュのみであるため、最大サーバー メモリを 4GB に構成しても、データ キャッシュは 1 GB (AWE によりマッピングされた部分) しか使用しないでしょうか。または、この追加の 1 GB を使用した上で、それ以上のメモリを使用し続けるかまたは標準アドレス空間にある他のメモリ コンシューマすべてと競合しますか。
回答 - 最大サーバー メモリは、常にバッファ プール サイズ全体を制限します。ただし、AWE によりマッピングされたメモリを使用できるのはデータ キャッシュだけです。
そのため最初の質問については、AWE が有効な状態であっても最大サーバー メモリはバッファ プール全体を制限しますが、データ キャッシュを行わないコンシューマが AWE によりマッピングされたメモリを使用することはありません。
2 番目の質問については、データ キャッシュは AWE によりマッピングされたメモリに加えて、SQL Server が適切と判断するバッファ プール内の他のメモリを使用します。つまり、データ キャッシュが使用するのは AWE メモリのみに限られません。ただし、データ キャッシュは AWE メモリを利用できる唯一のコンシューマなのです。/3GB スイッチの機能がわからない場合は、Raymond Chen のブログ (英語) を参照してください。

プロファイリングとパフォーマンス
質問 - SQL Server 2005 を運用環境でミラーリングしています。データベースを実行するマシンで SQL Server Profiler を開始し、トレース データをファイルに書き込むと、パフォーマンスが大幅に低下します。なぜでしょうか。
回答 - パフォーマンス低下の理由は、Profiler をどこで実行しているかによって異なります。Profiler をサーバー マシンで対話的に実行している場合、Profiler の UI がサーバーのメモリと CPU の両方を消費することで、パフォーマンスに影響を与えます。
Profiler をワークステーションで対話的に実行している場合、イベント情報をネットワーク内で移動させていることになり、スループットに影響を与えます。ミラーリングに使用しているネットワークと同じネットワーク内であれば、そのネットワークに対する影響もあります。また、プロファイラの出力をネットワーク共有に保存している場合、データをネットワーク内で移動させていることになり、パフォーマンスに悪影響があります。
これらの影響を軽減する最善の方法は、プロファイル対象のインスタンスを実行するサーバー上で Profiler を非対話的に実行し、出力をローカル ファイルにパイプすることでしょう。それでもサーバー リソースを消費し続けますが、通常この方法が最小の影響で済みます。この方法は、(メモリ内) Profiler トレースよりもうまく機能します。ファイル トレースではシステム メモリがさらに効果的に使用されます。バッファはより大きく、ディスクへのフラッシュもより効果的に行われます。また、ファイル トレースは、SQL Server Profiler のように外部プロセスには依存しません。
最終的には、トレース データは、Profiler がプロファイリングを行っている間にディスク ファイルに書き込まれます。トレース ファイルは、他の人がプロファイル データをリアルタイムにリモートで確認できるようにするため共有されています。トレース ファイルを対話的に呼び出すということは、Profiler を手動で呼び出して画面上の出力を見ていることになります。トレースは画面出力なしでプログラムにより作成できますから、非対話的に実行する方がよいでしょう。
また、ローカル ディレクトリ上に共有を作成すれば、他の人はそこにあるファイルにアクセスできます。これで通常問題ありません。前述のように、トレース出力をリモート共有上のファイルに書き込むのは良くありません。そのファイルがミラーリングに使用されるのと同じネットワーク パイプでアクセスされる場合は特にそうです。
また、調査に必要な最低限のイベントだけを選択する必要があります。トレース ファイルの場所については、システムで最速のドライブを選択してください (SQL Server データベースとトランザクション ログのドライブ以外が良いでしょう)。それでもパフォーマンスが大幅に低下する場合、イベントを複数のトレースに分け、それぞれを別個のハード ドライブに格納します。トレースの格納先が同じハード ドライブであっても、トレースごとに独自のバッファがあるため分割のメリットがあります。詳細については、SQL Server Books Online で sp_trace_create とその関連事項を確認してください。

クラスタリングの問題
質問 - SQL Server を Windows Server 2003 を実行するクラスタにインストールしようとしています。ですが毎回「クラスタ ノードで必要な操作を実行できませんでした。」というメッセージが表示されます。sqlstp.log には、ただ次のように記載されているだけです。
Script file copied to '\\SERVER01\ADMIN$\SERVER01_MSSQLSERVER.iss' successfully.
Installing remote service (SERVER01)...
An error occured in the service create (SERVER01): 1069...
どうしてでしょうか。
回答 - このエラーにはいくつかの理由が考えられます。セットアップでは、Windows NT® サービスが選択されたノードすべてにインストールされ、個々のマシンのセットアップ処理をリモートで管理します。したがって、発生する可能性のある多くの問題について知っておく必要があります。
まず、ドメイン アカウント ユーザーに対し、"サービスとしてログオン" 許可を拒否するグループ ポリシーがある可能性があります (ドメイン ポリシーは、ローカル マシン ポリシーより優先することを思い出してください)。こうした制限のないアカウントを使用していることを確認してください。
次に、セットアップの実行元マシンにログインしているアカウントに、すべてのノードに対する管理者アクセス許可がある必要があります。その理由は、マスタのセットアップ プロセスは、すべてのマシンのレジストリにリモートでアクセスできる必要があるためです。また、セットアップでは cnvsvc.exe をリモート マシンの Windows ディレクトリにコピーします。さらに、リモート マシンにアクセスするためにログイン済みのアカウントのアクセス許可のみを使用する標準 Windows API を使用するため、という理由もあります。これらの理由から、既定ですべてのノードに管理者としてログインする必要があります。

障害時復旧計画
質問 - SAP データベースの障害復旧 (DR) 戦略を実装するため、データベース ミラーリング (非同期モード) またはログ配布の使用を検討しています。運用環境と DR サイトには、100 Mb のミラーリング セッション専用ではないブロードバンド接続を使用します。この接続は、別のミラーリング セッションまたは別の DR サーバーと共有されます。
ログ レコードがミラー データベースに送信されなくなるネットワーク上の問題が発生した場合、再試行は行われますか。
ミラーリング セッションの中断中に、保存期間はありますか。そして、システム ビュー以外に、ミラーリング トラフィックとログ レコード送信の監視に使用できるログ情報はありますか。
回答 - まず質問にお答えします。データベース ミラーリングの再試行ロジックについては、2 つの面から考えることができます。第一に、一時的なネットワークの問題であれば、ミラーリング セッションは切断状態になります。既定のネットワーク タイムアウト値は 10 秒であり、ログ レコードをプリンシパル データベースからミラー データベースに送信できないことになります。このような場合、プリンシパルはミラーリングが行われない状態で実行し続け、トランザクションはクライアント側でコミットされます。ネットワークの問題が解決されると、ミラーリング セッションはユーザーの介入なしで自動的に再試行されます。ミラーリング セッションでは、ログ レコードを使用して遅れを取り戻そうとします。つまり、パートナーがまず同期を取り、遅れを取り戻したら同期状態となります。
第二に、再実行の問題の場合、ミラーリング セッションは中断状態になります。再実行の問題とは、ミラー データベースがそのデータベースのログ レコードをコミットできないことを指します。再実行の問題は、主に物理的ファイルが見つからない、または十分なディスク スペースがないなどで発生します。このような場合、プリンシパルはミラーリングが行われない状態で実行し続け、トランザクションはクライアント側でコミットされます。ミラー サーバー上で再実行の問題を手動で解決すると、ミラー セッションに介入して次のような操作が必要になります。
ALTER DATABASE <db> SET PARTNER RESUME;
保存期間については、回答は次のようになります。ミラー セッションが切断されているか中断されているかに関係なく、ログ レコードはセッションが復元されるまで保持されます。そして、セッションの中断から再開までの間に発生したすべてのレコードがミラーに保存されます。基本的に、ミラーリング セッションの切断中または中断中は、プリンシパルのログの切り捨てはできません。なぜなら切り捨てによりログの再実行チェーンが破壊されてしまうためです。この場合、プリンシパルのログがセッションの復元まで際限なく大きくなります。したがって、事実上ミラーリング セッションでは保存期間の制限がありませんが、現実的な制約は、プリンシパル サーバー上のログ保存用ディスク スペースだけです。というのも、ログが切り捨てられないためです。
最後に、ミラーリングの監視に利用できる特定のログ ファイルはありません。SQL Server 2005 では、データベース ミラーリング モニタという GUI ツールがこの目的で用意されています。このツールを使用すると、システム管理者は状態を表示および更新したり、いくつかの主要なパフォーマンス評価基準の警告しきい値を構成したりできます。これにより、ミラーリングが正常に実行されていない場合にアラートを表示できます。データベース ミラーリングに関するパフォーマンス上の主要な問題は、ログ レコードがタイミングよく処理されるかどうかということです。データベース ミラーリングの監視に関する詳細については、msdn2.microsoft.com/fr-fr/library/ms365781.aspx の記事「ミラーリングの状態の監視」を参照してください。

技術的知識を提供してくれた次の Microsoft IT 技術支援スタッフの皆様に感謝します。Chad Boyd、Sandu Chirica、Alan Doby、Kaloian Manassiev、Luciano Moreira、Ivan Penkov、Sivagaminathan Rajarethinam、Deborah To、Patrick Woodward、Buck Woody、Stanley Yau、Warren Young。


 Cable Guy: DHCPv6 プロトコル
Cable Guy
DHCPv6 プロトコル
Joseph Davies

動的ホスト構成プロトコル (DHCP) は、コンピュータに IP アドレスやその他のネットワーク情報を割り当てて、コンピュータどうしがネットワークを介して自動的に通信できるようにするために開発されたものです。IPv6 ネットワークでは DHCP を使用せずにアドレスを構成できますが、あえて使用する価値は十分にあります。
なぜなら、DHCP for IPv6 (DHCPv6) では、IPv6 ホストのステートフル アドレス構成とステートレス アドレス構成の両方がサポートされるからです。たとえば、次のような方法で IPv6 ホストのアドレス構成を行うことができます。
ステートレス アドレス自動構成 - 近隣ルーターとの間でルーター要請メッセージやルーター アドバタイズ メッセージを交換することにより、リンクローカル アドレスと非リンクローカル アドレスの両方を構成できます。
ステートフル アドレス自動構成 - DHCP などの構成プロトコルを利用して、非リンクローカル アドレスを構成できます。
IPv6 ホストは通常、ステートレス アドレス自動構成を自動的に行います。また、近隣ルーターからのルーター アドバタイズ メッセージに次のフラグが使用されている場合は、DHCPv6 などの構成プロトコルを使用します。
管理されたアドレス構成フラグ。"M フラグ" とも呼びます。1 が設定されている場合、ホストは構成プロトコルを使用してステートフル アドレスを取得します。
その他のステートフル構成フラグ 。"O フラグ" とも呼びます。1 が設定されている場合、ホストは構成プロトコルを使用してその他の構成設定を取得します。
さらに、M フラグと O フラグの値を組み合わせることにより、次のように設定を調整できます。
M フラグの値をゼロ、O フラグの値をゼロに設定。 DHCPv6 インフラストラクチャを持たないネットワークで利用できます。ホストの非リンクローカル アドレスの構成には、ルーター アドバタイズを使用します。アドレス以外の情報の構成には、その他の方法 (手動構成など) を使用します。
M フラグの値を 1、O フラグの値を 1 に設定。 アドレスの構成にもその他の情報の構成にも、DHCPv6 を使用します。このフラグの組み合わせを "ステートフル DHCPv6" と呼びます。"ステートフル DHCPv6" では、DHCPv6 を使用して IPv6 ホストにステートフル アドレスを割り当てます。
M フラグの値を 1、O フラグの値をゼロに設定。 DHCPv6 はアドレス以外の情報の構成専用となり、アドレスの構成には使用されません。近隣ルーターは非リンクローカル アドレスのプレフィックスをアドバタイズするように構成され、IPv6 ホストはこれらのアドレス プレフィックスからステートレス アドレスを取得します。このフラグの組み合わせを "ステートレス DHCPv6" と呼びます。"ステートレス DHCPv6" では、DHCPv6 を使用して IPv6 ホストにステートレスな構成情報を割り当てますが、ステートフル アドレスは割り当てません。
M フラグの値を 0、O フラグの値をゼロに設定。 DHCPv6 はアドレスの構成専用となり、その他の情報の構成には使用されません。通常、IPv6 ホストには、ドメイン ネーム システム (DNS) サーバーの IPv6 アドレスなど、その他の情報も構成する必要があるため、このフラグの組み合わせはほとんど使用しません。
DHCPv6 インフラストラクチャは、DHCP for IPv4 の場合と同様に、構成情報を要求する DHCPv6 クライアント、構成情報を提供する DHCPv6 サーバー、および DHCPv6 リレー エージェントで構成されます。DHCPv6 サーバーと DHCPv6 クライアントが同じサブネット上にない場合は、DHCPv6 リレー エージェントがサーバーとクライアント間のメッセージを中継します。

DHCPv6 メッセージ
DHCPv6 では、DHCP for IPv4 の場合と同様に、ユーザー ダイアグラム プロトコル (UDP) メッセージを使用します。DHCPv6 クライアントは UDP ポート 546 上、DCHPv6 サーバーとリレー エージェントは UDP ポート 547 上で、それぞれ DHCPv6 メッセージをリッスンします。メッセージ構造は、DHCP for IPv4 (ディスクのないワークステーション向けに設計された BOOTP プロトコルの拡張) のときよりずっとシンプルです。図 1 に、クライアントとサーバーがやりとりする DHCPv6 メッセージの構造を示します。
Figure 1 DHCPv6 messages between client and server
Figure 1 DHCPv6 messages between client and server (画像を縮小するには、ここをクリックします)
Figure 1 DHCPv6 messages between client and server
Figure 1 DHCPv6 messages between client and server (画像を拡大するには、ここをクリックします)
1 バイトの Msg-Type フィールドは、DHCPv6 メッセージの種類を示します。3 バイトの Transaction-ID フィールドは、クライアント側で設定されるフィールドで、1 回の DHCPv6 メッセージ交換で交換されるメッセージをグループ化するために使用されます。Transaction-ID フィールドの後ろには、クライアントとサーバーの識別情報、アドレス、その他の構成情報を指定する DHCPv6 オプションが続きます。RFC 3315 で規定されている定義済みの DHCPv6 オプションの一覧は、補足記事「DHCPv6 RFC 参考資料」で確認できます。
DHCPv6 オプションのフォーマットは、type-length-value (TLV) 形式です。図 2 に、DHCPv6 オプションの構造を示します。
2 バイトの Option-Code フィールドは、特定のオプションを示します。2 バイトの Option-Len フィールドは、Option-Data フィールドの長さをバイト数で示します。Option-Data フィールドには、オプションのデータが入ります。
リレー エージェントとサーバー間で交換されるメッセージには、追加情報を記録するためのメッセージ構造が別途用意されています。図 3 に、この種のメッセージの構造を示します。
Figure 2 Structure of DHCPv6 options
Figure 2 Structure of DHCPv6 options (画像を縮小するには、ここをクリックします)
Figure 2 Structure of DHCPv6 options
Figure 2 Structure of DHCPv6 options (画像を拡大するには、ここをクリックします)
1 バイトの Hop-Count フィールドは、メッセージを受信したリレー エージェントの数を示します。リレー エージェントは、受信メッセージ数が最大ホップ数を超えた場合、そのメッセージを破棄できます。16 バイトの Link-Address フィールドには、クライアントのサブネットに接続されたインターフェイスの非リンクローカル アドレスが入ります。サーバーは、この Link-Address フィールドの情報から、アドレスの割り当てに使用する正しいアドレス スコープを把握します。16 バイトの Peer-Address フィールドには、メッセージの発信元クライアントまたは先行してメッセージを中継したリレー エージェントの IPv6 アドレスが入ります。さらに、この Peer-Address フィールドの後ろには、リレー メッセージ オプション (中継されるメッセージとその他のオプションを含む) などの DHCPv6 オプションが続きます。リレー メッセージ オプションでは、クライアントとサーバー間でやりとりされるメッセージをカプセル化できます。
IPv6 用のブロードキャスト アドレスは定義されていません。IPv6 では、DHCPv4 メッセージの制限されたブロードキャスト アドレスの代わりに、All_DHCP_Relay_Agents_and_Servers アドレス (FF02::1:2) を使用します。たとえば、ネットワーク上の DHCPv6 サーバーの場所を確認したい場合、DHCPv6 クライアントはリンクローカル アドレスから FF02::1:2 へ要請 (Solicit) メッセージを送信します。ホストのサブネット上に DHCPv6 サーバーがある場合は、その DHCPv6 サーバーが要請メッセージを受信して適切な応答 (Reply) メッセージを返信しますが、通常はホストのサブネット上の DHCPv6 リレー エージェントが要請メッセージを受信し、DHCPv6 サーバーに転送します。
Figure 3 Structure of messages between relay and server
Figure 3 Structure of messages between relay and server (画像を縮小するには、ここをクリックします)
Figure 3 Structure of messages between relay and server
Figure 3 Structure of messages between relay and server (画像を拡大するには、ここをクリックします)

ステートフル メッセージ交換
DHCPv6 ステートフル メッセージ交換では、受信したルーター アドバタイズ メッセージの M フラグと O フラグの値がどちらも 1 に設定されている場合に、IPv6 アドレスとその他の構成情報を取得できます。このメッセージ交換では、通常、次のメッセージを使用します。
  • 要請 (Solicit) メッセージ。サーバーを検索するため、クライアントから送信されます。
  • アドバタイズ (Advertise) メッセージ。要請メッセージへの応答としてサーバーから送信されます。サーバーがアドレスと構成情報を提供できることを示します。
  • 要求 (Request) メッセージ。特定のサーバーにアドレスまたは構成情報を要求するため、クライアントから送信されます。
  • 応答 (Reply) メッセージ。要求を受け取ったサーバーから送信されます。アドレスと構成情報が含まれています。
クライアントとサーバーの間にリレー エージェントが存在する場合は、リレー エージェントからサーバーに、クライアントから送信された要請メッセージと要求メッセージをカプセル化したものを含むリレー転送メッセージが送信されます。また、サーバーからリレー エージェントに、クライアント宛てのカプセル化されたアドバタイズ メッセージと応答メッセージを含むリレー応答メッセージが送信されます。すべての DHCPv6 メッセージの一覧は、図 4 を参照してください。
Figure 4 DHCPv6 メッセージ (Close Figure 4)

DHCPv6 メッセージ | 説明 | 対応する DHCP for IPv4 メッセージ
要請 (Solicit) | サーバーを検索するため、クライアントから送信されます。 | DHCPDiscover
アドバタイズ (Advertise) | 要請メッセージへの応答としてサーバーから送信されます。サーバーの可用性を示します。 | DHCPOffer
要求 (Request) | 特定のサーバーにアドレスまたは構成情報を要求するため、クライアントから送信されます。 | DHCPRequest
確認 (Confirm) | クライアントの構成が接続リンクで有効であるかどうかを確認するため、クライアントから全サーバーに送信されます。 | DHCPRequest
更新 (Renew) | 割り当てられたアドレスの有効期間を延長し、更新された構成情報を取得するために、クライアントから特定のサーバーに送信されます。 | DHCPRequest
再バインド (Rebind) | 更新メッセージへの応答がなかったときに、クライアントから任意のサーバーに送信されます。 | DHCPRequest
応答 (Reply) | 要請メッセージ、要求メッセージ、更新メッセージ、再バインド メッセージ、情報要求メッセージ、確認メッセージ、リリース メッセージ、または拒否メッセージへの応答として、サーバーから特定のクライアントに送信されます。 | DHCPAck
リリース (Release) | クライアントが割り当てられたアドレスをもう使用していないことを示すため、クライアントから送信されます。 | DHCPRelease
拒否 (Decline) | 割り当てられたアドレスが使用中であることを示すため、クライアントから特定のサーバーに送信されます。 | DHCPDecline
再構成 (Reconfigure) | サーバーの構成情報が追加または更新されたことを示すため、サーバーからクライアントに送信されます。クライアントは、このメッセージへの応答として、更新メッセージまたは情報要求メッセージを返信します。 | なし
情報要求 (Information-Request) | アドレス以外の構成情報を要求するため、クライアントから送信されます。 | DHCPInform
リレー転送 (Relay-Forward) | メッセージをサーバーに転送するため、リレー エージェントから送信されます。リレー転送メッセージには、DHCPv6 リレーメッセージ オプションとしてカプセル化されたクライアント メッセージが含まれています。 | なし
リレー応答 (Relay-Reply) | リレー エージェント経由でクライアントにメッセージを送信するため、サーバーから送信されます。リレー応答メッセージには、DHCPv6 リレーメッセージ オプションとしてカプセル化されたサーバー メッセージが含まれています。 | なし

ステートレス メッセージ交換
DHCPv6 ステートレス メッセージ交換では、受信したルーター アドバタイズ メッセージの M フラグの値がゼロ、O フラグの値が 1 に設定されている場合に、構成情報だけを取得できます。このメッセージ交換では、通常、情報要求 (Information-Request) メッセージと応答 (Reply) メッセージを使用します。情報要求メッセージはサーバーに構成情報を要求するメッセージで、DHCPv6 クライアントから送信されます。応答メッセージは要求された構成情報を含むメッセージで、サーバーから送信されます。
IPv6 ネットワーク上に、IPv6 ホストにアドレス プレフィックスを割り当てるルーターが構成されている場合は、2 つの DHCPv6 メッセージを交換することにより、DNS サーバーと DNS ドメイン名の割り当て、およびルーター アドバタイズ メッセージには含まれていないその他の構成情報の割り当てを実行できます。

Windows の DHCPv6 サポート
Windows Vista™ と Windows Server® の後継バージョン (コードネーム "Longhorn") には、DHCPv6 クライアントが付属しています。この DHCPv6 クライアントは、受信したルーター アドバタイズ メッセージに含まれる M フラグと O フラグの値に応じて、DHCPv6 ベースの構成を行います。したがって、DHCPv6 を使用するためには、IPv6 サブネットごとに DHCPv6 サーバーとリレー エージェントを構成し、さらに IPv6 ルーターを構成して、M フラグと O フラグの値を適切に設定する必要があります。単一のサブネット上にアドバタイズ ルーターが複数存在する場合は、これらのルーターからアドバタイズされるステートレス アドレス プレフィックスと M フラグおよび O フラグの値が一致するようにルーターを構成します。一方、Windows® XP や Windows Server 2003 を実行している IPv6 ホストには DHCPv6 クライアントが付属していません。したがって、ルーター アドバタイズ メッセージの M フラグと O フラグの値を気にする必要はありません。
Windows Vista や Windows Server の後継バージョン ("Longhorn") を実行する IPv6 ルーターからアドバタイズされるメッセージの M フラグの値を 1 に設定するには、"netsh interface ipv6 set interface InterfaceName managedaddress=enabled" コマンドを実行します。同様に、ルーター アドバタイズ メッセージの O フラグの値を 1 に設定するには、"netsh interface ipv6 set interface InterfaceName otherstateful=enable" コマンドを実行します。
Beta 2 リリースの Windows Server "Longhorn" は、DHCP Server サービスを利用して、DHCPv6 リレー エージェントと DHCPv6 ステートレス構成をサポートします。DHCP Server サービスの構成により、先ほど説明した 2 つの DHCPv6 メッセージを交換する方式で、すべての DHCPv6 クライアントに DHCPv6 オプションを配布することができます。Beta 3 リリースの Windows Server "Longhorn" では、DHCP スナップインで IPv6 のアドレス スコープを作成する機能など、DHCPv6 ステートフル処理のサポートが追加される予定です。
DHCPv6 RFC 参考資料
DHCPv6 関連の主要 RFC
  • RFC 3315、IPv6 のための動的ホスト構成プロトコル (DHCPv6)
  • RFC 2462、IPv6 ステートレス アドレス自動構成
  • RFC 3633、DHCP バージョン 6 の IPv6 プレフィックス オプション
  • RFC 3646、DHCPv6 の DNS 構成オプション
  • RFC 3736、IPv6 のステートレス DHCP サービス

Joseph Daviesマイクロソフトのテクニカル ライターとして Windows ネットワークのトピックに関する講義および執筆を 1992 年から行っています。Microsoft Press から 5 冊の書籍を上梓しており、月間の TechNet Cable Guy コラムの執筆者でもあります。


 Windows Powershell: 変数の機能
Windows Powershell
変数の機能
Don Jones

VBScript や KiXtart などの Windows ベースのスクリプト言語を使用している方は、データ記憶の 1 手段として変数に慣れていることでしょう。Windows PowerShell にも変数がありますが、従来のスクリプト言語の変数よりもはるかに強力です。Windows
PowerShell の変数は、実際には基盤となる Microsoft® .NET Framework のクラスにマッピングされています。Framework では、変数はオブジェクトです。つまり、変数にデータを格納して、そのデータをさまざまな方法で操作することもできます。実際、Windows PowerShell™ スクリプト言語に組み込みのデータ操作関数がないのは、Windows PowerShell の変数が強力な機能を持っているためなのです。変数自体に機能が備わっているので、そのような関数は必要ないのです。

変数を宣言する
Windows PowerShell の New-Variable コマンドレットを使用して変数を宣言し、初期値を割り当てることもできますが、必ずしもコマンドレットを使用する必要はありません。代わりに、次のように変数に値を割り当てるだけで、新しい変数をすぐに作成できます。
$var = "Hello"

Windows PowerShell では、変数名は必ずドル記号 ($) で始まり、文字、数字、記号、およびスペースを組み合わせて指定できます。スペースを使用する場合は、変数を ${My Variable} = "Hello" のように中かっこで囲む必要があります。この例では、$var という名前の新しい変数を作成し、その変数に初期値 "Hello" を割り当てています。この場合は、値が文字列なので、Windows PowerShell は String データ型を使用して値を格納します。.NET Framework の用語では、これは System.String クラスです。このクラスには、おそらくどの種類の変数よりも多くの機能が組み込まれています。たとえば、$var の値をすべて小文字で表示するには、次のように記述できます。
PS C:\> $var.ToLower()
hello
PS C:\>
ToLower メソッドは System.String クラスに組み込まれており、文字列の値をすべて小文字で出力します。ただし、この場合、変数 $var の実際の内容は変わりません。System.String クラスのすべての機能を確認するには、次のように、パイプを使用して文字列変数を Get-Member コマンドレットに渡します。
$var | get-member
図 1 に示す出力を見ると、文字列の操作に使用される数十個のメソッドを確認できます。VBScript の文字列操作関数が提供するほとんどすべての機能は、Windows PowerShell では文字列変数のメソッドによって提供されます。
Figure 1 A look at the System.String class output
Figure 1 A look at the System.String class output (画像を縮小するには、ここをクリックします)
Figure 1 A look at the System.String class output
Figure 1 A look at the System.String class output (画像を拡大するには、ここをクリックします)

管理コンテキストでは、多くの場合、VBScript のような言語の文字列関数よりも、文字列変数の機能を使用した方が便利です。たとえば、ファイルから UNC (汎用名前付け規則) パスを読み取って、何らかの処理を行うスクリプトを作成したとします。読み取ったパスを実際に使用する前に、そのパスが UNC であることを確認する必要がある場合は、StartsWith メソッドを使用します。このメソッドにより、文字列の先頭が UNC に必要な円記号であるかどうかを確認できます。
PS C:\> $path = "\\Server\Share"
PS C:\> $path.StartsWith("\\")
True
PS C:\>
StartsWith は True または False を返すので、論理コンストラクトで使用できます。
if ($path.StartsWith("\\")) {
 # code goes here
}
Windows PowerShell は、変数のメソッドのオートコンプリート機能も備えているため、タイプ入力の手間が省けます。$var に文字列が格納されている場合は、次のように入力し
$var.
Tab キーを押すと、$var 変数の最初のメソッド名がポップアップ表示されます。再度 Tab キーを押すと次のメソッドが表示され、Shift キーを押しながら Tab キーを押すと前のメソッドが表示されます。このように操作して、必要なメソッドが見つかるまで使用可能なすべてのメソッドを表示することができます。

変数の混同
これまでの例では、変数のデータ型を Windows PowerShell が判別可能でした。変数に文字列を割り当てると、変数は本質的に System.String 型となります。一方、変数に数値を割り当てた場合は、通常、変数は Integer 型 (より詳しくは、特定の範囲の値を格納できる Int32 型) となります。たとえば、次の例について考えてみましょう。
PS C:\> $int = 5
PS C:\> $int | get-member

  TypeName: System.Int32
この出力例 (一部省略) は、Windows PowerShell が $int を独自のメソッドとプロパティのセットを持つ Int32 型として扱っていることを示しています。そして実のところ、Int32 型のメソッドとプロパティは、String 型よりもはるかに少ないのです。
$int が Int32 型と判別されたのは、値が引用符で囲まれておらず、さらに数字だけで構成されていたからです。引用符で囲まれていたならば、System.String 型と解釈されます。
使用するデータ型の決定を Windows PowerShell に委ねると、期待した結果にならないことがあります。たとえば、ファイルから値を読み取り、それらの値を常に文字列として扱う必要があるとします。しかし、一部の値には数字しか含まれていないため、Windows PowerShell によって Int32 型または別の数値型として扱われる可能性があります。そのことが原因で、スクリプトで問題が生じることがあります。Windows PowerShell によって値が文字列と認識されない場合は、System.String クラスのすべてのメソッドを使用できませんが、スクリプトでこれらの使用できないメソッドのいずれかを利用している可能性があるためです。
このような問題を回避するには、最初に変数を使用するときに特定の型を宣言して、強制的に Windows PowerShell が変数をその型として扱うようにできます。次に例を示します。
[string]$var = 5
通常であれば、$var は Int32 型と解釈されますが、ここでは Windows PowerShell に $var を String 型として扱うように強制しています。これにより、System.String クラスに関連付けられているすべてのメソッドを使用できるようになります。変数の型を宣言することで、$var のデータ型が明確になるため、コードの簡単な自己文書化としても役立ちます。実際、私は常にすべての変数について特定の型を宣言する習慣が付いているので、Windows PowerShell から完全に決定権を取り上げてしまっています。このため、スクリプトの動作が予測しやすく、デバッグの時間を大幅に節約できています。
お察しのとおり、強制的に変数を宣言することで、さまざまな影響が生じます。ただし、必ずしも悪影響とは限りません。変数の型を宣言していない次の例について考えてみましょう。
PS C:\> $me = 5
PS C:\> $me = "Don"
$me 変数は、最初は Int32 型でしたが、値 "Don" が追加されたときに Windows PowerShell によって String 型に変更されました。Windows PowerShell では、変数が明示的に特定の型に設定されていなければ、必要に応じて変数の型が変更されます。
次の例では、[int] という型名を使用して $me を強制的に Int32 型として宣言しています。
PS C:\> [int]$me = 5
PS C:\> $me = "Don"
Cannot convert value "Don" to type
"System.Int32". Error: "Input string
was not in a correct format."
At line:1 char:4
+ $me <<<< = "Don"
そのため、この変数に文字列を割り当てようとしたときに、エラー メッセージが表示されました。$me が明示的に Int32 型として宣言されているため、Windows PowerShell は文字列 "Don" を整数値に変換しようとしました。これは不可能であり、$me の型を String 型に変更することもできませんでした。

多数の型
Windows PowerShell では、多数の型を使用できます。実際には、.NET Framework のすべての型を使用できます。したがって、使用可能な型は何百種類にもなります。ただし、Windows PowerShell では、よく使用されるデータ型のショートカットがいくつか定義されています。図 2 は、データ型のショートカットの一部について、最もよく使用される 10 種類を示しています。完全な一覧については、Windows PowerShell のドキュメントを参照してください。
Figure 2 よく使用される型のショートカット (Close Figure 2)

ショートカット | データ型
[datetime] | 日付または時刻
[string] | 文字列
[char] | 1 文字
[double] | 倍精度浮動小数点数
[single] | 単精度浮動小数点数
[int] | 32 ビット整数
[wmi] | Windows Management Instrumentation (WMI) インスタンスまたはコレクション
[adsi] | Active Directory サービス オブジェクト
[wmiclass] | WMI クラス
[Boolean] | True または False
次のように、.NET Framework の完全なクラス名を使用して変数の型を宣言することもできます。
[System.Int32]$int = 5
この方法により、Windows PowerShell に特定のショートカットがない .NET Framework の型を使用することができます。

型を拡張する
Windows PowerShell の最も便利な機能は、おそらくこれらの変数型の機能を拡張できることでしょう。Windows PowerShell のインストール フォルダ (通常は %systemroot\system32\windowspowershell\v1.0 ですが、64 ビット システムではパスが少し異なります) に、types.ps1xml というファイルがあります。このファイルは、メモ帳や、PrimalScript などの XML エディタで編集できます。既定では、System.String クラスは記載されていませんが、他の多くの型が記載されています。ただし、types.ps1xml ファイルに System.String 型を追加すれば、この型に新しい機能を追加できます。
ファイルを変更したら、Windows PowerShell を閉じて、再度開く必要があります。また、types.ps1xml は署名されていないので、次のようにローカル スクリプト実行ポリシーで未署名のスクリプトの実行を許可する必要があります。
Set-executionpolicy remotesigned
これで、Windows PowerShell を再起動したら、次のように新しい機能を使用できます。
PS C:\> [string]$comp = "localhost"
PS C:\> $comp.canping
True
PS C:\>
ご覧のとおり、私は CanPing プロパティを System.String クラスに追加しました。このプロパティは、True または False を返して、文字列に含まれているアドレスにローカル コンピュータが ping を実行できるかどうかを示します。図 3 では、WMI クエリで特殊な変数 $this が使用されているのがわかります。$this 変数は文字列に含まれている現在の値を表しており、これを使用して文字列変数の内容を WMI クエリに渡しています。
Figure 3 System.String 型の拡張 (Close Figure 3)
<Type>
  <Name>System.String</Name>
  <Members>
    <ScriptProperty>
      <Name>CanPing</Name>
      <GetScriptBlock>
      $wmi = get-wmiobject -query "SELECT *
FROM Win32_PingStatus WHERE Address = '$this'"
      if ($wmi.StatusCode -eq 0) {
        $true
      } else {
        $false
      }
      </GetScriptBlock>
    </ScriptProperty>
  </Members>
</Type>

変数に処理を行わせる
Windows PowerShell には、柔軟性の高い機能豊富な変数型と、型の機能を拡張するための同様に柔軟性の高いシステムが用意されています。これらの機能を使用すると、スクリプトに多くの機能を簡単に組み込むことができます。実際、変数は複雑なスクリプトにおいては主要な構成要素となり、多くの場合、より複雑な関数に通常見られるような、高度な機能を備えています。
オンラインで学習する
毎月第 3 または第 4 火曜日に開催される一連の Web キャスト (英語) に参加してください。Windows PowerShell の豊富なスクリプト機能について詳しく説明します。microsoft.com/events/series/donjonesscripting.mspx (英語) にアクセスして、今すぐサインアップしてください。

2007 年 2 月 20 日 Windows PowerShell: The Scripting Crash Course (スクリプトに関する短期集中コース)
この Web キャスト (英語) では、Windows PowerShell の変数、言語コンストラクト、スクリプト、および関数について学習します。1 時間の短期集中コースで、Windows PowerShell の簡単かつ有効なスクリプト言語によって Windows® 管理の自動化を迅速に行う方法を示します。Windows PowerShell のスクリプト作成を可能な限り簡易化するサードパーティ製のツールもいくつか紹介します。

2007 年 3 月 20 日 Windows PowerShell: Functions, Filters, and Efficiency (関数、フィルタ、および効率)
Windows PowerShell の関数とフィルタにおいて、効率的なモジュール化されたコードを作成する方法を学習します。関数とフィルタを完全にカプセル化するための Windows PowerShell の強力なスコープ規則と、これらの関数とフィルタをプロジェクトで簡単に再利用する方法を説明します。また、Windows PowerShell のグローバル スコープに独自のカスタム関数を追加して、便利なユーティリティ関数のライブラリを簡単に構成できることを示します。

2007 年 4 月 17 日 Windows PowerShell and Windows Management Instrumentation (Windows PowerShell および Windows Management Instrumentation)
Windows PowerShell では、Windows Management Instrumentation (WMI) のすべての機能にアクセスできます。この Web キャスト (英語) では、Windows PowerShell を使用して WMI にアクセスする方法と、Windows PowerShell パイプラインを使用して WMI のオブジェクトおよびコレクションを渡す方法について説明します。Windows PowerShell スクリプトで WMI のプロパティとメソッドを利用する方法や、基礎となる WMI のセキュリティと構成機能についても説明します。

2007 年 5 月 22 日 Windows PowerShell: Converting from VBScript (VBScript からの変換)
スクリプトを (またはあなたのスキルを) VBScript から Windows PowerShell に変換したい方はいますか。この Web キャスト (英語) に参加すれば、その方法がわかります。Windows PowerShell に VBScript の主要なコンストラクトと機能のすべてがどのように組み込まれているかを示し、あなたの VBScript スキルをこの新しい管理環境に簡単に移行できることを説明します。また、VBScript のツールを Windows PowerShell のネイティブのスクリプト言語に変換する方法も示します。また、Windows PowerShell 独自の構造と、作業をより効率的かつ効果的に行えるように Windows PowerShell スクリプト言語を使用する方法についても説明します。

2007 年 6 月 19 日 Windows PowerShell: Under-the-Hood Extensions (内部の拡張機能)
この Web キャスト (英語) では、Windows PowerShell が強力かつ柔軟性のある .NET Framework をどのように使用してデータを処理しているかについて説明し、文字列、日付、およびその他のデータ型を管理するための数百もの組み込み関数が提供されていることを示します。ところで、これらの機能を Windows PowerShell スクリプトでは拡張できることをご存知でしたでしょうか。コンピュータ名を含むだけでなく、そのコンピュータが稼働中であるかどうかを知らせる文字列変数の作成方法を示します。また、外部関数を使用しないでデータの書式を自動的に設定できる日付型と時刻型の変数の作成方法を学習します。このセッションに参加して、あらゆる新機能をわずか数分で Windows PowerShell に組み込んで、Windows の管理をより迅速かつ簡単にする方法を確認してください。

Don Jones は SAPIEN Technologies のプロジェクトおよびサービスの責任者であり、『Windows PowerShell: TFM』(SAPIEN Press) の共著者でもあります。Don の連絡先については、www.ScriptingAnswers.com (英語) を参照してください。


 Hey, Scripting Guy!: わずか 5 セントで OU に関する質問に回答する
Hey, Scripting Guy!
わずか 5 セントで OU に関する質問に回答する
Microsoft Scripting Guys
この記事で使用しているコードのダウンロード: HeyScriptingGuy2007_03.exe (151KB)

質問 - Active Directory から OU を選択するダイアログ ボックスを表示する方法はありますか。

ご存じでしょうが、この質問を受けるたびに Scripting Guys が 5 セントずつ受け取っていたとしたら、ええと、そうですね、実際には $37.15 にしかならないですね。しかし、時間がなくてまだ質問していないが、この質問をしたいと思っているすべてのユーザーから 5 セントずつ受け取ったとしたら、ええと、まあ、金額なんてどうでもいいです。なぜなら、私たちはお金のために Scripting Guys になったわけではありませんから。Scripting Guys になったのは、ユーザーがシステム管理タスクをより速く、より簡単に実行できるようになるという満足感のためです。
注: 厳密に言えば、収入を得るために Scripting Guys になりました。でも上司が言いました。「君たちが業績を上げてかなりの収入を得ることは可能だが、それは一生懸命働いて高品質のものだけを生産しようという強い意志があって初めて可能になる。」この言葉を聞いたときから、お金がすべてではないと思うようになりました。
それはどうでもいいことです。問題は、OU を選択し、その延長線上で、スクリプトを使用してその OU に接続できるようなダイアログ ボックスを表示する方法を多くのユーザーが知りたいと思っていることです。最近、次のような電子メールを受け取りました。「以前に、フォルダを選択するダイアログ ボックスを表示する方法を説明していただきました。また、ファイルを選択するダイアログ ボックスについても記事が掲載されています。しかし、Active Directory® から OU を選択するダイアログ ボックスの表示方法に関する記事がないのはなぜですか。」
はい、たしかに、フォルダを選択するダイアログ ボックスを表示する方法について説明しました。この例については、こちら を参照してください。また、ファイルを選択するダイアログ ボックスの表示方法については、http://www.microsoft.com/japan/technet/scriptcenter/resources/qanda/jan05/hey0128.mspx にアクセスしてご確認ください。これらの記事は非常に好評で、このテクニックがユーザーのスクリプトで利用されていることを知っています。Active Directory から OU を選択できるようなダイアログ ボックスの表示方法に関する記事がないのはなぜでしょうか。これはマイクロソフトの陰謀か何かでしょうか。
もちろんそうではありません (ちょっと待ってください。陰謀にかかわっている人は必ずこう言いますよね)。実のところ、Active Directory から OU を選択するダイアログ ボックスの表示方法を説明していないことには、正当な理由があります。それは、そのようなダイアログ ボックスが存在しないからです。野球では、「見えないものは打てない」とよく言います。同様に、スクリプトでは、「存在しないものは表示できない」と言います。
さて、今月のコラムはこれで終わりです。またお会いしましょう。
そうは問屋が卸しません。TechNet Magazine の編集者によると、これで終わりではないそうです。編集者は次のように言いました。「そのようなダイアログ ボックスが存在しないと、何か問題でもあるのですか。あなたたちは Scripting Guys でしょうが。何とかして ダイアログ ボックスを作成できないのですか。スクリプトに関しては何でもできると思っていたのに。」
言うまでもありませんが、TechNet Magazine の編集者は大きな思い違いをしています。スクリプトに関しては何でもできる? 必ずしもそうではありません。実際、スクリプトに関して Scripting Guys にできることは 1 つだけです。
幸い、私たちにできることは、唯一、Active Directory から OU を選択するダイアログ ボックスを作成することです。図 1 をご覧ください。
はい、どちらかと言えば長いスクリプトですね。しかし、よく言われるように、卵を割らずにオムレツは作れません。同様に、卵を割らずにカスタム ダイアログ ボックスは作成できません (このコラムの途中でおなかがすいたので、中断して軽食を取りました)。さて、食欲が満たされたので、このスクリプトの動作を説明できるかどうかやってみましょう。
このスクリプトでは、Internet Explorer® オブジェクト モデルを使用して擬似ダイアログ ボックスを作成します。Internet Explorer のインスタンスを作成し、Active Directory から OU のコレクションを取得し、Internet Explorer ウィンドウのリスト ボックスに取得した OU を表示します。ユーザーが OU を選択するまで待ち、選択したら、その項目の ADsPath を取得し、ダイアログ ボックスを閉じ、処理を継続します。
注: これは装飾された非常に美しいダイアログ ボックスになりますか。はい、[OK] ボタンも [Cancel] ボタンもなく、必要最小限の機能だけを備えたものを "装飾された非常に美しい" ダイアログ ボックスと呼ぶのであればそうなります。弁解になりますが、この例の目的は、基本的な枠組みを示すことです。ダイアログ ボックスを装飾したり変更したりする場合は、自力でお試しください。
(「自力でお試しください」と言うたびに 5 セントずつ受け取っていたら、ほんとうに "金持ち" になっていたでしょう。寄付の送り先は、TechNet Magazine の The Scripting Guys です。)
技術的な説明を与えられたスペースに収めるには、一部の項目を飛ばすしかありません。たとえば、次のコード ブロックについて説明できることは、幅が 350 ピクセル、高さが 400 ピクセルの Internet Explorer インスタンスを作成し、その際に、アドレス バーやステータス バーなどを非表示にすることだけです。
Set objExplorer = CreateObject( _
    "InternetExplorer.Application")

objExplorer.Navigate "about:blank"
objExplorer.ToolBar = 0
objExplorer.StatusBar = 0
objExplorer.Width= 350
objExplorer.Height = 400
objExplorer.Left = 400
objExplorer.Top = 400
objExplorer.Visible = 1
もちろん、上記のコードでは、空白の Internet Explorer ウィンドウが作成されるだけです。ドメイン内の OU の一覧を取得するには、Active Directory を検索する必要があります。今日は Active Directory の検索について詳しく説明することはできません。詳細については、Script Center の 2 部構成シリーズ (microsoft.com/japan/technet/community/columns/scripts/sg0405.mspx) を参照してください。ここでは簡単に、次のコードが fabrikam.com ドメイン内の各 OU の Name と ADsPath を取得するためのコードであると説明しておきます。
objCommand.CommandText = _
    "SELECT Name, ADsPath FROM 'LDAP://DC=fabrikam,DC=com' WHERE objectCategory=
    'organizationalUnit' ORDER BY Name"
また、見やすくするために、OU の名前をアルファベット順に並べ替えました。このために ORDER BY Name 句を追加しました。(お安いご用です。これが私の務めですから。)
Execute メソッドを呼び出すと、fabrikam.com 内のすべての OU から成るレコードセットが返されます。したがって、次のステップは、これらの OU をリスト ボックスに表示することです。
では、どのような方法で表示するのでしょう。まず最初に、メモリ内にリスト ボックス全体を構築する必要があります。初心者のために説明しますが、それは次のコードを使用して、<SELECT> タグを strHTML という変数に格納することです。
strHTML = "<select size = '20' name='OUList' style='width:300px'>"
このコードでは、どのような操作を行っていますか。通常の HTML リスト ボックスを作成しているだけです (これには <SELECT> タグを使用します)。その際に、このリスト ボックスに OUList という名前を付け、一度に 20 項目が表示されるように構成し、幅を 300 ピクセル (300px) に設定します。HTML について少しでもご存知な方でしたら、上記のコードは見慣れていると思います。
次に、いくつかの項目 (つまり、OU) をリスト ボックスに追加する必要があります。偶然にも、レコードセットは、ドメイン内の各 OU に関する情報で構成されています。そのため、レコードセット全体をループする Do Until ループをセットアップすれば、情報を取得し、各 OU をリスト ボックスに追加できます。このループ内で、次のコード (リスト ボックスに項目を追加するための標準の HTML) を使用して各 OU を追加し、OU の Name が一覧に表示されるように項目を構成します。また、リスト ボックス内の OU をクリックしたとき、スクリプトに ADsPath が渡されるようにします。
strHTML = strHTML & "<option value= " & _
    Chr(34) & objRecordSet.Fields
    ("AdsPath").Value & Chr(34)
strHTML = strHTML & ">" & objRecordSet.
    Fields("Name").Value
スクリプトに ADsPath を渡すのはなぜですか。それは簡単です。ADsPath ではなく、OU の Name を渡した場合を考えてみましょう。たとえば、Name が Finance であった場合、この OU にバインドするのは困難です。何しろ、"Finance" だけでは有効な ADSI バインド文字列にはなりませんから。一方、ADsPath (LDAP://ou=Finance,dc=fabrikam,dc=com) が返された場合、バインドは非常に簡単です。なぜなら、ADsPath は、Active Directory 内のオブジェクトを検索および接続するのにまさに必要なものだからです。
ところで、リスト ボックスに Name を表示するのは、OU の名前が一意であると仮定しているからです。しかし、そうでない場合もあります。たとえば、North America\Research と Europe\Research という OU では、名前 (Research) が同じです。OU の名前が重複している場合は、ADsPath や distinguishedName など、別のプロパティをリスト ボックスで使用することをお勧めします。しかし、これは自分で判断しなければならないことです (カシャーン。また 5 セントが発生しました)。
ところで、このリスト ボックスはメモリ内に作成されている点に注意してください。つまり、ボックスに追加された各項目は、変数 strHTML に追加されたことになります。これはすべて計画どおりです。リスト ボックスのコード全体を変数 strHTML に保存してから、この変数の値を使用して Internet Explorer のインスタンスにリスト ボックスを実際に追加します。
すべての OU を追加したら、次のコードを使用してリスト ボックスの終わりであることを示します。
strHTML = strHTML & "</select>"
この時点で、strHTML には、リスト ボックスの作成に必要なすべての HTML タグが含まれています。また、何よりも良いことに、リスト ボックス内の各項目は、Active Directory 内の 1 つの OU を表しています。したがって、strHTML の値を Internet Explorer ドキュメントの InnerHTML プロパティに割り当てることができます。
objExplorer.Document.Body.InnerHTML = strHTML
これでドメイン内のすべての OU を表示するリスト ボックスができました。
待ってください。まだ完全に終わってはいません。そのままお待ちください。たとえば、ダイアログ ボックスの OU をユーザーが選択するまで、スクリプトを停止するためのコードが必要です。リスト ボックスが表示されても、このコードなしでは、ユーザーが選択したかどうかにかかわらず、スクリプトは処理を続行します。これは大変ですね。このシナリオが発生しないように、次のコード ブロックを使用します。
Do While objExplorer.Document.Body.All.OUList.Value = ""
    Wscript.Sleep 300
Loop
このコード ブロックでは、リスト ボックスの Value を繰り返し確認しています (このリスト ボックスの名前は OUList ですが、これは Scripting Guys の 1 人が自分の娘に付けた名前と同じです)。Value が空の文字列である (つまり、項目が選択されていない) 場合、スクリプトを 300 ミリ秒だけ一時停止した後、ループ処理を行い、再び確認します。この操作は、a) 永久に続くか、b) ユーザーがリスト ボックスの項目を選択するまで、または c) ユーザーが Internet Explorer ウィンドウを閉じるまで続きます。
ユーザーがリスト ボックスの OU を選択したとします。この場合は、Value (つまり、OU の ADsPath) を取得し、strTargetOU という変数に割り当てます。
strTargetOU = objExplorer.Document.Body.All.OUList.Value
次に、Quit メソッドを使用して Internet Explorer のインスタンスを終了します (次のコードを参照)。
objExplorer.Quit
これで、もうすぐ終わりです。まず、strTargetOU が空の文字列に等しいかどうかを確認します。
If strTargetOU = "" Then
    Wscript.Quit
End If
空であれば、ユーザーが OU を選択せずに Internet Explorer を閉じたことを表しています。この場合は、Wscript.Quit メソッドを使用してスクリプトを終了します (ここでは、ユーザーが OU を選択しなかった場合、ユーザーはスクリプトを実行することにあまり関心がなかったものと仮定します)。ただし、strTargetOU が空の文字列と等しくない場合は、変数の値をエコー バックします。
Wscript.Echo strTargetOU
もちろん、実際のスクリプトでは、ADsPath をエコー バックするだけでなく、Active Directory の該当する OU にバインドすることになるでしょう。しかし、よく言われるように (少なくとも、Scripting Guys の間ではよく言われます)、これは自力でお試しください。
前に説明したとおり、または、図 2 を見ておわかりのとおり、それほど美しいダイアログ ボックスではありませんが、これで十分です。また、ADsPath を入力することに比べて (ADsPath がわかっていると仮定した場合)、かなり簡単です。さらに、コードとダイアログ ボックスをニーズに合わせてカスタマイズできます。
Figure 2 A simple script dialog
Figure 2 A simple script dialog

これで、あと、Active Directory から OU を選択するダイアログ ボックスの表示についてコラムを記述するごとに 5 セントずつ受け取ることができればいいのですが。そうすれば、通常の TechNet Magazine の収入よりも 5 セントだけ増えますから。
念のために言っておきますが、文句を言っているわけではないのです。

Microsoft Scripting Guys はマイクロソフトの仕事をしています、というよりもマイクロソフトに雇われています。野球をプレイしたり監督したり観戦したり (または他のさまざまな活動を) しているのでない限り、彼らは TechNet Script Center を運営しています。詳細については、http://www.microsoft.com/japan/technet/scriptcenter/default.mspx を参照してください。


 Exchange Queue &amp; A: トランザクション ログ、コマンドレット、リモート管理など
Exchange Queue & A
トランザクション ログ、コマンドレット、リモート管理など
KC Lemson and Nino Bilic

質問 - Microsoft® Exchange Server 2007 でトランザクション ログのサイズを 1 MB に縮小したのはなぜですか。
Exchange 2007 にはログ配布と呼ばれる優れた機能があります。この機能は、ローカル連続レプリケーション (LCR)、クラスタ連続レプリケーション (CCR) などの新機能を背後で支えるテクノロジです。ログ配布をストレージ グループ (SG) レベルで有効にすると、実行中の実稼動 SG からコピー SG に SG トランザクション ログがコピーされます。コピー SG のログを再生してデータベースに戻すことでデータベースを最新の状態に維持します。ここでは説明を簡素化して概要を伝えています。
問題は、トランザクション ログをコピー SG に送信するには、実稼動 SG 上のログを閉じなければならないということです。つまり、最初のストレージ グループの現在のログである e00 ログを送信するには、このログがいっぱいになるか、このログを閉じるか、名前を変更する必要があります。また、可用性とパフォーマンスはトレードオフの関係にあるので、このプロセスで使用可能なログの数を制御するための設定が用意されています。これらの設定を行うには、Exchange 管理シェルで Set-MailboxServer コマンドレットを実行します。必要なパラメータの詳細については、ヘルプ ファイルを参照してください。
簡単に言えば、トランザクション ログのサイズを縮小したのは、ストレージ グループの 2 つのコピー間で非同期になるデータの量を少なくするためです。これは、実稼動データベースのハード ドライブがクラッシュして、コピーから SG を起動する必要がある場合などに有効です。トランザクション ログのサイズが小さいほど、データが消失する可能性も少なくなります。
とはいえ、データの消失が 1 MB を超えないと保証することはできません。失われた 1 MB のログ ファイルの中には、トランザクション ログのように見えても、たとえば 5 MB のデータに対する COMMIT トランザクションが含まれている可能性があります。この場合、コピー上ではこれらの 5 MB のデータは失われます。データが記録された 5 つのログを取得できたとしても、最後のログに存在するのはデータの一部のみで、これらのデータに必要な COMMIT トランザクションが欠けています。
最終的には、ビジネス要件から考えて、このリスクが許容範囲であるかどうかは各自の判断に委ねられます。復旧作業に何時間もかかる場合と比べたら、ものの数分で復旧可能なほど消失データが少量であるなら、十分に許容範囲といえるのではないでしょうか。この問題については、今後の記事で詳しく取り上げます。

質問 - サイズが縮小されたことによって、トランザクション ログは今までより早く不足するのでしょうか。
Exchange では、トランザクション ログが不足するのはログの名前が原因でした。Exchange Server 2003 では、トランザクション ログの名前は次の形式で付けられます。
E nn fffff.log
nn は SG を識別するプレフィックスです。nn は SG の生存期間中は不変であるため、1 つのストレージ グループで一意の名前を付けることができるトランザクション ログの数は fffff 個 (約百万個) です (自分用メモ : 口の両脇を小指で引っ張って強迫的に笑ってみよう)。使用頻度の高いメール サーバーでこの制限に到達した顧客もいました。
Exchange Server 2000 からは、この制限に達した場合はアプリケーション ログにイベントを表示する修正プログラムが提供されています (詳細については、support.microsoft.com/kb/896001 を参照してください)。
Exchange 2007 では、前述したように、トランザクション ログは 5 MB (Exchange の旧バージョンのサイズ) から 1 MB (Exchange 2007 のサイズ) に変更されましたが、だからといって、従来の 5 分の 1 のデータを記録した時点で一意のトランザクション ログ名が不足するというわけではありません。
Exchange 2007 では、トランザクション ログの名前は次の形式で付けられます。
E nn ffffffff.log
Exchange の前バージョンで使用できる名前の数は "fffff" 個であったのに対し、Exchange 2007 では "ffffffff" 個の名前を使用できます。内部 Extensible Storage Engine (ESE) の演算の関係上、Exchange 2007 で "ffffffff" 個のログのすべてを作成することはできません。Exchange 2007 で作成できるログは "7fffffec" 個までですが、これでも相当な数です (嘘だとお思いなら、この 16 進数を 10 進数に変換してみてください)。
これはどういうことかというと、Exchange 2007 で作成可能なログの数は前バージョンの約 2048 倍になるということです。さらに、ログのサイズが 5 分の 1 になるという点を考慮してみましょう。
2048 / 5 = 409.6
おわかりのように、新しいログ命名方式では、旧バージョンの 409 倍のデータを処理できます。これはストレージ グループ 1 つあたりの話であって、さらに各ストレージ グループには e00、e01 などの異なるログ ファイル プレフィックスを付けることができます。Exchange 2007 の Enterprise バージョンでは、さらに 1 サーバーあたり 50 のストレージ グループを作成できるということも付記しておきます。これで当面、トランザクション ログが不足する可能性は少ないと思います。

質問 - Exchange 2007 サーバーをリモート管理するにはどうしたらよいですか。
Exchange 2007 サーバーをリモート管理する方法はいくつかあります。まず、Exchange サーバーとは別のマシン (32 ビット版または 64 ビット版の Windows Server® 2003 Service Pack 1 (SP1) 以降、Windows Server 2003 R2、または Windows XP SP2 以降が動作するマシン) に Exchange 2007 管理ツールをインストールできます。サーバーの役割 (クライアント アクセス、メールボックス、エッジなど) の 32 ビット ハードウェアへのインストールは実稼動環境ではサポートされませんが、32 ビット マシンへの管理ツールのインストールに関してはサポートされます。また、Exchange Server 2007 の初期リリース時点では、管理ツールは Windows Vista™ ではサポートされません。
組織によっては、1 台のサーバーを管理サーバーにして、このサーバー上に各種製品に必要なすべての管理ツールをインストールしている場合があります。これらのツールを使用する必要がある管理者は、ターミナル サーバー経由で管理サーバーにアクセスしてリモート管理を行います。ユーザーが自分のデスクトップに管理ツールをインストールする場合もあります。
コンソールまたはシェルから組織内のサーバーを操作できます。コンソールでサーバーを参照して、リモート操作することができます。シェルを使用する場合、多くのタスクで -server などのフィルタ フラグをサポートしており、このフラグを指定して操作対象を 1 台のサーバーに限定することができます。Get-NetworkConnectionInfo コマンドなどのローカルで実行する必要があるコマンドにはこのフラグを指定できません。

質問 - 前回のコラムでは、Exchange 2007 サーバーに推奨される RAM の容量が示されていましたが、推奨されるページ ファイル サイズを教えてください。
Exchange 2007 サーバーで仮想メモリの不足エラーが起こらないようにするためには、以下のガイドラインに従ってシステム ページ ファイルのサイズを決めることをお勧めします。
サーバーの RAM が 8 GB 未満の場合、ページ ファイルの最小サイズは RAM の容量 + 10 MB にします。したがって、サーバーの RAM が 4 GB の場合、最小サイズは 4 GB + 10 MB になります。ページ ファイルの推奨サイズは RAM の容量× 1.5 であるため、4 GB のサーバーの場合は 6 GB です。
サーバーの RAM のサイズが 8 GB 以上の場合も、ページ ファイルの最小サイズは同様に RAM の容量 + 10 MB で計算しますが、推奨サイズの計算方法が異なります。基本的に、RAM の容量が 8 GB を超える場合、ページ ファイルを小さめに指定すると仮想メモリの不足エラーが発生する場合にのみ、RAM 容量× 1.5 で計算します。
ここでいうエラーは、Exchange 2000 および Exchange 2003 サーバーで問題になっていた、仮想メモリの断片化とは無関係です。ページ ファイルのサイズが増加していること、または小さすぎることを示すエラーがログに記録され、ポップアップ表示されます。

質問 - Exchange 管理シェルの使い方を知りたいのですが、これまでコマンド ラインを使ってシステムを管理した経験がありません。手始めに何をしたらよいでしょう。
まず、基本から始めましょう。Exchange 管理シェルの各コマンドレットは 1 つの動詞と 1 つの名詞で構成されます。Exchange 管理シェルで使用する動詞の数は限られています。オブジェクトのプロパティを取得するには "Get" を使用し、オブジェクトのプロパティを変更するには "Set" を使用し、新規オブジェクトを作成するには "New" を使用する、という具合にします。Exchange 管理シェルの名詞には、Exchange 管理者にはお馴染みの多くの概念 (メールボックス、連絡先、キュー、OWAVirtualDirectory など) があります。Exchange Server 2007 で登場した新しい概念 (TransportRule、StorageGroupCopy、UMAutoAttendant など) もあります。したがって、基本的なコマンドレットは New-Mailbox (メールボックスを作成する) や Get-Mailbox (組織内のメールボックスの一覧を取得する) のようになります。
とはいえ、多くのコマンドレットでは、実行する操作をより詳細に指定する必要があります。たとえば、メールボックスのプロパティを変更する場合、どのメールボックスのどのプロパティを変更するかを指定する必要があります。それにはパラメータを使用します。たとえば、New-Sandwich (サンドイッチの作成) がコマンドレットであるとすると、パラメータには -NumberOfTomatoSlices 4 (トマト スライスの枚数 4)、-Bread Wheat (パン素材 小麦) など、サンドイッチの詳細な形状を指定するさまざまなオプション (-FlufferNutter $true-ahhhh yum) が考えられます。
動詞と名詞がどのように分かれているかがわかれば、Exchange 管理コンソール (EMC) ウィザードでコマンド ライン表示を使用して、どのコマンドレットでどの操作を実行するか十分に理解できます。EMC でウィザードを実行して新しいユーザーを作成します。ウィザードの最後の操作が完了すると、ウィザードが内部的に実行したコマンドのコピーが表示されます (図 1 を参照)。Ctrl キーを押しながら C キーを押すと、ダイアログの内容がコピーされるので、コマンドレットをメモ帳に貼り付けて簡単なバッチ ファイルを作成することができます。
Figure 1 Command-line exposure for creating a new user
Figure 1 Command-line exposure for creating a new user (画像を縮小するには、ここをクリックします)
Figure 1 Command-line exposure for creating a new user
Figure 1 Command-line exposure for creating a new user (画像を拡大するには、ここをクリックします)
実害なくコマンドレットの使い方を練習するには、コマンドの最後に -WhatIf を追加する方法がお勧めです。このオプションを指定すると、システムを実際には変更せず、コマンドを実行した場合の結果が示されます。
*-Mailbox などの基本的なコマンドレットの使い方に慣れたら、他のコマンドレットも使ってみたくなるでしょう。その他のコマンドレットを探すには、Get-ExCommand コマンドレットを使用します。このコマンドレットを実行すると、すべての Exchange 管理コマンドレットが一覧表示されます (このコマンドレットを実行するには、Exchange 管理シェルが起動している必要があります。Microsoft Command Shell または Windows PowerShell™ を開いただけでは、このコマンドレットやその他の Exchange 管理タスクを実行することはできません)。この一覧は膨大なので、検索時にはワイルドカード一致を使用してください。たとえば、Get-ExCommand *database* を実行すると、名前に "database" が含まれているすべての Exchange コマンドレット (Dismount-Database、Move-DatabasePath、New-MailboxDatabase など) の一覧が返されます。
検索する名詞の一部がわかっている場合、このオプションを繰り返し処理することができます。たとえば、「Get-Mailbox」と入力してから Tab キーを押すと、タスク名の名詞に mailbox が含まれるすべてのコマンドレットが繰り返し処理されます。ワイルドカード一致と Tab キーの押下を組み合わせることもできます。たとえば、「Get-*Mailbox*」と入力して Tab キーを押すと、対象となるコマンドレットが繰り返し処理されます。
もう一つの簡単な方法は、プロンプトを使うことです。各コマンドレットには、既定で必要とされる一連のパラメータがあります。これらのパラメータは、操作の実行に必要な基本パラメータです。Get-Mailbox などの "Get" コマンドレットには、パラメータは不要です。既定では、Get-Mailbox を実行すると、組織全体のすべてのメールボックスの一覧が返されます (この一覧は、既定では、最大 1000 件です。この最大値を変更するには、たとえば、「Get-Mailbox -ResultSize 2000」と入力します)。オブジェクトを作成または変更するコマンドレット (Set や New など) では、作成または変更の対象となるオブジェクトなど、必要な情報を指定するよう要求されます。たとえば、New-Mailbox を実行すると、1 件ずつに対してパスワード、データベース、名前などの情報が要求されます。
特定のコマンドレットに関する有効なパラメータの詳細を検索するには、ヘルプ システム : Help Move-DatabasePath を使用します (「Move-DatabasePath」、「Move-DatabasePath -?」などを入力することもできます)。コマンドレットの説明、パラメータ一覧、および各パラメータの目的が表示されます。ヘルプは、Get-Help コマンドレットで表示することもできます (「Get-Help」と入力するだけで助けが得られるなんて嬉しいと思いませんか。実生活でも自分の知人がこんなコマンドレットを実行してくれたらよいのにと思ったりしませんか)。
コマンドレットに指定可能なパラメータを確認するには、パラメータ名の最後で Tab キーを押すという方法もあります。たとえば、「Get-Mailbox -S」と入力して Tab キーを押すと、S で始まる有効なパラメータが繰り返し処理されます。
詳細なヘルプ システムも用意されています。探している項目がオフラインで見つからない場合は、定期的に更新されている go.microsoft.com/fwlink/?linkid=79421 (英語) のヘルプ コンテンツおよび microsoft.com/downloads/details.aspx?FamilyID=01A441B9-4099-4C0F-B8E0-0831D4A2CA86&displaylang=ja のクイック リファレンス ガイドを参照してください。
これで、Exchange 管理コンソールを使い始めることができますが、ここに記載した情報は、コマンド ラインの機能および柔軟性のほんの表面をなぞったにすぎません。詳細については、今後のコラムで取り上げるつもりです。

質問 - Exchange Server 2003 ESM (Exchange システム マネージャ) では、すべてのユーザーのメールボックスのサイズを簡単に表示することができましたが、この機能は Exchange 2007 ではなくなっているようです。Exchange 2007 でこの機能を使用する方法はありますか。
新しい Exchange 2007 コンソールでは、メールボックスの全般的なプロパティ ページにメールボックスのサイズが表示されます。複数ユーザーのメールボックス サイズを確認するには、Exchange 管理シェルを使用する必要があります。
Get-MailboxStatistics を実行すると、特定のデータベースのみではなく、サーバー全体に関するデータが返されます。既定では、サイズは表示されません。サイズを取得するには、このコマンドレットと Format-List を実行する必要があります。
get-mailboxstatistics | format-list
表示内容を自分で選択してテーブルにパイプすることができれば、さらに便利です。この例では、メールボックスの表示名、アイテムの合計サイズ、削除済みアイテムの合計サイズ、およびメールボックスが存在するデータベースを取得します。
Get-MailboxStatistics | Select-Object
displayname,totalitemsize,
totaldeleteditemsize,databasename
| Format-Table
検索する情報に応じて、出力書式を変えることができます。この例では、Format-Table の方が Format-List より適しています。

KC Lemsonは Exchange Server チームのリード プログラム マネージャです。ATM PIN 番号は 0000 です。一度に全部使わないでください。
Nino Bilicはテクニカル リードです。暇な時は、電子メールを転送する謝礼として Bill から 1,000 ドルの小切手を集金して過ごしています。


 セキュリティ ウォッチ: EFS を展開する : 第 2 部
セキュリティ ウォッチ
EFS を展開する : 第 2 部
John Morello

暗号化ファイル システム (EFS) の展開は、基本的に次の 2 つの部分に分けて考えることができます。1 つは証明書管理と回復エージェントに重点を置いたバックエンドの設計、もう 1 つはユーザー側の EFS の展開です。先月はバックエンドの設計を取り上げ、データとキーを回復するためのオプション、
それにクライアントの証明書を準備するためのオプションについて説明しました。ここでは、Windows® エクスプローラの機能拡張、暗号化するファイル システムの場所の選択、グループ ポリシーを使用した暗号化オプションの管理方法など、エンド ユーザー側の展開に重点を置いて説明します。

EFS が既に使用されているかどうかを確認する
EFS を展開することに決めたら、まず、組織内で EFS が現在使用されているかどうかを確認する必要があります。EFS がスタンドアロン モードで使用できることを思い出してください。スタンドアロン モードでは、暗号化キーの作成とバックアップは、エンド ユーザー自身が行います。既にこのようにして EFS を使用している上級ユーザーが組織内にいる場合があります。したがって、管理された展開にスムーズに移行できるように、これらのユーザーを特定することが重要です。
EFS がコンピュータ上で初めて使用されたときに、Windows によって HKEY_CURRENT_USER に次のレジストリ エントリが作成されます。
HKCU\Software\Microsoft\Windows NT\CurrentVersion\EFS\CurrentKeys\CertificateHash
Microsoft® Systems Management Server (SMS)、Active Directory ログオン スクリプト、またはその他のツールを使用して、組織全体のコンピュータについてこのエントリが存在するかどうかを確認できます。このレジストリ値が存在するコンピュータでは、EFS が使用されたことがあることを示しています。ただし、この値は、EFS を現在使用しているユーザーがいることや、コンピュータ上のデータが暗号化されていることを示すものではありません。したがって、このレジストリ キーが存在するコンピューが見つかった場合は、現在暗号化されているファイルがあるかどうかを確認するために、コンピュータをよく調べる必要があります。
/U および /N スイッチを渡して cipher.exe を使用すると、コンピュータ上のファイルとディレクトリの暗号化状態が報告されます。たとえば、システム上のデータが暗号化されているかどうかを確認する必要がある場合は、次のコマンドを実行できます。
cipher /U /N
レジストリの確認と cipher のレポートを 1 つのスクリプトにまとめて、レジストリ値が存在するかどうかを確認し、存在する場合は現在暗号化されているコンピュータ上のファイルのレポートを生成することができます。これらのレポートを生成すると、どのユーザーがどのファイルを暗号化しているかを把握して、それらのファイルを一元管理の設計に移行できます。
展開中にグループ ポリシーの適用を制御するには、ドメイン内に 2 つのセキュリティ グループを作成して、EFS が使用されているコンピュータを、EFS が使用されていないコンピュータから切り離すと便利です。たとえば、"SG-ComputersUsingEFS" には EFS が既に使用されているコンピュータのコンピュータ アカウントを所属させ、"SG-ComputersNotUsingEFS" には EFS が現在使用されていないコンピュータを所属させます。

グループ ポリシーで EFS の使用を制御する
EFS を使用しているユーザーと使用していないユーザーを把握したら、次に、EFS を現在使用していないユーザーによるスタンドアロンの EFS の使用を無効にします。これは展開プロセスにおいて重要な手順です。EFS を初めて有効にして正しく構成する方が、自己署名入りの証明書を使用しているユーザーを移行するよりも簡単だからです。この手順は、EFS を既に使用しているユーザーを特定した後で行ってください。グループ ポリシーを使用して EFS を無効にすると、ユーザーは現在暗号化されているファイルにアクセスできなくなるからです。このポリシーは、グループ ポリシー オブジェクト エディタで [コンピュータの構成]、[Windows の設定]、[セキュリティの設定]、[公開キーのポリシー]、[暗号化ファイル システム] を順に展開すると見つかります。
前述のように、EFS を既に使用しているユーザーの作業を混乱させないように、EFS が現在使用されていないコンピュータでのみこの値を有効にする必要があります。そのため、私の例では、EFS を無効にするグループ ポリシー オブジェクト (GPO) のアクセス制御リスト (ACL) で、"SG-ComputersNotUsingEFS" グループだけがこのグループ ポリシーを適用できるようにしています。

暗号化するかどうかを決定する
EFS を現在使用しているコンピュータを特定し、管理された展開の完了まで他のすべてのコンピュータ上の EFS を無効にしたら、その管理された展開において暗号化する対象を決定します。クライアント システムがどのように管理されているかによって、このプロセスは単純な場合もあれば複雑な場合もあります。
暗号化するファイルを検討するときには、まずユーザーがコンピュータの管理者であるかどうかを考慮する必要があります。ユーザーがローカル管理者の場合は、機密データの暗号化をユーザーに指導して促すことのみ可能であり、暗号化の制御を本当に管理された方法で行うことはできません。その理由は単純です。ローカル管理者は、ファイルやディレクトリをファイル システム上のどこにでも作成できるからです。したがって、マイ ドキュメントなどの一般的な場所を暗号化しても、ユーザーが新しいディレクトリを別の場所に作成してそのディレクトリに機密情報を保存する場合は、このデータを確実に保護するのは難しくなります。エンド ユーザーがローカル管理者ではない場合には、さまざまなセキュリティ上の利点に加えて、EFS についても管理が容易になり、セキュリティが強化されます。
EFS について次に留意すべき重要な点は、ユーザーごとの暗号化です。つまり、あるユーザーが暗号化したものは、そのユーザーだけが暗号化を解除でき、SYSTEM アカウントなどの他のユーザーは暗号化を解除できません (もちろん、データ回復エージェント (DRA) は例外です)。したがって、ユーザーのキーを使用して実行可能ファイルまたは DLL が暗号化された場合に、システム上の別のプリンシパルがそのファイルにアクセスしようとすると、アクセス拒否エラーが発生します。通常、実行可能なコードを含むファイルやディレクトリは、システム上の複数のプリンシパルがアクセスする必要があるため、暗号化しないことをお勧めします。Windows では、%SystemRoot% 内のファイルまたは SYSTEM 属性を持つファイルを暗号化できません。しかし、ソフトウェア ベンダが SYSTEM アカウントで実行されるサービスのバイナリを %ProgramFiles% にインストールすることはよくあります。たとえば、ラップトップ (ノート型パソコン) のメーカーは、サービスとして実行される電源管理ソフトウェアやデバイス管理ソフトウェアをインストールするときに、この方法をよく使用します。
これらの 2 つの事実を考慮すると、EFS 暗号化の対象についてのベスト プラクティスはどうなるでしょうか。その答えは、ユーザーのシステムが通常どのように構成されているかによります。標準化されたオペレーティング システムのイメージを含む管理の行き届いた環境では、多くの場合、イメージで定義済みのデータ保存場所に基づいて、ユーザーの暗号化プロセスを自動化できます。たとえば、ユーザーがデータを %userprofile%\My Documents ディレクトリにのみ保存できる場合は、そのディレクトリを暗号化するだけで済みます (メモ : フォルダのリダイレクトを使用する場合は、マイ ドキュメントを暗号化するときに注意が必要です。マイ ドキュメントをサーバーにリダイレクトする場合は、そのサーバーが委任に対して信頼され、ユーザーのプロファイルにアクセスできる必要があります。そのような場合には、通常はオフライン ファイルのキャッシュだけを暗号化する方が簡単です。オフライン ファイルについては後述します)。
管理の程度が低い環境 (ユーザーがファイル システム上の多くの場所に書き込みできる環境) では、少数の一般的な保存場所の暗号化を自動化し、他の保存場所をユーザー自身で暗号化する方法をユーザーに指導する方法を取るのがよいでしょう。環境の種類にかかわらず、常にファイル レベルではなく、ディレクトリ レベルで暗号化を行うことをお勧めします。これにより、そのディレクトリに作成されたすべてのファイルは、一時ファイルも含めて常に暗号化されます。

暗号化が推奨される場所
一般的な規則として、%userprofile%\My Documents、%userprofile%\Application Data\Microsoft\Outlook (メッセージング クライアントとして Microsoft Office Outlook® を使用している場合)、および %userprofile%\デスクトップを暗号化することをお勧めします。My Documents ディレクトリを暗号化すると、Windows XP ではファイル保存時の既定の場所が保護されます。Outlook ディレクトリを保護すると、ローカルにキャッシュされた機密性のある電子メールも暗号化されます。これは、既定のキャッシュ モードで Outlook 2003 を実行しているユーザーにとって特に重要です。最後に、デスクトップは一時ディレクトリとして使用されることが多く、ユーザーは現在作業中のドキュメントやよく使用するプレゼンテーションをここに配置します。もちろん、組織内でこれらのディレクトリの既定の場所を変更していることもあります。そのため、EFS 暗号化の対象には、組織内で通常使用する場所をすべて選択することをお勧めします。
これらの一般的なベスト プラクティスに加えて、機密情報を別の場所に保存するアプリケーションがあるかどうかを調べることをお勧めします。たとえば、一部のアプリケーションでは、ユーザー情報をユーザーのプロファイルではなく %ProgramFiles%\AppName に保存します。クライアント システム上にそのようなアプリケーションがあるかどうかを調べて、アプリケーションによって使用されるデータを適切に保護できるようにすることが重要です。最良の場合、ユーザー プロファイル固有の別のパス (マイ ドキュメントなど) に変更内容を保存するようにアプリケーションを構成できれば、EFS に変更を加える必要がありません。最悪の場合、アプリケーションのデータを Program Files ディレクトリに格納する必要があるならば、EFS を使用して Program Files の特定のサブディレクトリだけを暗号化することができます。
最後に、一時ディレクトリ (%TMP%、%TEMP% など) を暗号化する場合は注意が必要です。多くのアプリケーション インストーラでは、このディレクトリにインストール パッケージの内容を展開し、%ProgramFiles% 内の適切なパスにそれらのファイルを移動します。同じボリューム上で移動されたファイルは、元の属性を保持するため、ファイルは %ProgramFiles% に移動された後でも暗号化されたままになります。このため、インストーラを実行したユーザー以外のユーザーがこのファイルを使用しようしても、拒否されます。多くの場合、このような問題が発生しても、根本的な原因を示す明確なアプリケーション エラー メッセージは表示されません。そのため、一般的には %TMP% の暗号化は、エンド ユーザーが自分でアプリケーションをインストールしないような管理の行き届いた環境でのみ行うことをお勧めします。

オフライン ファイルを保護する
オフライン ファイルは Windows 2000 以降の機能です。この機能を使用すると、ファイル サーバーに格納されているデータのローカル コピーを作成できます。サーバーに接続していない間にこのデータを処理して、次にサーバーに接続したときに変更内容をサーバーと同期できます。ただし、オフライン ファイルは、サーバーのファイルのコピーが格納された単純なディレクトリではなく、システム全体で共有され、SYSTEM アカウントのコンテキストで実行されるデータベースになっています。Windows XP では、このデータベースを EFS で保護できます。ユーザーごとの EFS について前述した内容を踏まえて、これが何を意味するかを考えてください。ユーザー固有の EFS は、複数のセキュリティ プリンシパルが使用するデータベースをどのようにして暗号化するでしょうか。
Windows XP を実行しているユーザーが Windows エクスプローラでオフライン ファイルを暗号化するオプションを選択した場合、使用される暗号化ルーチンは、そのユーザーが行う可能性がある他の暗号化操作に使用されるルーチンとは異なります。ユーザー個人の EFS キー ペアを利用すると SYSTEM がファイルにアクセスできなくなるため、代わりに SYSTEM アカウントが EFS で使用するキー ペアを自己生成し、そのキー ペアを使用してクライアント側のキャッシュを暗号化します。この場合セキュリティ面で重大な影響があります。この後だれかが SYSTEM として実行できるコードを入手すると、その人はキャッシュ内のデータの暗号化を解除できるからです。ラップトップが盗まれた場合、攻撃者は簡単に管理者パスワードをリセットして、管理者としてログオンできてしまいます。いったん管理者となってしまえば、強制的にコードを SYSTEM として実行してキャッシュにアクセスするのも同様に簡単なことです (Windows Vista™ では、この動作が変更され、個々のユーザーのキーを使用して、ユーザー固有のオフライン ファイルを暗号化するようになりました)。
このような攻撃を防ぐには、Security Accounts Management (SAM) データベースの暗号化キーをオフラインで保存するように、起動時のパスワード入力にするか (モード 2)、起動時のフロッピー ディスク挿入にする (モード 3) ようにラップトップを構成できます。どちらの方法も起動中に自動化できないコンピュータ操作の必要があるため煩雑であり、自動化されたシステム管理では問題が生じる可能性があります。しかし、オフライン ファイルを使用するコンピュータ上で EFS を使用する場合は、これらのオプションのいずれかを使用してキャッシュ内のデータを保護することが非常に重要です。通常は、起動時のパスワードを使用することをお勧めします (図 1 を参照)。これは、ラップトップのバッグを盗まれたユーザーは、ディスクをラップトップにセットしたままか、バッグの中に一緒に入れている可能性が高いからです。
Figure 1 Automate EFS operations
Figure 1 Automate EFS operations

EFS を有効にする
クライアント上で暗号化する対象を決めたら、次に実際の暗号化操作を行います。この処理は、ログオン スクリプトを使用するか、cipher.exe を呼び出して暗号化操作を行うクライアント上のスクリプトによって実行できます。前述の例のように、スタンドアロンの EFS ユーザーが環境に存在する場合は、まずそれらのユーザーを移行することをお勧めします。
これらのスタンドアロン ユーザーを移行するには、このコラムの 2007 年 2 月号の回 (microsoft.com/technet/technetmag/issues/2007/02/SecurityWatch) で説明したように、まず管理された証明書をクライアント システムに準備します。すべてのシステムがこれらの管理された証明書を登録したら、/U スイッチを指定して cipher を実行し、既存のすべてのファイルを新しい暗号化キーと回復エージェント キーで更新する必要があります。これで、SG-ComputersUsingEFS グループ内のすべてのシステムは、中央で発行された (アーカイブされている可能性もある) キー、一元管理の回復エージェントなど、管理された方法で EFS を利用するようになります。
EFS を現在使用していないユーザー用に EFS を展開するには、まず EFS の使用を禁止しているグループ ポリシーを削除する必要があります。グループ ポリシーの削除が完了し、管理された証明書をユーザーが登録したら、ログオン スクリプトを実行して、前述の主要なパスを暗号化できます。簡単なサンプル スクリプトを次に示します。
cipher /e /s /a "%userprofile%\My Documents"

cipher /e /s /a "%userprofile%\Application Data\Microsoft\Outlook"

cipher /e /s /a "%userprofile%\Desktop"
目的のディレクトリに対して EFS を有効にしたら、EFS の展開のセキュリティを強化する 2 つの追加オプションの設定を検討する必要があります。これらのオプションは、両方ともメモリからディスクにページングされたデータに関連するものです。それぞれのシナリオでは、これまでの処理により、悪意のある人物によって回復される可能性があるデータの量は、コンピュータの正当な使用時にメモリに読み込まれるか、ディスクにページングされるデータの量にまで制限されています。つまり、機密性のある EFS で保護されたデータがコンピュータ上にあり、そのデータを表示したことがない (したがって、メモリに読み込んだことがない) 場合は、そのデータがこれらの攻撃を受ける危険性はありません。
ページ ファイルは、Windows によって仮想メモリ (他のオペレーティング システムではスワップ領域と呼ばれることが多い) として使用されます。このファイルには、ハード ドライブにクリア テキストで書き込まれるメモリ内のデータの一部 (未加工) が含まれます。攻撃者によってページ ファイルが回復された場合は、フォレンジック (科学捜査) ツールを利用してこのファイルから使用可能なデータを抽出される可能性があるため、EFS で保護されたシステムでも機密データが危険にさらされることがあります。ページ ファイル自体は、Windows XP では暗号化できないので (Windows Vista ではできます)、シャットダウン時にページ ファイルを Windows に強制的にクリアさせるのが最良の手段です。そのためには、図 2 に示すようにグループ ポリシーを使用します。
Figure 2 Setting group policy
Figure 2 Setting group policy (画像を縮小するには、ここをクリックします)
Figure 2 Setting group policy
Figure 2 Setting group policy (画像を拡大するには、ここをクリックします)
この設定の欠点は、特に大容量のメモリが搭載されたコンピュータでは、シャットダウンに長い時間がかかることです (既定では、ページ ファイルのサイズは、コンピュータの物理メモリのサイズと直接関係があります)。これは、ページ ファイルをクリアするためには、シャットダウンの前にディスク上のすべてのページに Windows が物理的に書き込む必要があるからです。
電源管理モードで休止状態が有効に設定されている場合は、Windows の休止状態ファイルにコンピュータの物理メモリのダンプが格納されます。コンピュータが休止状態になると、Windows は物理メモリのすべての内容をディスクの休止状態ファイルに書き込みます。これにより、ユーザーが作業を続行するときに、コンピュータの状態を休止状態前とまったく同じに戻すことができます。ページ ファイルと同様に、休止状態ファイルは Windows XP では暗号化できません。ただし、ページ ファイルとは違って、休止状態を GPO から直接無効にすることはできません。代わりに、スクリプトを使用して、/HIBERNATE スイッチを指定した powercfg.exe を呼び出すことで休止状態を無効にしたり再度有効にしたりできます。
初期の暗号化と構成の作業が完了したら、展開先のディスク上にあるスラック領域の消去を検討する必要があります。この処理には長い時間がかかり、混乱を招く可能性がありますが、高度なセキュリティが必要とされる環境では、セキュリティ上の利点があります。スラック領域とは、システム上の現在アクティブなデータを保持していないディスク領域です。ハード ディスク動作のしくみにより、以前使用されていたファイルの機密情報の一部が格納されている場合があります。つまり、ファイルを削除しても、ファイル テーブルからポインタが削除されるだけで、実際にはファイルがディスク上で使用するすべてのセクタが上書きされないため、削除されたデータはディスク上に残ることがあります。このような場合には、このスラック領域を読み取ってファイルを再び組み立て直すことができるフォレンジック ツールを使用して、データを回復できる可能性があります。この残留データを安全に削除するには、/W スイッチを指定して cipher を実行します。これにより、ディスク上で使用可能なすべてのセクタが繰り返し上書きされます。機密データに対して今後行われるすべてのファイル操作が EFS で保護されたディレクトリで行われる限り、このコマンドを定期的に実行する必要はありません。

Windows エクスプローラを EFS 用に拡張する
既定では、ファイルやディレクトリの暗号化と暗号化解除のオプションは、Windows エクスプローラの詳細プロパティ メニューに埋もれた状態になっています。Windows エクスプローラのコンテキスト メニュー (右クリックで表示されます) に [暗号化] および [暗号化解除] を追加すると、エンド ユーザーの EFS の操作性を向上できます。さらに、EFS で保護されたファイルとディレクトリを他のファイルと異なる色 (緑) で表示するように Windows エクスプローラを構成できます。これにより、ユーザーは詳細プロパティ メニューを調べなくてもファイルやディレクトリが暗号化されているかどうかを確認できます。最後に、ファイルやディレクトリにアクセスできるユーザーを定義するオプションを追加することもできます。これらのオプションを有効にするには、reg.exe を呼び出すスクリプトを使用して、レジストリに次の変更を行います。
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced]

"EncryptionContextMenu"=dword:00000001

"ShowCompColor"=dword:00000001

[HKEY_CLASSES_ROOT\*\Shell\Encrypt To User...\Command]
@="rundll32 efsadu.dll,AddUserToObject %1"

Windows Vista の EFS
Windows Vista では、EFS に関する重要な機能拡張が多数追加され、EFS の展開と管理、およびセキュリティの向上が容易になりました。これらの機能拡張の中で第一のものは、スマート カードに EFS キーを保存できるようになったことです。既にスマート カード ログオンを利用している組織にとっては、これにより同じカードを使用してユーザーの EFS キーも保存できるため、特に有用な機能です。このスマート カードのサポートは、回復エージェントの証明書にも適用され、機密性のある DRA 証明書もカードに保存できます。
Windows Vista では、Windows XP では不可能であったり、難しかったアイテムの暗号化もサポートされています。たとえば、Windows Vista ではページ ファイルを暗号化できるため、[仮想メモリのページ ファイルをクリアする] オプションを設定する必要がなくなりました。また、オフライン ファイルの設計全体が練り直されました。パフォーマンスと安定性、およびユーザー フレンドリなインターフェイスが大幅に向上されただけでなく、クライアント側のキャッシュがユーザー単位になりました。つまり、SYSKEY モード 2 や 3 を使用しなくても、キャッシュを安全に暗号化できます。これらの 2 つの機能強化により、今日の Windows XP ベースの環境における主な展開の問題が解消されます。
最後に、Windows Vista では、管理者が個別のスクリプトを利用しなくても、グループ ポリシーを使用して直接ドキュメント フォルダの暗号化を構成できるようになりました。図 3 に、Windows Vista において GPO で使用できる EFS プロパティを示します。
Figure 3 EFS properties in Windows Vista
Figure 3 EFS properties in Windows Vista (画像を縮小するには、ここをクリックします)
Figure 3 EFS properties in Windows Vista
Figure 3 EFS properties in Windows Vista (画像を拡大するには、ここをクリックします)

まとめ
EFS は、Windows 管理者にモバイル データを保護するための高度なセキュリティ オプションを提供します。EFS はスケーラビリティと管理性が高く、柔軟なデータ回復メカニズムを備えています。Windows Vista の EFS はさらに機能強化され、管理と展開を容易にする拡張機能を備え、スマート カードへのキーの保存もサポートしています。データを保護する必要のある組織では、コンピュータが物理的に失われた場合でも、既存の Windows プラットフォームの一部になっている強力なソリューションが EFS によって提供されます。
参考資料
このコラムで説明したトピックの詳細については、以下のリソースを参照してください。
  • February 2007 セキュリティ ウォッチ
  • Encrypting File System in Windows XP and Windows Server 2003
    • (英語)
  • SysKey ユーティリティを使用して Windows セキュリティ アカウント マネージャ データベースをセキュリティで保護する方法

John Morelloは、LSU を首席で卒業し、これまでにマイクロソフトで 6 年間さまざまな任務を果たしてきました。シニア コンサルタントとして、フォーチュン 100 企業や、連邦政府の民生向けおよび国防向けのセキュリティ ソリューションの設計に携わってきました。現在は、Windows Server グループのプログラム マネージャとして、セキュリティおよびリモート アクセス テクノロジに取り組んでいます。


 デスクトップ ファイル: PsTools 入門
デスクトップ ファイル
PsTools 入門
Wes Miller
この記事で使用しているコードのダウンロード: MillerTheDesktopFiles2007_03.exe (150KB)

昨年まで、Winternals Software に勤務していました。Winternals Software は、マイクロソフトにより 2006 年 7 月 に買収されました。Winternals の市販用ソフトウェアは売却されましたが、創業者である Mark Russinovich と Bryce Cogswell は、多数のツールをフリーウェアとして提供している Sysinternals という別の会社も経営していました。これらのフリーウェア アプリケーションには、
Winternals Administrator's Pak のコンポーネントになっているものもあります。Mark と Bryce は、通常のフリーウェア ライセンス条件の範囲外でこれらのツールを使おうとしている企業に対してライセンスの供与も行っていました。
Sysinternals ライブラリにある多数のツールの中で、PsTools スイートは私のお気に入りのツールの 1 つです。現在、このツールは microsoft.com/technet/sysinternals/utilities/pstools.mspx にあります。このツール名は、UNIX のプロセス リスト ユーティリティ (ps) にちなんで Mark が付けた名前です。ツールのダウンロード サイトに記載されているように、組み込みの Windows® コマンドライン ユーティリティには、これらのツールと同じ機能を実行できるものもあります。ただし、PsTools スイートは、非常に独特な機能であることに加え、ローカルでもリモートでも使用できる点に大きな違いがあります (ただし、リモート システムが適切に構成されている必要があります)。さらに、リモートでもローカルの場合と同じくらい簡単に実行できるというメリットがあります。
PsTools スイートには、図 1 に示すように、複数の個別のアプリケーションが含まれています。他の Sysinternals ユーティリティと同様、インストーラはなく、アプリケーションのみです。これらのアプリケーションをパス上の任意のフォルダに置き、実行するだけです。
Figure 1 PsTools のユーティリティ (Close Figure 1)

ツール | 説明
PsExec | 任意のユーザー コンテキストでプロセスを実行できます。
PsFile | システムで開いているファイルをリモートで表示します。
PsGetSid | コンピュータまたはユーザーの Windows セキュリティ識別子 (SID) を表示します。
PsInfo | Windows システムの情報を表示します。
PsKill | 指定したプロセス名またはプロセス ID によりプロセスを終了します。
PsList | 実行中のプロセスの詳細情報を表示します。
PsLoggedOn | ローカルのログオン ユーザーおよびリソースを共有しているリモート ユーザーをすべて表示します。
PsLogList | Windows イベント ログのレコードをダンプします。
PsPasswd | ユーザー アカウントのパスワードを変更します。
PsService | Windows サービスを表示および管理します。
PsShutdown | コンピュータをシャットダウン、再起動、休止状態に設定、または中断します。
PsSuspend | 実行中のプロセスを中断します。
お気付きのとおり、一部の機能 (特に PsLogList) は、Windows Management Instrumentation (WMI) や複雑なスクリプトによって実行することも可能です。ただし、PsTools スイートのメリットは、簡単かつわかりやすい方法で、各ユーティリティが特定のタスクを実行するように設計されていることです。
以下では、各ツールについて説明し、簡単な例を挙げて各ツールの使用目的と使用方法を示します。まず最初に、これらのツールがどのように動作し、動作のために必要な前提条件を簡単に説明します。

ツールの動作
通常、すべてのツールは同じように動作します。ホスト システムで、目的の PsTool を起動します。多くのツールは、ローカルでも実行できますが、リモート システムに対して実行するか、一度に複数のシステムに対して実行した場合に、最大の効果を得ることができます (以下の例で示すように、PsExec は特に優れた効果を発揮します)。ユーティリティは、指定したコマンドライン引数を使用して、リモート システムの管理共有、つまり、リモート システムの %SystemRoot% (Windows ディレクトリ) にコピーされます。
リモート ディレクトリにコピーされると、アプリケーションが起動し、Windows サービスがインストールされます。この Windows サービスは、起動時にユーザーが指定した資格情報を使用して、ユーザーが要求したタスクを実行します。特定のツールでクライアント システム上のエンドユーザー UI が必要な場合、このサービスはユーザーのコンテキストで追加のバイナリを起動します (サービスは直接の対話型 UI を投入できないことに留意してください)。必要な情報は、サービスの起動元のコンソールに返送されます。最後に、サービスは自動的にアンインストールされます。
ご覧のように、これらは強力な自己完結型のツールです。ツールには多数のバイナリおよびプロセスが含まれますが、ユーザーはこれらを気にせずに、目的のツールを実行するだけで動作します。
ツールを使用するには、次の前提条件を満たしている必要があります。Windows NT®、Windows 2000、Windows XP、または Windows Server® 2003 (x86 版と x64 版の Windows はサポートされますが、Itanium 版はサポートされません) のいずれかを使用していること。ツールを実行するリモート システム上で、既定の管理用ネットワーク共有 (admin$) が有効であること。また、Windows ファイアウォール、インターネット接続ファイアウォール、または他のファイアウォール製品を使用するかどうかにかかわらず、リモート システム上のファイルとプリンタの共有のためのポートが開いていること。

PsExec
PsExec は、私のお気に入りのツールの 1 つですが、これは大方の予想とは異なる理由によります。この 2 年間ほとんど、システム上で「管理者以外」で実行しています。管理者ではなく、ユーザーとして実行しています。管理者として実行するのではなく、run.vbs という短いスクリプトを使用することでローカル管理者としてアプリケーションを実行できます (どのようなユーザーとしても実行できます)。図 2 に、スクリプトの内容を示します。このスクリプトは、TechNet Magazine のサイト (technetmagazine.com/code07.aspx) でも入手できます。このスクリプトでは、Path システム変数に PsTools が格納されていることを前提とします。
Figure 2 Run.vbs (Close Figure 2)
SET WshShell = WScript.CreateObject("WScript.Shell")
SET WshSysEnv = WshShell.Environment("SYSTEM")
SET FSO = CreateObject("Scripting.FileSystemObject")
IF WScript.Arguments.Count <> 0 Then
    FOR EACH arg IN WScript.Arguments
        iArgCount = iArgCount + 1
        strCmdArg = (arg)
        strCmdArray = Split(strCmdArg, " ", 2, 1)
        IF iArgCount = 1 THEN
        strExe = strCmdArray(0)
        ELSEIF iArgCount = 2 THEN
        strRun = strCmdArray(0)
        ELSE
        strParams = strParams&" "&strCmdArray(0)
        END IF
    NEXT
END IF
'/t:0A && title ***** Admin *****
        strExt = LCase(Right(strExe, 3))

IF strExt <> "exe" AND strExt <> "bat" AND strExt <> "cmd" THEN
WshShell.Run "psexec.exe -d -i -e -u COMPUTERNAME\USER -p PASSWORD  cmd /c start "&strExe&"
    "&strRun&" "&strParams, 0, FALSE
ELSE
WshShell.Run "psexec.exe -d -i -e -u COMPUTERNAME\USER -p PASSWORD "&strExe&" "&strRun&"
    "&strParams, 0, FALSE
END IF

    SET WshShell = NOTHING
    SET WshSysEnv = NOTHING
    SET FSO = NOTHING
この簡単なスクリプトは、PsExec を使用する際に利用できる機能の 1 つの例であり、これは Winternals で Protection Manager 製品の作業をしていたときに Mark が追加したものです。この機能を使用すると、制限付きユーザーがより高い特権を持つ資格情報を指定して PsExec をローカルで起動できます。当然ですが、PsExec は、一般にリモートでの実行によく使われています。たとえば、独自のリモート機能、スクリプト、または自動化のフレームワークを持たないユーティリティを実行するために使用されます。PsExec のいくつかの重要な機能には、実行の対象となるリモート システムにバイナリをコピーする機能、プロセッサの関係を指定する機能などがあります。PsExec のもう一つの便利な機能は、スクリプト ファイルを指定して、同時に多数のマシンに対するスクリプト化が可能なことです。
PsExec の簡単な使用方法を次に示します。
PsExec \\computer -u username -p password command
図 3 に示すスイッチを使用して、これを拡張することもできます。
Figure 3 PsExec のスイッチ (Close Figure 3)

スイッチ | 説明
-a | プロセッサの関係を指定します。
-c | アプリケーションをリモート システムにコピーするかどうかを指定します。
-d | プロセスの終了を待たずに終了します (成功または失敗のメッセージを待ちません)。
-e | 指定したアカウントのプロファイルを使用して読み込みます。
-f | アプリケーションがリモート システムに存在する場合もアプリケーションをコピーします。最新 (または特定の) バージョンを実行中であることを確認します。
-i | リモート システムでアプリケーションを対話形式で実行します (アプリケーションでユーザー インターフェイスをエンド ユーザーに表示する場合に必要です)。
-l | アプリケーションを制限付きユーザーとして実行します。Administrators グループ トークンを削除し、プロセスの特権を制限して Users グループのメンバと同じレベルにします。リスクの高いインターネットに接続されたアプリケーションを最小限の特権で実行する場合に便利です。
-n | リモート コンピュータとの接続に失敗するまでの待ち時間のタイムアウトを指定します。
-priority | 指定した優先順位でプロセスを実行します。つまり、特定のタスクに関する処理の優先順位を Windows でどのように設定するかを指定します (-low、-belownormal、-abovenormal、-high、または -realtime )。
-s | システム アカウントを使用してプロセスを実行します (Regedit を実行して特権が設定されたレジストリ キーにアクセスする場合に便利です)。
-v | コピー先よりも最新のアプリケーションである場合のみアプリケーションをコピーします。
-x | セキュリティで保護された Winlogon デスクトップに UI を表示します (ローカル システムのみ)
@file | テキスト ファイルに指定されたすべてのコンピュータでコマンドを実行します。

PsFile
PsFile は、PsExec よりも限定的なツールです。具体的には、リモート システム上で開いているファイル、およびファイルを開いたユーザーを確認するのに使用します。この機能は、サーバーを再起動する前に、開いているファイルを把握する場合に役立ちます。いずれかのユーザーによってファイルがロックされ、ファイルの編集や削除ができないとき、そのユーザーを特定する必要がある場合は、手動で通知するか、PsFile でファイルを閉じることができます。PsFile の使用方法を次に示します。
PsFile \\computer -u username -p password
上記は、リモート システムで開いているファイル ハンドルの一覧を返します。標準の使用以外にも、ID パラメータを追加して、情報を取得するファイルや閉じるファイルの名前を指定できます。また、-c スイッチを追加して ID パラメータで指定したファイルを閉じることもできます。

PsGetSid
PsGetSid も、非常に限定的なツールです。このツールは、コンピュータ、ユーザー、またはグループのセキュリティ識別子 (SID) を取得します。このツールは、ドメイン内のシステムの SID が重複していないことを確認する場合や、単純にシステム上のすべてのユーザーまたはグループの SID を確認する場合に役立ちます。PsGetSid の使用方法を次に示します。
PsGetSid \\computer -u username -p password account
account には、ユーザー、コンピュータ、またはグループを指定できます。PSGetSid の構文は単純ですが、指定可能ないくつかの追加のパラメータがあります。SID パラメータは、指定した SID を持つアカウント (グループまたはコンピュータ) を指定し、@file は、指定したテキスト ファイルに示されたすべてのコンピュータでコマンドを実行します。

PsInfo
PsInfo を使用すると、詳細なシステム情報を取得できます。言うまでもなく、このツールが最も有益となるのは、複数のリモート システムに対してスクリプト化され、出力先のファイル (Excel® およびデータベース フレンドリな CSV ファイル) が指定されている場合です。このユーティリティは、他の多くのツールとは異なった重要なコンセプトで動作します。したがって、コンピュータ名を指定しないと、PsInfo は既定により、ドメイン内のすべてのコンピュータに問い合わせを試みます。PsInfo の使用方法を次に示します。
PsInfo  \\computer -u username -p password
構文は単純ですが、図 4 に示すように、追加のスイッチやパラメータを指定できます。
Figure 4 PsInfo のスイッチ (Close Figure 4)

スイッチ | 説明
-h | Windows の更新プログラムをすべて表示します。
-s | システムにインストールされたすべてのアプリケーションを表示します。
-d | システムのディスク情報またはボリューム情報を表示します。
-c | 結果を CSV 形式で出力します。
-t | 既定値の \t 以外に、CSV ファイルの区切り文字をもう 1 つ指定します。
Filter | 指定したフィルタに一致するデータのみを表示します。
@file | 指定したテキスト ファイルに示されたすべてのコンピュータでコマンドを実行します。

PsKill
PsKill は、ローカル システムまたはリモート システムのプロセスを終了するための優れたユーティリティです。使用方法はごく簡単であり、プロセスとそのすべての子プロセスをすばやく終了することができます。PsKill の使用方法は、上記の他のツールとほとんど同じです。
PsKill -t \\computer -u username -p password process id | process name
終了するプロセスの ID またはプロセス名のいずれかを指定できます。

PsList
私は Process Explorer (詳細は microsoft.com/technet/sysinternals/ProcessesAndThreads/ProcessExplorer.mspx を参照) が非常に気に入っているため、PsList はあまり使用していません。ただし、リモートで実行可能な Process Explorer がないため、Process Explorer のいくつかの重要な機能を合理的に模写したものが PsList になります。実際に、PsList では、リモート システムで実行中の 1 つ以上のプロセスをリモートで表示できます。
PsList の使用方法はごく簡単です。
PsList \\computer -u username -p password account
他のツールの場合と同様、account パラメータにはユーザー、コンピュータ、またはグループを指定できます。図 5 に、追加のパラメータを示しています。
Figure 5 PsList のスイッチ (Close Figure 5)

スイッチ | 説明
-t | スレッド レベルの情報を表示します。
-m | 各プロセスのメモリの詳細を提供します。
-x | プロセス、メモリ、およびスレッドの情報を表示します。
-t | 情報をプロセス ツリーとして表示します (Process Explorer のツリー ビューを思い出してください)。
-s [n] | 指定した秒数だけタスク マネージャ モードで実行します。リモート プロセスの情報を相対的にリアルタイムで表示できます。
-r [n] | タスク マネージャ モードで実行するときの更新間隔を指定します (秒単位)。
name | 指定した値で始まる名前のプロセスに関する情報を表示します。
-e | 完全に一致する名前のプロセスだけが表示されます。
pid | 特定のプロセスの情報を表示します。
PsList は強力であると同時に使いやすく、リモート デスクトップを使用せずにリモート プロセスを極めて詳細に表示できます。たとえば、プロセスを制限する必要がある場合は、この情報を使用して PsKill または PsSuspend に進むことが可能です。

PsLoggedOn
PsLoggedOn の背後にある前提条件は一目瞭然です。このユーティリティは、システムにログオンしているユーザーを表示します。ローカル (対話型) ログオンまたはネットワーク共有のログオンを表示できます。PsFile と同様、この機能を使用すると、サーバーのメンテナンスを行う必要があるとき、そのサーバーを使用しているユーザーを調べるのに役立ちます。使用方法は非常に簡単です。
PsLoggedOn \\computer
PsLoggedOn のオプション パラメータは 2 つだけです。-l はローカル ログオンのみ (ネットワーク ログオン以外) を表示し、-x はログオン時刻を除きます。
単純でありながら、PsLoggedOn を使用すると、通常では数箇所の Windows を詳細に調べなければ入手できない情報を簡単に表示できます。

PsLogList
PsLogList は、最も広く使われている実用的なユーティリティの 1 つです。このツールでは、Windows イベント ログのダンプがテキスト形式で出力されるので、ログ リーダー、データベース、その他お好きなものでログ データを使用できます。主な利点は、イベント ログのエントリがバイナリ形式から、さらなる変換や自動化がしやすい形式に変換されることです (Windows Vista™ では、イベント ログを XML として取得できますが、このトピックは別の機会に譲ることにします)。
PsLogList の使用方法は次のとおりです。
PsLogList \\computer -u username -p password
図 6 に示すように、指定できる追加のスイッチやパラメータが多数あります。
Figure 6 PsLogList のスイッチ (Close Figure 6)

スイッチ | 説明
-a | 指定した日付より後に発生したイベントのみダンプします。
-b | 指定した日付より前に発生したイベントのみダンプします。
-c | 目的の出力をダンプした後、イベント ログを完全に削除します。
-d | 指定した日数の情報のみ表示します。
-e | 指定したイベント ID のイベントを除外します (10 個まで指定可能)。
-f | イベントの種類をフィルタします (警告、エラーなど)。
-g | イベント ログを EVT ファイルとしてエクスポートします (-c スイッチが必要)。
-h | 指定した数時間の情報のみ表示します。
-l | 指定した EVT ファイルからダンプします。
-m | 指定した数分間の情報のみ表示します。
-n | 最新のイベントを指定した数だけ表示します。
-o | 指定したソースのイベントのみ表示します (Windows System Restore Service の場合は -o SRService など)。
-q | 指定したソースのイベントを除外します (-o の逆です)。
-r | 順序を逆にします (最も古いものから順番にログ イベントをダンプします)。
-s | 区切り文字で囲まれたフィールド内に各行のレコードを並べます。
-t | -s の出力に使用するコンマ以外の区切り文字を指定します。
-w | 新しいイベントが挿入されるのを待機し、リアルタイムでダンプします。ローカル システムにのみ適用されます。
-x | イベント ログから拡張データをダンプします。
eventlog | ダンプするイベント ログを指定します。既定値は System です。
@file | テキスト ファイルに指定されたすべてのコンピュータでコマンドを実行します。
Windows イベント ログは非常に有効な診断ツールです。重要なことは、操作や統合が可能な形式でデータを出力することです。PsLogList は、この重要な処理を実行します。

PsPasswd
PsPasswd は、単純であると同時に非常に有効なユーティリティです。Net.exe と同様の機能の一部を持つように設計されていますが、リモートでの実行と自動化に対する配慮が付加されています。
PsPasswd  \\computer -u username -p password Username Newpassword
コンピュータの指定、コンピュータの指定なし (ローカル システム)、または \\* と指定して現在のドメイン内のすべてのコンピュータに対してユーティリティを実行することが可能です。PsPasswd には、指定可能な追加のパラメータが 1 つだけあります。@file を指定すると、テキスト ファイルに指定されたすべてのコンピュータに対してコマンドが実行されます。他のユーティリティと同様、非常に多数のシステムに対して機能する基本的なユーティリティです。

PsService
PsService を使用すると、ネットワーク上の 1 つ以上のシステムのサービス コントロール マネージャ (SCM) 情報を表示および編集できます。さらに、ネットワーク上のシステムで特定のサービス名を検索することも可能です。
PsService \\computer -u username -p password command options
PsService を実行するとき、command には図 7 に示されたいずれかのコマンドを指定し、options には特定のコマンドに適用する属性を指定します。追加のコマンド スイッチを指定しない場合、PsService は SCM の全情報をダンプします。
Figure 7 PsService のコマンド (Close Figure 7)

コマンド | 説明
query | 特定のサービスに対するクエリを実行します。
config | 特定のサービスの構成情報を問い合わせます。
setconfig | 特定のサービスの構成情報を設定します。
start | サービスを起動します。
stop | サービスを停止します。
restart | サービスを再起動 (停止して起動) します。
pause | サービスを一時停止します。
cont | 一時停止したサービスを再開します。
depend | 特定のサービスに依存するサービスを表示します。
find | サービスの特定のインスタンスをネットワークで検索します。
security | 特定のサービスのセキュリティ情報を提供します。
PsService は、強力かつリモート実行が可能なコマンドライン版の Services.msc であると考えることができます。ただし、PsService では、ネットワーク中のサービス (危険を伴う可能性があるサービスなど) を検索し、構成情報を設定することも可能です。

PsShutdown
PsShutdown は、私のもう 1 つのお気に入りです。このタスクは組み込みのツール (shutdown.exe) で処理されるとも言われていますが、実際には異なります。主な違いは、PsShutdown の機能にあります。具体的には、リモート システムのシャットダウンと再起動が可能なことです。また、シャットダウンと再起動だけでなく、システムをスタンバイ モードまたは休止状態に設定でき、システムをロックし、一定時間ユーザーにメッセージを表示した後にシステムを再起動できます。
PsShutdown \\computer -u username -p password
図 8 に示すように、PsShutdown で使用できる追加のパラメータは多数あります。
Figure 8 PsShutdown のスイッチ (Close Figure 8)

スイッチ | 説明
-a | PsShutdown によって開始された既に進行中のシャットダウンを中止します。
-c | 対話ユーザーによるシャットダウンの中止を許可します。
-d | コンピュータを中断します (スタンバイ)。
-e | シャットダウンの理由コード。理由コードについては、PsShutdown と組み込みの shutdown.exe の両方で使用すると問題が発生する可能性があるため、Microsoft Web サイトを参照することをお勧めします。詳細については、msdn2.microsoft.com/en-us/library/aa376885.aspx を参照してください。
-f | 実行中のすべてのアプリケーションを強制終了します。
-h | コンピュータを休止状態にします。
-k | コンピュータの電源を切ります (電源の切断がサポートされない場合は再起動します)。
-l | コンピュータをロックします。
-m | 対話ユーザーに表示するメッセージを指定します。
-n | リモート コンピュータとの接続に失敗するまでの待ち時間のタイムアウトを指定します。
-o | コンソール ユーザーをログオフします。
-r | コンピュータを再起動します。
-s | シャットダウンし、電源を切りません。
-t | シャットダウン コマンドを実行するまでの時間、または電源を切断するまでの特定の時間。
-v | シャットダウンするまでユーザーにメッセージを表示します。
@file | テキスト ファイルに指定されたすべてのコンピュータでコマンドを実行します。
PsShutdown は、非常に有効な、広範囲にわたる構成が可能なシステム電源管理ユーティリティです。このように多機能でありながら、比較的使いやすいツールです。

PsSuspend
PsSuspend は、不正なプロセスを一時的に制御する場合、またはデータやアプリケーション コンテキストを失うことなく CPU 使用率の高いプロセスを一時的に停止する場合に便利なユーティリティです。
PsSuspend \\computer -u username -p password process ID
プロセス ID は、PsList を使用して取得できます。中断されたプロセスは、-r スイッチを使用して再開できます。プロセスの中断と再開のコンセプトは、Process Explorer でも実装されますが、Process Explorer の場合はローカルでのみ動作します。PsSuspend は、リモートでもローカルでもプロセスの中断と再開が可能であるという点で、組み込みの Process Explorer の実装よりも優れています。

まとめ
PsTools スイートは、私にとって極めて重要なユーティリティ セットです。いずれかのシステムで Windows の再インストールを行った場合、他の Sysinternals ユーティリティ (具体的には、Regmon、Filemon、Process Explorer、および Process Monitor) と共に、最初にパスに保存するのは PsTools のプログラムです。PsTools を既にご存じの読者、またはそうでない読者も、このコラムがツールに関する理解を深め、新しい情報の収集に役立つことを期待しています。長年にわたってツールを無償で提供し、このコラムの執筆に当たってご助力いただいた Mark Russinovich に感謝します。

Wes Miller は、テキサス州オースティンにある Pluck 社 (www.pluck.com) の開発マネージャです。以前は、オースティンにある Winternals Software に勤務しており、その前はマイクロソフトで Windows のプログラム マネージャとプロダクト マネージャを兼任していました。Wes の連絡先は、technet@getwired.com です。


 Microsoft.com の内部事情: データベース ミラーリングの概要
Microsoft.com の内部事情
データベース ミラーリングの概要
Saleem Hakani

使用中のデータベースがいきなりオフラインになったらどうしますか? SQL Server 2005 SP1 のデータベース ミラーリング機能を使用すれば、障害を防ぐことができます。この新しい高可用性テクノロジでは、実稼働データベース サーバーが使用できなくなったときに備えて、もう 1 つのデータベースをホット スタンバイ状態で稼働しておけるのです。
データベース ミラーリング機能は、プライマリ サーバーのデータベースのトランザクション ログ レコードを、ホット スタンバイ状態のセカンダリ サーバーに転送することによって機能します。データの変更内容は、SQL Server™ の通常の更新動作と同じように、実際のデータ ページに適用される前にトランザクション ログに記録されます。このログ レコードは、プリンシパル データベースのメモリ内ログ バッファに書き込まれ、その後ディスクに保存されます。同じログは、ミラー サーバーのデータベースにもコピーされ、再生されます。これで、プリンシパル データベースの変更内容がミラー データベース上にコピーされます。なお、クライアント接続からアクセスできるのはプリンシパル データベースだけです。プリンシパル データベースがクライアントからの変更要求を受け取ると、プリンシパル サーバーにより、アクティブな変更内容がミラー サーバーに送信されます。一方、ミラー側では、このような決定処理は行われません。データベース ミラーリング機能を有効にすると、プリンシパル データベースで障害が発生した場合に、ミラー データベースが使用可能になります。

データベース ミラーリング機能のしくみ
データベース ミラーリング機能は、SQL Server 2005 をサポートするすべての標準ハードウェアに対応し、データベース障害の発生時にデータが失われないよう保護します。ミラー データベースは、プライマリ データベース サーバー上で実行されるトランザクションによって常時更新されます。図 1 に、このデータ フローを示します。
プリンシパル サーバーがダウンしても、前回トランザクションがコミットされた時点のプリンシパル データベースがミラー サーバーに正確にコピーされているので安心です。このミラー サーバーで、プリンシパル サーバーの役割を即座に引き継ぐことができます。
Figure 1 Data replication to the mirror
Figure 1 Data replication to the mirror (画像を縮小するには、ここをクリックします)
Figure 1 Data replication to the mirror
Figure 1 Data replication to the mirror (画像を拡大するには、ここをクリックします)
プリンシパルからミラー、またはミラーからプリンシパルに自動的にフェールオーバーするためには、データベース ミラーリング トポロジにミラーリング監視サーバーと呼ばれる 3 台目のサーバーを用意する必要があります。SQL Server 2005 をサポートしていれば、どのコンピュータでもミラーリング監視サーバーに指定できます。

動作モード
どのようなデータベース ミラーリング トポロジを使用するかは、トランザクションの安全性と動作モードの選択によって異なります。データベース ミラーリング機能で選択できる動作モードには、高安全性モード (自動フェールオーバーは有効または無効) と高パフォーマンス モードがあります。
高安全性モード (自動フェールオーバー有効)。ミラー データベースへの同期データ転送および自動フェールオーバーにより、データベースの可用性を最大限に高めます。プリンシパル サーバーとミラー サーバー間の通信の信頼性と速度が優れており、単一データベースの自動フェールオーバーが必要な場合に最適です。この動作モードでは、プリンシパル データベースは、ミラー サーバーからトランザクション ログをディスクに保存したというメッセージを受け取ってからトランザクションをコミットします。
高安全性モード (自動フェールオーバー無効)。ミラー データベースへの同期データ転送により、データベースの可用性を最大限に高めます。ただし、自動フェールオーバーは行いません。このモードでは、ミラー サーバー インスタンスが使用できなくなってもプリンシパル サーバー インスタンスは無事ですが、データのミラーリングはできなくなります。プリンシパル サーバーがダウンした場合、データベース ミラーリングは中断されます。サービスの強制的なフェールオーバーは、手動で実行することができます。
高パフォーマンス モード。非同期データ転送を行います。プリンシパル サーバーは、上の 2 つのモードとは異なり、ミラーからの受信確認を待ちません。ミラー サーバーはプリンシパル サーバーとの同期を最大限確保しようとしますが、プリンシパル サーバー上の最新のトランザクションがすべてミラー サーバーのトランザクション ログに保存される保証はありません。プリンシパル サーバーがダウンした場合、データベース ミラーリングは中断されます。サービスの強制的なフェールオーバーは、手動で実行することができます。

準備作業
ベスト プラクティスに従ってしっかり下準備をしておけば、データベース ミラーリングのセットアップは簡単です。
サーバーのエディション プリンシパル サーバーとミラー サーバーで実行されている SQL Server 2005 のエディションが同じであることをもう一度確認してください。Standard Edition または Enterprise Edition のいずれかを使用できます。
ミラーリング監視サーバーの可用性 自動フェールオーバーが有効な高安全性モードを使用する計画の場合は、SQL Server 2005 (任意のエディション) がインストールされたミラーリング監視サーバーが使用できることを確認してください。ミラーリング監視サーバーは、SQL Server 2005 をサポートする信頼性の高い任意のコンピュータ システムで実行できます。
ミラー イメージ ミラー サーバー インスタンスとプリンシパル サーバー インスタンスのジョブ、ログイン、SQL Server Integration Service (SSIS) パッケージ、ディスク パーティション、ファイルの格納場所、およびサーバー構成が完全に一致していることを確認してください。ミラー サーバーをプリンシパル サーバーとまったく同じ構成にすることで、プリンシパル サーバーと同じように動作させることができます。
完全復旧 データベース ミラーリング機能を使用するすべてのデータベースは、完全復旧モデルに設定する必要があります。
マスタ データベースと TempDB ミラーリング トポロジに含まれるすべてのサーバー インスタンスで、マスタ データベースと TempDB の照合順序およびコード ページが一致していることを確認してください。照合順序やコード ページが異なる場合、データベース ミラーリングのセットアップ中に問題が発生することがあります。
バックアップ ミラー化するデータベースのサイズが大きい場合は、最初にデータベースの完全バックアップを実行します。その後、ミラー サーバー インスタンス上で NORECOVERY オプションを使用してバックアップを復元します。
事前の計画 サーバー名、ポート番号、セキュリティ アカウント、およびデータベースの配置場所をすべて事前に決定し、文書化しておきます。補足記事「データベース ミラーリングのベスト プラクティス」のチェックリストを参照してください。
準備作業が完了したら、いよいよデータベース ミラーリングのセットアップ開始です。

セットアップ
では、データベース ミラーリングのセットアップを開始しましょう。ここでは、自動フェールオーバーを有効にした高安全性モードを選択するので、前述のようにミラーリング監視サーバーが必要になります。図 2 に、サンプルのサーバー名、データベース名、および各サーバーの役割を示します。
データベース ミラーリングでは、保留中のトランザクション ログをプリンシパル サーバーからミラー サーバーにコピーします。このため、構成内容によってはパフォーマンスに悪影響が出る場合があります。データベース ミラーリングの初期構成は、ピーク時を避けて行うことをお勧めします。
ミラーのセットアップは 3 段階で行います。まず、データベース ミラーリングに使用する各サーバー上にエンドポイントを作成します。次に、プリンシパル データベースのバックアップと復元を実行します。そして最後に、データベース ミラーリングに使用するすべてのサーバー上でセッションのミラーリングを有効にします。
データベース ミラーリング セッションを開始する前に、データベース ミラーリングに使用するすべてのサーバーの通信メカニズムを確立する必要があります。このためには、ServerA と ServerB の両方で次のステートメントを実行することにより、すべてのサーバー上にエンドポイントを作成します。
Create Endpoint Mirroring_Endpoint
State= Started as TCP (Listener_Port=5001)
For Database_Mirroring (Role=Partner);
ServerC (ミラーリング監視サーバー) では、このステートメントの (Role=Partner) の部分を (Role=Witness) に変更して実行します。これで、各インスタンスがリッスンする TCP ポートが決まります。
次に、データベースの完全バックアップを実行し、続いてプリンシパル サーバーの DBM_Demo データベースのログ バックアップを実行します。その後、NORECOVERY オプションを指定して、このバックアップをミラー サーバー インスタンス上で復元します。NORECOVERY オプションを指定すると、ミラー データベースは "復元中" 状態になるので、トランザクション ログを適用することができます。
次の T-SQL ステートメントを実行すると、ServerA (プリンシパル サーバー インスタンス) の DBM_Demo データベースの完全バックアップが実行されます。
Backup Database DBM_Demo to DISK='E:\MSSQL\Bak\DBM_Demo_FULL.bak';
データベースの完全バックアップの実行後に、データベースに変更が加えられた場合は、データベースのログ バックアップを実行します。変更がない場合は必要ありません。
必要に応じ、次の T-SQL ステートメントを使用して、ServerA の DBM_Demo データベースのログ バックアップを実行します。
Backup Log DBM_Demo to Disk='E:\MSSQL\Bak\DBM_Demo_Log.bak';
すべてのバックアップが完了したら、ServerB 上でバックアップを復元できるように、バックアップ ファイルを ServerB または共有の場所に移動します。バックアップ ファイルを ServerB 上で復元したら、前回 ServerA のデータベースの完全バックアップを実行した後に実行したすべてのトランザクション ログ バックアップも復元します。
次の T-SQL ステートメントを実行すると、ServerB 上で、完全バックアップおよびログ バックアップの復元 (NORECOVERY オプション指定) が実行されます。
--Restore full database backup on the mirror --server instance
Restore Database DBM_Demo from Disk='E:\MSSQL\Bak\DBM_Demo_FULL.bak' with NORECOVERY;
最後に、次の T-SQL ステートメントを実行します。このステートメントでは、ミラー サーバー上で、ログ バックアップの復元 (NORECOVERY オプション指定) が実行されます。
Restore Log DBM_Demo from Disk='E:\MSSQL\Bak\DBM_Demo_Log.bak' with NORECOVERY;
すべてのバックアップを復元できたら、最終段階です。データベース ミラーリングに使用するすべてのサーバー上で、データベース ミラーリング セッションを有効にします。
データベース ミラーリング セッションをセットアップするには、各 サーバー インスタンスのサーバー ネットワーク アドレスが必要です。このアドレスは各サーバー インスタンスを識別するアドレスであり、システム アドレスとそのサーバー インスタンスがリッスンしているポート番号で構成されます。サーバー ネットワーク アドレスは、次のようになります。
TCP://<System-address>:<port>
<System-address> の部分は、完全修飾ドメイン名または IP アドレスで置き換えます。この情報を確認するには、ローカル コンピュータのコマンド プロンプトで IPCONFIG を実行します。
<Port> の部分は、エンドポイントの作成時に設定したポート番号で置き換えます。
次のステートメントを実行して、ServerB 上でデータベース ミラーリング セッションを開始します。
Alter Database DBM_Demo
Set Partner= 'TCP://ServerA.com:5001';
続いて次の T-SQL ステートメントを実行し、ServerA 上でもセッションを開始します。
Alter Database DBM_Demo
Set Partner='TCP://ServerB.com:5001';
さらに、ServerC (ミラーリング監視サーバー) 上でミラーリング セッションを有効にします。
Alter Database DBM_Demo
Set Witness='TCP://ServerC.com:5001';
これで、データベース ミラーリング機能の設定は完了です。DBM_Demo データベース上でデータベース オブジェクトが追加または変更されると、同じ内容が ServerB 上のミラー データベースに転送されます。ServerA のデータベースが使用できなくなった場合は、フェールオーバーが行われ、ミラー データベースがプリンシパルの役割を引き継ぎます。
これで、データベース ミラーリング機能の導入は完了です。ホット スタンバイ状態のデータベースが待機しているので、実稼働データベースがダウンしても、対策は万全です。

Saleem Hakani は、Microsoft で 14 年以上データベース システム関係の業務を担当しているシニア データベース エンジニアです。彼は、Microsoft SQL コミュニティの創設者として、SQL Server における標準の策定と Windows Live サービス全体での自動化業務に従事しており、MCTS、MCDBA、および MCSA の資格を取得しています。連絡先は、Saleem@sqlcommunity.net (英語のみ) です。


 フィールド ノート: PC ドクターの登場
フィールド ノート
PC ドクターの登場
Matt Hester

最近 、情報技術者は医者に似ていると思うようになりました。これは、はじめて Windows Vista™ を使ったときに頭に浮かんだ新発見です。当時、私はネットワーク接続の問題を抱えていました。何時間も ping や ipconfig を実行し、再起動を繰り返しているうちに、すべての情報技術者が共有する "診断" という言葉に思い当たり、この言葉に本能的に好奇心をそそられました。普段、オペレーティング システムを操作していると、"修復"、"状態"、"タスク マネージャ"、"エラー報告を送信する" といった、あまり一般的でない機能を操作しやすくするための言葉を目にすることがあります。"診断" という言葉を見て、私は情報技術者と医者の類似を連想しました。
まず、医者も情報技術者も、名前の後ろに特定の略語を付けるために資格試験や認定を受けます。その頭字語によって自分の専門を明らかにし、願わくは壁に飾る証書や名刺で印象付けたいと考えます。
医者と同様、情報技術者にも問題を解決するためのさまざまなリソースがあります。医者は時に同僚に相談し、時に専門誌やインターネットを検索します。我々、情報技術者も、同僚に相談したり、インターネットや技術誌を検索したりして (もちろん、TechNet Magazine が第一です)、問題の解決に役立てます。
また、医者も情報技術者も信頼できるツールを頼りにしています。医者には聴診器などの信頼できる器具があり、情報技術者には ping があります。どちらも現状を確認するツールです。
最後の共通点は社交場の立場です。医者も、情報技術者も、社交の場に出ると、自分の職業を明らかにしないことが重要だということをしばしば思い知らされます。最近出席したパーティーでも、どういうわけか私の職業が嗅ぎつけられ、私はたちまち人気者になりました。ただ、この人気には対価が求められます。私は人気と引き換えに、一人の魅力的な人間としての個性を失うのです。私は単なる "コンピュータ屋さん" 扱いになり、挙句の果てには、否応なくパーティー客全員のオンサイト サポート技術者にされてしまいました。「コンピュータ屋さん、うちのコンピュータが今朝クラッシュしたんだけど、どうしてなの?」「コンピュータ屋さん、Any キーってどこにあるの?」、「コンピュータ屋さん、私の Mac 直してもらえるかしら?」最悪なのは、部屋の向こうにいる医者が訳知り顔に満面の笑みを浮かべながら、止まることなく踊り続ける姿を目撃したことでした。
話を接続の問題に戻しましょう。接続できずにあれこれ試して 3 時間ほど経ってから、見つけた [診断と修復] ボタンをクリックしてみました。次のような応答画面を目にしたときの私のショックと困惑を想像してください。

(画像を縮小するには、ここをクリックします)
私はあっけにとられ、顔をほてらせながら、部屋中を見回して、誰も見ていないことを確認しました。それから、持参したパソコンを取り出してケーブルに接続したのです。あの最高の日以来、私はさらに多くの時間を Vista と共にすごし、大いに診断機能を利用しました。診断機能のおかげで、多くの問題の原因を格段に短時間で突き止められるようになりました。[問題のレポートと解決策] コントロール パネルとの連携にも優れていて、追加情報をオンラインで検索できます。いらいらして髪の毛をかきむしる前に、この機能を使ってみてください。
あの晩は、眠りに落ちながら、ネットワーク接続の問題を見つけて無事解決した満足感に浸って考えました。これでゴルフをやる時間を増やせるかな。新品の愛車を乗り回すこともできるんじゃないかな。

Matt HesterMicrosoft Across America の TechNet プレゼンタ。著者のプレゼンテーションの詳細については、technetevents.com/mhester (英語) を参照してください。blogs.technet.com/matthewms (英語) ではブログも公開されています。


 Windows 秘話: ばかな方が賢く見えることもある
Windows 秘話
ばかな方が賢く見えることもある
Raymond Chen

お使いの Windows® コンピュータに CD を挿入すると、前回指定したにもかかわらず、実行する動作を選択するダイアログ ボックスが表示されることがあります。なぜ Windows は自動再生の設定を忘れてしまうのでしょうか。ただ実際には忘れているわけではないのです。ただ再確認しているだけなのです。
Windows XP による CD 自動再生の処理方法には、2 つの問題がありました。1 つは、CD 自動再生をサポートするプログラムのインストール後に、そのプログラムを新しい既定の CD 自動再生プログラムに設定する方法がわかりにくいことでした。以前にプログラムを選択して [常に選択した動作を行う] をオンにしたことがあると、この選択を元に戻すことも、新しいプログラムを既定のプログラムとして選択するダイアログ ボックスを再表示させることも簡単にはできませんでした。
もう 1 つは、一部の行儀の悪いプログラムをインストールすると、文書化されていない CD 自動再生の設定をこっそり上書きして、そのプログラムを既定の CD 自動設定ハンドラとして設定してしまうことです。
まとめると、ユーザーにとってこの 2 つの問題は、「この新しくインストールしたプログラムを CD の自動再生プログラムにしたい」またはその逆に、「この新しくインストールしたプログラムを CD の自動再生プログラムにしたくない」ということでした。
Windows Vista treats autoplay settings globally
Windows Vista treats autoplay settings globally (画像を縮小するには、ここをクリックします)
Windows Vista treats autoplay settings globally
Windows Vista treats autoplay settings globally (画像を拡大するには、ここをクリックします)
Windows XP Service Pack 2 (SP2) では、このような問題に対処するために CD 自動再生の新しい動作が導入されました。新しい CD の自動再生ハンドラが利用可能であると Windows が判断すると、CD の自動再生ダイアログ ボックスを再度表示するようになったのです。これによって、インストールしたばかりの新しいプログラムを選択する機会が与えられ、既定の再生プログラムとして勝手に設定されてしまうこともなくなりました。
また、Windows XP SP2 へのアップグレード後に初めて CD を挿入すると、CD の自動再生ダイアログ ボックスが表示されます。このダイアログ ボックスは、Windows XP SP2 へのアップグレード前にインストールされたハンドラに対処するための "遅くても表示しないよりはまし" なダイアログ ボックスです。
昔は、OS が関係するのは開発者と機能とのインターフェイスを取り持つことだけでした。ですが今では、プログラマがこのインターフェイスを不正に使用しないようにすることにも気を配る必要があります。
Windows がユーザーの自動再生の設定を忘れたように見えるもう 1 つ別の場合があります。USB ドライブなどのリムーバブル記憶装置を接続すると、既に [常に選択した動作を行う] をオンにしたことがある場合でもダイアログ ボックスが表示されます。これは、Windows が設定を忘れたためというよりも、すべての設定を覚えすぎているためなのです。
あるリムーバブル記憶装置のためのオプションを選択すると、Windows はそのデバイスの設定を記憶します。別のデバイスを接続すると、この別のデバイスの動作を指定していなかったためにダイアログ ボックスが新たに表示されます。この設計の意図は、お使いのデジタル カメラの既定の動作を "画像の表示" にする一方、音楽プレイヤーの既定の動作を "音楽の再生" にすることです (シリアル番号のないデバイスを異なる USB ポートに接続すると、別のデバイスとして扱われることになります)。
Windows XP の設計によって生じた混乱を踏まえて、Windows Vista™ ではこの動作が変更されています。自動再生の設定は、デバイスごとではなく、デバイス全体に対して行われるようになりました。[何もしない] を選択すると、Windows Vista では挿入または接続されたデバイスが何であれ何も実行しません。オペレーティング システムの機能を落として "もっとばかに" する方が賢く見える場合もあるのですね。

Raymond Chenは自分の Web サイト The Old New Thing (blogs.msdn.com/oldnewthing) および同じタイトルの書籍 (Addison-Wesley、2007 年) で、Windows の歴史と Win32 プログラミングについて扱っています。空いた時間で、７ 年生 (日本の中学 1 年生に相当) のエッセイを採点していることで知られています。