中断した移行が、単に「途中まで」の状態とは限りません。1つの単位を保存する前に停止した場合もあれば、一部の変更を確定した後や、移行先から曖昧な応答が返った時点で停止した場合もあります。プロセス自体は終了していても、差異が残っている可能性もあります。続行方法を決めるには、終了コードや最後に記録されたIDだけを頼りにせず、検証可能な証拠をもとに何が起きたかを再構成する必要があります。
実務上の問いは、PHPで失敗したデータ移行をどう再開するかだけではありません。各単位の状態について何を断定できるのか、操作を繰り返す前にどのような確認が必要なのかも重要です。この違いを明確にすることで、重複、リレーションの破損、監査が難しい手作業での修正のリスクを抑えられます。
まず、停止した実行と差異のある移行を区別する

停止した実行とは、例外、接続断、運用上の介入などにより、プロセスの進行が止まった状態です。一方、差異のある移行とは、エラーなくプロセスが終了していても、結果が期待した条件を満たしていない状態です。行が欠落していたり、キーが誤って変換されていたり、リレーションが不完全だったりすることがあります。
そのため、完了や失敗のような全体状態だけでは不十分です。少なくとも、実行中、停止、完了、差異を伴う完了を区別するのが望ましいでしょう。全体状態は作業の概要を示すものであり、単位ごとの記録や結果の検証に代わるものではありません。
コマンドを再実行する前に、利用可能なログを保全し、この段階でどのシステムを正とするかを明確にしてください。移行後の書き込み、手動変更、並行プロセスがある場合は、それらが比較にどう影響するかを特定します。この情報がないまま続行すると、調査可能な差異が追跡不能になるおそれがあります。
作業単位と検証可能なチェックポイントを定義する
データと復旧方法に適した作業単位を選びます。エンティティ、関連レコードのグループ、安定したパーティションなどが考えられます。チェックポイントを単に「最後に処理したID」にするのは避けてください。そのIDから分かるのは、せいぜいプログラムがある位置まで到達したことだけです。それ以前のすべてのレコードが正しく保存されたことや、移行先に整合性があることまでは証明できません。
各単位について、安定したソースキー、実行のバージョンまたは識別子、状態、検証可能な結果を保持します。チェックポイントは移行先のデータと照合できる必要があります。たとえば、移行先キー、関連フィールドから計算したハッシュ、検証クエリなどを使えます。処理中にデータが変わる可能性がある場合は、選択条件や適用したカットオフ時点も記録してください。
設計は環境によって異なります。ソースと移行先が同じトランザクションを共有するなら、両方が同時に確定したことを示す証拠になる場合があります。別々のシステムであれば、両者の間にアトミック性があると想定してはいけません。API連携では、応答が失われると、サーバーが操作を適用したかどうか分からなくなることがあります。戦略にはその不確実性を反映し、単位を自動的に失敗または確定と分類するのではなく、後から確認できる手段を用意してください。
単位ごとに試行内容と確定内容を記録する
サポートに役立つ記録があれば、誰が移行を実行し、どの単位を処理し、いつ状態が変わり、どの証拠があるのかを確認できます。処理済み(コードが手順を実行した)と、確定済み(期待した結果が移行先に存在する信頼できる証拠がある)を区別してください。試行回数、エラーの分類、プロセスのイベントと外部呼び出しを関連付ける相関IDも記録します。
状態はアルゴリズムの段階だけでなく、運用上の状況を表すべきです。たとえば、保留中、処理中、確定不明、確定済み、要確認です。単位が処理中の状態でプロセスが終了した場合、再起動後は移行先を検証するまで不確定として扱います。効果が発生したかを確認せずに失敗とマークしてはいけません。
調査に必要な情報は記録しつつ、認証情報、秘密情報、不要な個人データをログに出力しないでください。追跡可能性を高めるためにデータの露出まで増やすことがないよう、エラーから対象の単位と操作を特定できるようにします。また、誰がログを参照でき、どの期間保持するかも定めてください。
続行方法を決める前に不変条件を比較する
不変条件とは、移行の実装方法にかかわらず満たすべき条件です。種類別やパーティション別の件数は差異の発見に役立ちますが、それだけでは不十分です。2つの集合のサイズが同じでも、含まれるレコードが異なることがあります。業務キー、レコードの有無、リレーション、許可される状態や再計算された金額などの重要なルールを比較してください。
影響度とデータ量に応じた検証方法を選びます。サンプルは診断に使えますが、それだけで全体の正しさを証明することはできません。網羅的に検証する場合は、キーまたはハッシュをブロック単位で比較し、確認した範囲を記録します。変換によって意図的にフィールドが変わる場合は、想定される差異とエラーを示す差異を明記してください。
ソースが引き続き更新される場合は、並行処理に起因する差異と、移行に起因する差異を切り分けます。カットオフ期間を設ける、後続の変更を取り込む、同期フェーズを再実行するといった対応が必要になることがあります。並行変更に関する明確なルールがなければ、システム間の比較で誤検知が生じたり、新しいデータを見落としたりする可能性があります。
証拠を確認してから再開し、不確実な結果を適切に扱う
安全に再開するには、保留中の単位と確定済みの単位を読み込みますが、不確定なままの単位を有効と見なしてはいけません。不確定な単位については、安定したキーで移行先を照会し、結果を期待される変換内容と比較します。一致すれば、効果を繰り返さずに確定を記録します。存在しなければ、再試行が適切な場合があります。内容が異なる状態で存在するなら、その単位を停止して調査してください。
操作の繰り返しで重複や外部への副作用(通知の送信など)が生じる可能性がある場合は、操作を冪等にするか、対象システムが対応していれば冪等性キーを使用します。それができない場合は、事前確認と照合の手順を設計してください。例外が発生したからといって、何も書き込まれなかったと決めつけてはいけません。変更の確定後、応答を受け取る前に失敗した可能性があります。
再開前に、同じマッピング、同じキーのポリシー、正しいコードまたは設定のバージョンが使われていることを検証してください。異なる変換で作成されたチェックポイントは誤解を招くことがあります。PHPでは、移行コマンドが識別可能な実行を受け付け、構造化された状態を出力するようにします。そうすれば、担当者は汎用的なコンソールメッセージだけに頼らず、記録とデータを照合できます。
停止条件を定め、レポートを作成して完了する

キーの競合、業務ルールが必要な無効データ、孤立したリレーション、検証できない不確定な結果、許容範囲を超える差異があれば、続行を停止してください。何が起きたかを利用可能な証拠から判断できない場合も停止します。こうした場合は、むやみに再試行するより、エスカレーションして状態を保全するほうが安全です。
終了時には、全体の検証を実施します。確定済みの単位と想定される単位の照合、件数とキー、リレーション、移行で定めた業務ルールを確認してください。何を移行し、何を検証し、何を再試行し、どの差異が未解決なのかを、調査に使える参照情報とともに示すレポートを作成します。プロセスが終了コード0で終わったという理由だけで、作業を完了と宣言してはいけません。
再開の基準は簡潔に表せますが、技術的な規律が求められます。各単位は、確定済み、未適用であることを検証済み、または要確認として切り分け済みのいずれかでなければなりません。この明示的な状態と、比較可能な不変条件、役立つ記録があれば、進捗を成功と取り違えたり、不確実な状態を再試行の許可と見なしたりせずに、PHPの移行を続行できます。



