バックアップがあればデータを復旧できますが、稼働中のデータベースに直接復元すると、バックアップ取得後に行われた正当な変更が失われるおそれがあります。問題が単一のレコードや限定された範囲に及ぶ場合、通常の目標は、失われた情報を復元しつつ、現在の状態の残りを維持することです。そのため、復旧は単純な置き換えではなく、比較と調整の操作として扱う必要があります。
適切な方法は、データベースエンジン、スキーマ、監査ログの有無、損害の範囲によって異なります。PHPアプリケーションでは、復旧ロジックを本番アプリケーションから切り離し、判断内容を記録してから、データを書き込む前に検証を試すのが適切です。どの変更が安全か判断できない場合は、上書きを自動化するよりも、作業を止めて手動調整を準備するほうがリスクを抑えられることが多いでしょう。
データの復旧が何を意味するかを定義する

完全復元では、データベース、スキーマ、または広範なデータセットを、ある復旧時点の内容で置き換えます。一方、選択的復旧では、稼働中の他のデータを変更せずに、特定の行や値を復元しようとします。方法を選ぶ前に、期待する結果を正確に記述してください。欠落または変更されたエンティティ、復元するフィールド、維持すべき後続の変更を明確にします。
名前やメールアドレスのように変更される可能性のある値だけでなく、主キーなどの安定した識別子を使って対象範囲を絞ります。また、インシデントが関連レコードに及んでいるかも確認してください。たとえば注文は、明細、支払い、住所、ステータスイベントに依存する場合があります。親レコードだけを復元するとエンティティの整合性が崩れることがあります。一方、関連データ一式を復元すると、取り消すべきでない正当な変更まで含まれる可能性があります。
- 問題の症状、おおよその発生時期、報告者を記録します。
- 関連するテーブル、主キー、外部キー、制約を特定します。
- 以前の値に戻すフィールドと、現在のまま維持するフィールドを定義します。
- 誰が操作を承認するか、完了と判断するために何を確認するかを定めます。
復旧時点を選び、状況を再構成する
必ずしも損害発生前のバックアップとは限りません。必要な状態を再構成できる復旧時点を選びます。インシデントによっては、複数のバックアップ、トランザクションログ、監査データを比較し、復元すべき情報と維持すべき後続の状況を特定する必要があります。特定時点への復旧でデータ抽出に使える一時データベースを作成できる場合がありますが、その内容全体を本番環境に移して安全だという意味ではありません。
日時とタイムゾーン、バックアップの対象範囲、作成時のスキーマ、利用可能な整合性チェックの結果を確認します。検証されていないバックアップを、初めから信頼できる情報源とみなしてはいけません。また、識別子が再利用されている可能性や、調査中に対象テーブルへ書き込むプロセスが存在するかも確認してください。
バックアップは、アクセスを制限し、本番環境への書き込み接続を持たない隔離インスタンスに復元します。アプリケーションが誤ってそのインスタンスを参照したり、スケジュールされたジョブを実行したりしないようにしてください。データに個人情報や機微情報が含まれる場合は、アクセスを制限し、それらのデータに定められた保護措置を適用します。隔離環境なら、稼働中のデータベースにリスクを加えることなく状態を比較できます。
バックアップを現在の正解と決めつけずに比較する
安定したキーを使って、バックアップ内の候補行と現在の行を比較します。それぞれについて、レコードが存在しない、存在するがフィールドが変更されている、または重要な差異がない、という3つの状況を区別します。更新日時、イベント履歴、監査ログがある場合は、いつ、なぜ変更されたのかを理解するために利用します。ただし、タイムスタンプだけでは、誰が変更したのか、あるいはその変更を維持すべきかは証明できません。
選択的復旧では、重要な注意点があります。一部のフィールドが正当に変化している場合に、古い行全体を自動的にコピーしてはいけません。たとえば比較の結果、説明フィールドが失われている一方で、ステータス、所有者、別のエンティティとの関連はその後に変更されていることがわかる場合があります。ビジネスルール上問題がなければ、行全体を置き換えるより、失われたフィールドだけを復元するほうが安全です。
一意性の競合、外部キー、必須カラム、デフォルト値、アプリケーション側で適用されるルールも確認します。論理削除を使用するシステムでは、レコードが存在しないのではなく、削除済みとしてマークされている可能性を確認してください。同じ業務処理に関わるテーブルは、残高、ステータス、参照関係の不整合を避けるため、一括して調整する必要がある場合があります。
範囲を限定し、検証可能な操作を実行する
変更対象となるキーとカラムを正確に列挙した計画を作成します。実行前に、対象行の現在の状態を保存するか、それと同等のロールバック手段を用意します。稼働中のデータベースの新しいコピーで計画を試し、結果を期待値と比較してください。試行では、行を個別にインポートするだけでなく、実際の制約や依存関係も含めて確認します。
データベースエンジンと操作が対応している場合は、変更をトランザクション内で実行します。ただし、トランザクションがレビューの代わりになるわけではありません。復元やインポートの一部の処理はエンジン固有の動作をすることがあり、外部プロセスが同時にデータを更新する可能性もあります。比較から書き込みまでの間に予期しない変更を検出できる条件を使ってください。行がレビュー済みの状態と一致しなくなっていたら、黙って上書きするのではなく、操作を止めて再分析します。
PHPアプリケーションでは、管理されたタスクやメンテナンスコマンドを使って、入力の検証、対象キーの限定、結果の記録を行えます。値を連結してSQL文を組み立てることは避けてください。パラメータ化クエリと、アプリケーションで使われているデータアクセス機構のトランザクション機能を利用します。操作を公開ルートから切り離し、認証情報やバックアップをテキストログに記録しないでください。
変更を確定する前に、影響を受けた行数、制約、関連するリレーションを検証します。その後、復元した値と、関連する業務処理におけるアプリケーションの動作を確認します。トランザクションの確定前に検証に失敗した場合は、トランザクションをロールバックします。すでに確定済みである場合や、取り消せない影響が発生している場合は、新たな書き込みを即興で行ってはいけません。実行前に承認されたロールバックまたは復旧計画を発動し、受け入れ可能な状態を復元して検証するための、テスト済み手順に従います。計画に従っても整合性のある状態に戻せない場合は、追加の変更を止め、証拠を保全し、責任者に判断を引き継ぎます。
判断を記録し、自動化しない場合を選ぶ
インシデント、使用した復旧時点、確認したキー、復元したフィールド、維持した後続の変更を記録します。誰がレビューと承認を行ったか、実行日時、実施した検証、その結果も記録してください。ログに不要な機微情報を含めないようにします。こうした追跡可能性により、判断の説明が可能になり、後日の調査にも役立ちます。
信頼できるキーがない、業務処理間で競合がある、誤操作と正当な変更を区別できない、または関係の意味が状況に依存するデータに復旧が及ぶ場合は、手動調整を選びます。広範な破損に対しては完全復元が適切なこともありますが、その影響、停止時間、失われる後続の変更、復旧手順を評価する必要があります。実行が簡単という理由だけで選んではいけません。
- 選択的復旧: 損害の範囲が明確で、キーの信頼性が高く、差異を検証できる場合。
- 手動調整: 同時変更がある、またはビジネスルールに人の判断が必要な場合。
- 完全復元: 損害が広範で、停止や失われる変更を管理する承認済み計画がある場合。
復旧を完了する前のチェックリスト

- 準備: 対象範囲、キー、依存関係、期待する結果を特定していますか。適切な復旧時点を選び、検証しましたか。
- 環境と承認: バックアップを隔離環境に復元し、アクセスを制限して、手順を試しましたか。責任者は操作とロールバックまたは復旧計画を承認しましたか。
- 実行: 対象行の現在の状態を保存し、書き込みを予定したキーとフィールドに限定し、同時変更を検出できるようにしていますか。
- 検証: 対象行、制約、参照関係、業務上の動作を確認しましたか。確認に失敗した場合、追加の書き込みを止め、承認済みの手順を発動しましたか。
- 追跡可能性: 不要な機微情報を含めずに、判断、実行、検証、維持した変更、結果を記録しましたか。
該当する項目に「はい」と答えられない場合は、本番環境への書き込みを延期してください。選択的復旧、手動調整、完全復元のいずれを選ぶかは、損害の範囲、証拠の信頼性、運用への影響、整合性のある状態に実際に戻せるかどうかに基づいて判断します。



