異なるライターによって管理されるコンポーネント間の依存関係
あるライターのデータが、別のライターによって管理されるデータに依存する場合があります。 このような場合は、両方のライターからデータをバックアップまたは復元する必要があります。
VSS は、明示的なライター コンポーネント依存関係と IVssWMDependency インターフェイスの概念によってこの問題を処理します。
ライターは、 IVssCreateWriterMetadata::AddComponentDependency メソッドを使用してライター メタデータ ドキュメントを作成するときに、1 つ以上の依存関係を追加します。 ライターは、依存コンポーネント (管理する) の名前と論理パス、および依存するコンポーネントの名前と論理パスと ライター クラス ID (クラス を識別する GUID) をメソッドに渡します。
この依存関係が確立されると、バックアップまたは復元操作中に依存コンポーネントとその依存関係のターゲットの両方が参加する必要があることを要求者に通知します。
特定のコンポーネントは複数の依存関係を持つことができます。これには、そのコンポーネントとそのすべての依存ターゲットが一緒にバックアップと復元に参加する必要があります。
依存コンポーネントまたはその依存関係のターゲットは、バックアップ操作または復元操作に 明示的 または 暗黙的に 含めることができます。
明示的なライター コンポーネント依存関係メカニズムを使用して、同じライター上の 2 つのコンポーネント間に依存関係を作成しないでください。 選択規則は、循環依存関係のリスクなしに、同じ機能をより効率的に提供できます。
たとえば、 IVssCreateWriterMetadata::AddComponentDependency を使用して、ライター クラス ID X を持つ InternetConnector というライターのコンポーネント internetData (論理パス "") 上のライター MyWriter の依存関係 (論理パス "") を定義できます (一方、同じクラス ID を持つ複数のライターがシステム上に同時に存在する可能性があります)。 論理パスとコンポーネント名の組み合わせは VSS の下のシステムで一意であるため、混乱は避けられます。
ライターは、異なるライターの異なるコンポーネントで繰り返される IVssCreateWriterMetadata::AddComponentDependency を呼び出すだけで、特定のコンポーネントに複数の依存関係を追加します。 特定のコンポーネントが依存する他のコンポーネントの数は、VSS_COMPONENTINFO構造体の cDependencies メンバーを調べることで確認できます。
ライターまたはリクエスターは、 IVssWMComponent::GetDependency を使用して IVssWMDependency インターフェイスのインスタンス を取得します。 IVssWMDependency は、依存関係のターゲットであるコンポーネントを管理するライターのコンポーネント名、論理パス、およびクラス ID を返します。
依存関係メカニズムでは、依存コンポーネントとその依存関係のターゲットの間で、特定の優先順位は規定されません。 前述のように、すべての依存関係は、特定のコンポーネントがバックアップまたは復元されるたびに、依存するコンポーネントもバックアップまたは復元する必要があることを示しています。 依存関係の正確な実装は、バックアップ アプリケーションの裁量です。
たとえば、上記の場合、コンポーネント writerData (論理パス "") は、コンポーネント InternetConnector (論理パス "Connections") に依存します。 要求者は、次のいずれかの方法でこれを自由に解釈できます。
- 依存コンポーネント writerData がバックアップまたは復元のために (暗黙的または明示的に) 選択されている場合、リクエスターは依存関係 internetData のターゲットを (暗黙的または明示的に) 選択する必要があります
- 依存関係 internetData のターゲットがバックアップ用に選択されていない場合は、依存コンポーネント writerData を選択しないでください。
ただし、依存関係のサポートを開発する場合、要求者の開発者は、そのコンポーネントの 1 つが依存関係のターゲットであるかどうかをライターが判断する方法がないことを認識する必要があります。
リモート依存関係の宣言
分散アプリケーションは、一度に 1 つ以上のコンピューターを使用するように構成できるアプリケーションです。 通常、アプリケーションは 1 つ以上のアプリケーション サーバー コンピューターで実行され、1 つ以上のデータベース サーバー コンピューターと通信します (ただし、実際には実行される場合と実行されない場合があります)。 この構成は、マルチシステム展開と呼ばれることもあります。 多くの場合、アプリケーション サーバーとデータベース サーバーの両方を実行する 1 台のコンピューターで実行するように、同じアプリケーションを構成することもできます。 このような構成は、単一システム展開と呼ばれます。 どちらの構成でも、アプリケーション サーバーとデータベース サーバーには、それぞれ独立した VSS ライターがあります。
マルチシステム展開では、アプリケーションのライターによって管理されるコンポーネントが、データベース サーバーのライターによって管理されるリモート コンポーネントに依存している場合、これはリモート依存関係と呼ばれます。 (一方、単一システムのデプロイにはローカルの依存関係しかありません)。
マルチシステム展開の例として、SQL Server データベース サーバーをデータ ストアとして使用するアプリケーション サーバーを考えてみましょう。 Web パーツ、Web コンテンツ ファイル、IIS メタベースを含むアプリケーション固有のデータは、フロントエンド Web サーバーと呼ばれる 1 つ以上のコンピューターに存在します。 Config データベースと複数のコンテンツ データベースを含む実際の SQL データ ストアは、バックエンド データベース サーバーと呼ばれる 1 つ以上の他のコンピューターに存在します。 各フロントエンド Web サーバーには、同じアプリケーション固有のコンテンツと構成が含まれています。 各バックエンド データベース サーバーは、任意のコンテンツ データベースまたは Config データベースをホストできます。 アプリケーション ソフトウェアは、データベース サーバーではなく、フロントエンド Web サーバーでのみ実行されます。 この構成では、アプリケーションの VSS ライターは、SQL ライターによって管理されるコンポーネントにリモート依存関係があります。
ライターは 、AddComponentDependency メソッド ("\\RemoteComputerName\") を呼び出すことでリモート依存関係を宣言できます。 RemoteComputerName は、リモート コンポーネントが存在するコンピューターの名前を wszOnLogicalPath パラメーターの論理パスに指定します。 RemoteComputerName の値には、IP アドレスまたは GetComputerNameEx 関数によって返されるコンピューター名を指定できます。
Windows Server 2003: ライターは、Windows Server 2003 Service Pack 1 (SP1) までリモート依存関係を宣言できません。
依存関係を識別するために、要求者は IVssWMDependency インターフェイスの GetWriterId、GetLogicalPath、および GetComponentName メソッドを呼び出します。 要求者は、 getComponentName が pbstrComponentName パラメーターで返すコンポーネント名を調べる必要があります。 コンポーネント名が "\\" で始まる場合、要求者はリモート依存関係を指定し、"\\" の後の最初のコンポーネントが、ライターが AddComponentDependency を呼び出したときに指定された RemoteComputerName であると想定する必要があります。 コンポーネント名が "\\" で始まらない場合、リクエスターはローカル依存関係を指定すると想定する必要があります。
リモート依存関係がある場合、リクエスターはローカル コンポーネントをバックアップするときにリモート コンポーネントをバックアップする必要があります。 リモート コンポーネントをバックアップするには、要求元がリモート コンピューターにエージェントをインストールし、リモート コンピューターでバックアップを開始する必要があります。
リモート依存関係の構造化
依存関係は、それ自体のコンポーネントではないことを理解することが重要です。 依存関係を保持するには、コンポーネントが必要です。
次の例では、一連の依存関係を構造化する 2 つの方法を示します。
Example 1:
Writer 1
Component A
File A
File B
Dependency (SQL/MSDE Writer, Component X, "\")
Dependency (SQL/MSDE Writer, Component Y, "\")
Example 2:
Writer 2
Component A
File A
File B
Component B
Dependency (SQL/MSDE Writer, Component X, "\")
Dependency (SQL/MSDE Writer, Component Y, "\")
例 1 では、依存関係はコンポーネント A によって保持されます。個々のファイルではなくコンポーネントのみを選択できるため、コンポーネント A の依存関係をこのように構成するには、コンポーネント全体 (ファイルと依存関係の両方) を常にバックアップして復元する必要があります。 個別にバックアップまたは復元することはできません。
例 2 では、個別のコンポーネント (コンポーネント A と B) が各依存関係を保持しています。 この場合、2 つのコンポーネントを個別に選択できるため、個別にバックアップおよび復元できます。 このように依存関係を構造化することで、分散アプリケーションのリモート依存関係を管理する柔軟性が大幅に向上します。
リモート依存関係のサポート
要求者は、リモート依存関係の完全または部分的なサポートを提供できます。
完全なサポートを提供するには、リクエスターはバックアップと復元時に次の操作を行う必要があります。
バックアップ時に、リクエスターはフロントエンド (ローカル) コンピューターでバックアップを開始し、存在する依存関係を決定し、バックエンド データベースをキャプチャするために追加のバックアップ ジョブをスプールする必要があります。 リクエスターは、リモート コンピューター上のバックエンド バックアップ ジョブが完了するまで待ってから、 IVssBackupComponents::SetBackupSucceeded メソッドと IVssBackupComponents::BackupComplete メソッドを呼び出す必要があります。 リクエスターは、 BackupComplete を呼び出す前にバックエンド コンポーネントのバックアップが完了するまで待機すると、バックアップ中にトポロジロックなどの追加の拡張機能を実装するライターに対して、より簡単に回復可能なバックアップが生成されます。 次の手順では、要求者が実行する必要がある操作の概要を示します。
- ローカル コンピューターで、リクエスターは IVssBackupComponents::InitializeForBackup、 IVssBackupComponents::GatherWriterMetadata、 IVssBackupComponents::P repareForBackup、 IVssBackupComponents::D oSnapshotSet メソッドを呼び出します。
- ローカル シャドウ コピーが完了した後、バックアップが完了する前に、リクエスターはリモート コンピューター上のエージェントに要求を送信することで、追加のバックアップ ジョブをスプールします。
- リモート コンピューターでは、要求元のエージェントが InitializeForBackup、 GatherWriterMetadata、 PrepareForBackup、 DoSnapshotSet、 SetBackupSucceeded、 BackupComplete を呼び出して、スプールされたバックアップ シーケンスを実行します。
- 要求者のエージェントがリモート コンピューターでスプール ジョブを完了すると、要求元は SetBackupSucceeded と BackupComplete を呼び出してバックアップ シーケンスを完了します。
復元時に、リクエスターはフロントエンド (ローカル) コンピューターを含む復元を開始し、復元するコンポーネントとその依存関係を選択してから、IVssBackupComponents::P reRestore メソッドを呼び出して PreRestore イベントを送信する必要があります。 その後、リクエスターはリモート コンピューターでバックエンド復元ジョブをスプールし、バックエンドの復元が完了したときに IVssBackupComponents::P ostRestore メソッドを呼び出す必要があります。 この要件により、フロントエンド ライターは復元エクスペリエンスをより詳細に制御でき、全体的な管理者ユーザー エクスペリエンスが向上します。 各システムのバックアップは同じ時点で行われるわけではないため、フロントエンド ライターはバックエンド データのクリーンアップを実行する必要があります。 前述の「リモート依存関係の宣言」で説明したアプリケーション例では、ライターは、バックエンド データベースの復元が完了した後、サイトの再マップまたはインデックス再作成を開始する必要があります。 これを行うには、ライターがフロントエンド サーバーでイベントを受信する必要があります。 次の手順では、要求者が実行する必要がある操作の概要を示します。
- ローカル コンピューターでは、リクエスターは IVssBackupComponents::InitializeForRestore、 GatherWriterMetadata、 IVssBackupComponents::SetSelectedForRestore (または IVssBackupComponentsEx::SetSelectedForRestoreEx)、 PreRestore を呼び出します。
- PreRestore フェーズが完了した後、PostRestore フェーズが開始される前に、リクエスターはリモート コンピューター上のエージェントに要求を送信することで、追加の復元ジョブをスプールします。
- リモート コンピューターでは、要求元のエージェントは、InitializeForRestore、GatherWriterMetadata、SetSelectedForRestore、PreRestore、SetFileRestoreStatus (または SetSelectedForRestoreEx)、および PostRestore を呼び出して、スプールされた復元ジョブを実行します。
- リクエスターのエージェントがリモート コンピューターでスプール ジョブを完了すると、要求元は IVssBackupComponents::SetFileRestoreStatus と PostRestore を呼び出して復元シーケンスを完了します。
リモート依存関係の部分的なサポートを提供するには、リクエスターはリモート依存関係に従い、バックアップの一部として含める必要がありますが、前の 2 つの手順で説明したように、フロントエンド システムとバックエンド システムでのイベントの順序は必要ありません。 部分的なサポートのみを実装するリクエスターの場合、リクエスターはライター アプリケーションのバックアップ/復元に関するドキュメントを参照して、サポートできるシナリオを理解する必要があります。