サイトコレクションのバックアップを使用してコンテンツを複製展開することの弊害

こんにちは SharePoint サポートの森 健吾 (kenmori) です。

今回の投稿では、サイトコレクションのバックアップを取得し、別の URL に複製を展開できることを利用して、大量展開することの危険性をご説明します。

サイト コレクションをバックアップし、別の URL としてコピーして復元し運用を続けると問題が生じます。移行の途中で一時的に重複することは問題ありません。ただし、その状況で使用し続けると問題に直面することになります。

サイトコレクションのバックアップ・リストアは障害復旧や、サイトコレクションの移動、再現環境のテスト環境への複製などで効果を発揮します。
サイトのエクスポートやインポート、サイト テンプレートなどよりも、エラーが発生する場合が少なく安定していることを理由に、これを使って大量にサイトを展開したいと考える人も多いでしょう。下記の公開情報の記述も誤解の要因になりがちです。

 

タイトル : Restore-SPSite
アドレス : https://technet.microsoft.com/ja-jp/library/ff607788(v=office.15).aspx

サイト コレクションがバックアップされ、同じ Web アプリケーション内の別の URL の場所に復元される場合は、サイト コレクションの復元されたコピーを保持するために追加のコンテンツ データベースを利用可能にする必要があります。

この内容を読み、新しいコンテンツ データベースを追加すれば、サイトコレクションを別の URL に複製しても良いと誤解するかもしれません。確かに異なるコンテンツ データベースにリストアを実施するとサイト配下の ID が重複しても主キー違反にはなりません。しかし、この記述をよく読むと、"コンテンツ データベースを追加すると、リストア操作が成功する" 以外の深い意図はありません。

実際に、別の URL に既存のコンテンツをリストアして複製すると、その後の運用において様々な悪影響が生じます。下記の内容を確認いただいて、バックアップ・リストアによるサイト コレクションのコピーを見直し、正規のコンテンツ展開方法であるエクスポート・インポート、サイト テンプレート、PowerShell コマンドレットによる自動化などを選択してください。

なお、Copy-SPSite コマンドを使用したサイトコレクションのコピーも同様の結果になりますのでご注意ください。

GUID が重複したサイトコレクションの検出方法 2015.05.25 追記

GUID が重複しているサイト コレクションを検出する PowerShell スクリプトを以下に記載します。
トップサイトの GUID でグループ化し、同じ GUID 2 つ以上あるサイト コレクションを詳細表示する内容です。

Get-SPSite -Limit ALL | group {$_.RootWeb.ID} | where Count -gt 1 | fl

 

上記の結果で /sites/bkcopydest と /sites/bkcopysource は重複していることが確認できます。

悪影響の一覧 (下記はすべてではありません)

・ワークフローを実行すると、同じバックアップで作成した別のサイト コレクションのワークフロー ロジックが実行される。(*1 詳細を後記します)
・他のサイトコレクションで利用可能なワークフローが、別のサイトコレクションで利用可能になる場合がある。またはその逆で利用できなくなる場合がある。
・IRM 保護されたライブラリから暗号化されたファイルをダウンロードし、同一の GUID を持つライブラリにアップロードすると別ライブラリであるにも関わらず暗号化が解除されてしまう。
・重複した GUID を持つ 2 つのアイテムのうち、片方のアイテムが削除されると増分クロールによって両方のアイテムが検索結果から消失する。

影響は特にワークフローにおいて、顕著に発生しますが、その他にも様々な影響が発生します。

 

サイトコレクションのバックアップと復元について

サイト コレクションのバックアップを復元すると、バックアップ元と同じ GUID を持つサイト、リスト、アイテムなどのオブジェクトが展開されます。
サイトコレクションのみ GUID が変更され、それ以外は完全に同じ GUID となります。GUID という形式は本来他の値とは完全に区別できる固有の値であることを意味し、重複することをアプリケーション側は全く想定していません。

 

ワークフローで発生する弊害 (*1) の要因

上記悪影響の一覧で赤字にしたワークフローについては特筆すべき事項として説明します。宣言型ワークフローは Workflows リストに XOML ファイルを格納します。サイトコレクションの機能などで展開されるワークフローは _catalogs/wfpub リストに展開されます。この XOML ファイルは Workflows リストの GUID とアイテムの Id (整数型) 、およびバージョンで一意に構成されます。

 

上記に説明しました通り、ワークフロー テンプレートが格納されたそれぞれのリストはバックアップ・リストアでサイトコレクションをコピーした場合、コピー元、コピー先サイトで GUID が重複します。その結果、ワークフロー テンプレートの格納リストは複製元と複製先は全く同じものと判断されます。

ワークフローの内部 ID は下記のような構文です。

Cfg.<Workflows リストの GUID>.<ItemId>.<Version>

 

宣言型ワークフローは、ワーカープロセス リサイクル直後、初回起動時においてテキスト形式のマークアップをバイナリの実行可能形式に変換するためにコンパイルを実施します。
このコンパイルは、負荷がかかる動作となりますため、同じアプリケーション プール上で内部 ID (上記コマンド <> 内) が重複するものがすでにコンパイル済みであれば再コンパイルを抑制します。その結果、他のサイト コレクション用にコンパイルされたワークフローのロジックが、別のサイトで再利用されてしまいます。この動作は製品の想定された動作です。

この結果、片方のサイトではワークフローが正常実行され、もう片方のサイトではエラー発生することがあります。また、作成したワークフローとは違う動作を実行する結果となります。
IISRESET やアプリケーション プール再起動後には、同じ ID を持つワークフローの内、先に起動したワークフローが正常動作となります。そのため、今度は以前異常だった方のサイトのワークフローが正常に動作し、正常動作していたワークフローが異常となります。

下記のような一時対処策もありますが、とても煩雑になりますし、根本的な再発防止策にはなりません。

・ワークフローを発行して、削除する操作を続けて、整数型の ItemId を変更して重複しないようにする

例)

Cfg.ca31399_2dde_498d_9da6_65c1a38c36aa.6.2048
Cfg.ca31399_2dde_498d_9da6_65c1a38c36aa.7.2048

・ワークフローを上書き発行し続けて、バージョンを離し、Version で重複しないようにする
Cfg.ca31399_2dde_498d_9da6_65c1a38c36aa.6.2048
Cfg.ca31399_2dde_498d_9da6_65c1a38c36aa.6.1024

 

このような状況になってしまった場合、サイトのエクスポート・インポートなどを使用して、再度データ移行しデータを修復することが根本解決策になります。
この状況に陥った後、復旧するとなると非常に多くの工数がかかりますし、ユーザー影響は甚大となります。この現象は氷山の一角で、他にも現象が 100% 再現しないまでも、時折予期せぬ様々な現象が発生することが報告されております。

設計段階より、バックアップ・リストアを使用した同じ GUID を持つサイトの大量展開という方法は、必ず避けるよう強くお願いいたします。

参考情報

バックアップ リストアに関連する過去の投稿をご紹介します。ご参考にしていただけますと幸いです。

タイトル : SharePoint 製品とテクノロジのバックアップと復元について考える Part 1
アドレス : https://blogs.technet.com/b/sharepoint_support/archive/2012/09/06/sharepoint-backup-restore-1.aspx

タイトル : SharePoint Server カスタマイズのバックアップ・移行について
アドレス : https://blogs.technet.com/b/sharepoint_support/archive/2014/11/28/sharepoint-server.aspx