運用・障害対応学習記事全11節Operate
バックアップを別の場所へ復元し、基準時点との3照合と戻らない変更を確かめる
この記事で身につくこと隔離した環境で復元し、件数・内容・関係・利用可否を確認する理由と、バックアップ以降の変更が復元されない可能性を説明できる。
記事内目次(24項目)
この記事の会社・人物・データはすべて架空の設定です。実在する会社や案件とは関係ありません。この記事の演習は、記事C(SAMPLE-C)の復元演習と同じ考え方を、Node.js標準機能だけで小さく再現したものです。本文のコードは正本の全文で、第6節の実行結果は2026-09-21に実際にローカルで実行した出力をそのまま載せています(第7節)。演習領域(
work/)の外には読み書きしません。
この記事は何の話か。架空の依頼・履歴データのバックアップ(基準時点)を、元の場所とは別の場所へ復元し、件数・内容・関係の3照合を行い、基準時点より後に加わった変更(新しい依頼、承認)が復元後には戻らないことを、実際に動かして確かめる話です。
なぜ必要か。バックアップを取っていても、実際に復元できるかどうか、復元した結果が期待どおりかどうかは、試してみなければ分かりません。また、「バックアップから復元すれば元どおりになる」という誤解を避ける必要があります。
この記事を読むとできるようになること。
- 隔離した環境で復元し、件数・内容・関係・利用可否を確認する理由を説明できる
- バックアップを別の場所へ復元し、基準時点との3照合、戻らない変更を復元演習記録に書ける
- バックアップの頻度と保存先を、許容する損失の範囲と費用から判断できる
- 記事に載っている実行結果が、正本のコードを実際に動かした出力そのものであるかを、証拠(実行記録)と照らして確かめられる
読む順路。この記事は3つの深さで読めます。全部を順に読む必要はありません。
- 基本だけ理解する:第1節→第3節(別の場所へ復元する理由、「基準時点どおり、元どおりではない」)→第4節(判断すること)→第5.1節(演習の流れ)→第6.3節の復元演習記録の表→第9節。コードを読まなくても、何を照合し、何が戻らないかが分かります。
- 作って確かめる:上に加えて第5.2〜5.4節(演習コードの全文)→第5.5節(演習の設計:実行前に見るもの・失敗したとき・戻せるか・誰が)→第6.1〜6.2節の実行結果→第7節(確かめたこと・確かめていないこと)。
- 設計判断を深める:上に加えて第8節(復元できたことと利用可否の判断、バックアップの頻度と保存先)。
1. 今回の業務課題と完成するもの
この記事でやることは、架空の依頼・履歴データについて、ある時点(基準時点)でバックアップを取り、その後に業務が続いた状態(新しい依頼、既存の依頼の承認)を作ってから、バックアップを元の場所とは別の場所へ復元し、件数・内容・関係の3照合と、戻らない変更を確かめることです。
12-03(記事C)では実際の障害を想定した復元演習を行いましたが、この記事では、このFast Trackで使ってきたデータ形式(JSON)を使い、同じ考え方を小さく再現します。
この記事を読み終えると、次のものが手元にできます。
- 復元演習コード(
examples/12-04-restore-drill/) - 復元演習記録(バックアップの基準時点、復元先、手順、件数照合、内容照合、関係の照合、利用可否、戻らない変更、実施者、日時)
2. 前提知識と読む順路
この記事で使う言葉を先に説明します。
基準時点
一言でいうと、バックアップを取った時刻です。復元すると、この時点の内容に戻ります。
基準時点どおり、元どおりではない
一言でいうと、復元は「バックアップを取った時点の内容」に戻すことであり、「今の状態」に戻すことではない、という考え方です(12-03・記事Cで扱った考え方と同じです)。
3照合
一言でいうと、復元したデータをバックアップと突き合わせる3つの確認です。件数(依頼と履歴の数が同じか)、内容(各依頼の依頼者・件名が同じか)、関係(履歴が指す依頼が復元先に存在するか)。
これがないと、「バックアップがあるから大丈夫」と思っていても、実際に復元したときに、基準時点より後の変更が戻らないことに気づかず、業務に混乱が生じます。
読む順路:障害対応・復元演習の全体像は12-03(記事C)、復旧方針は05-04、環境の区別は06-02、コードの切戻し(データの復元とは別の作業)は11-04が該当します。この記事の復元演習記録は、13-04(引継ぎ・移行・廃止を行う)、05-04の方針見直しで使います。
3. 理解する:隔離した環境で復元し、3照合する理由
3.1 別の場所へ復元する理由
12-03(記事C)で確認したとおり、復元は元の場所を上書きせず、別の場所(この記事ではwork/restore/)へ行います。元のデータ(バックアップ、稼働中のデータ)を壊さずに、復元結果だけを確認できるようにするためです。復元先が既にある場合も上書きせず、拒否します(第6.2節で実際に確かめます)。
3.2 よくある誤解
「バックアップから復元すれば元どおりになる」。12-03(記事C)で確認したとおり、復元は「基準時点どおり」であり、「元どおり」ではありません。基準時点より後に加わった変更(新しい依頼、承認など)は、復元しても戻りません(第6節で実際に確認します)。
「復元できれば、それで完了」。復元したデータが基準時点と一致するか(件数・内容・関係)を確認し、戻らない変更を明らかにしてから、利用を再開するかどうかを判断します(第8節)。
「記事に実行結果が載っていれば、動いた証拠になる」。載っている結果が、載っているコードを実際に動かした出力そのものでなければ、証拠になりません。この記事の初版は、実行結果の JSON を読みやすく1行にまとめ、拒否の確認も実際には出ていない形の出力を書いていました(第11節)。本更新では、正本のコードの全文と、実行した出力そのまま(整形なし)を載せ、実行記録(evidence)と一致させています。
4. 判断すること
復元演習で人が判断することは、次の5つです。
| 判断すること | なぜ判断が必要か | 仮置きしてよいか | 間違えた場合の影響 |
|---|---|---|---|
| いつ演習してよいか | 復元先が稼働中のデータと隔離されていること(この記事では work/restore/)が前提。隔離されていなければ演習しない | 不可。復元先が既にある場合は拒否する(演習コードは例外で止まる) | 稼働中のデータやバックアップを上書きする |
| 何を照合し、何を「一致」とするか | 件数・内容・関係の3つ。内容は依頼者・件名で比べる(状態は基準時点より後に変わりうるので、戻らない変更として別に扱う) | 可(比べる項目は業務に合わせて増やす) | 状態の違いを「不一致」と誤読して復元失敗と判断する、または戻らない変更を見落とす |
| 戻らない変更をどう扱うか | 基準時点より後の新しい依頼(REQ-D04)と状態変更(REQ-D01)は、復元では戻らない。作り直すか諦めるかは関係者と決める | 不可。演習コードは一覧を作るだけで、扱いを決めない | 利用者の操作が黙って消える |
| 何を証拠として残すか | コード(正本)、コマンド、stdout・stderr・終了コードをそのまま。整形した結果を「実行結果」として載せない | 不可 | 記事の結果と実際の動作が食い違い、証拠にならない(初版の問題) |
| 誰が実施し、誰が利用再開を判断するか | 実施は運用担当(架空)。利用再開の判断は運用管理者と業務担当者(架空)。復元できたことと利用可否は別(第8.1節) | 可(架空の体制で仮置き) | 3照合が一致しただけで利用を再開し、戻らない変更に気づかない |
勝手に決めてはいけないこと:実際のバックアップ・実際のデータベースを対象にしたかのように書きません。この記事は架空データによる演習です。復元できたことを、そのまま利用再開の判断として扱いません(第8.1節)。実行結果を整形・省略して「実行結果」として載せません。戻らない変更の扱い(作り直す・諦める)を演習の実施者が決めません。
AIに任せる範囲:演習コードの下書き、実行して結果をそのまま返すこと、3照合の集計、戻らない変更の一覧化はAIに任せられます。任せてはいけないのは、復元先が隔離されているかの最終確認、戻らない変更の扱い、利用再開の判断です。
5. 作って確かめる:復元演習を実行する
5.1 演習の流れ
| 手順 | 内容 | 関数(drill.js) |
|---|---|---|
| 1 | 演習用の初期データ(依頼3件、履歴3件)を work/live.json に作る | setupInitialData() |
| 2 | バックアップを work/backup.json に取る(この時点が基準時点) | takeBackup() |
| 3 | 基準時点のあと、業務が続く(REQ-D04 を追加、REQ-D01 を承認) | applyAfterBackupChanges() |
| 4 | バックアップを別の場所 work/restore/restored.json へ復元する。復元先が既にあれば拒否 | restore() |
| 5 | 件数・内容・関係の3照合と、戻らない変更の一覧を作る | reconcile() |
演習領域(work/)の外は読み書きしません(assertInsideWork)。
5.2 演習コード(drill.js)
演習コードは examples/12-04-restore-drill/ を正本とします。以下は全文です。
// 教材演習用:バックアップからの復元演習(記事Cの演習と同じ考え方を、Node.js標準機能だけで小さく再現する)。
// 「元どおり」ではなく「基準時点どおり」に戻ることを、架空データで確かめる。
// 演習領域(このフォルダ直下の work/)の外は読み書きしない。
const fs = require("node:fs");
const path = require("node:path");
const WORK_DIR = path.join(__dirname, "work");
const LIVE_FILE = path.join(WORK_DIR, "live.json");
const BACKUP_FILE = path.join(WORK_DIR, "backup.json");
const RESTORE_DIR = path.join(WORK_DIR, "restore");
const RESTORED_FILE = path.join(RESTORE_DIR, "restored.json");
function assertInsideWork(targetPath) {
const resolved = path.resolve(targetPath);
if (!resolved.startsWith(WORK_DIR + path.sep) && resolved !== WORK_DIR) {
throw new Error("演習領域(work/)の外への操作は拒否します: " + targetPath);
}
}
function readJson(file) {
assertInsideWork(file);
return JSON.parse(fs.readFileSync(file, "utf8"));
}
function writeJson(file, data) {
assertInsideWork(file);
fs.writeFileSync(file, JSON.stringify(data, null, 2));
}
// 手順1:演習用の初期データ(基準時点の直前)を作る。
function setupInitialData() {
fs.mkdirSync(WORK_DIR, { recursive: true });
const initial = {
requests: [
{ id: "REQ-D01", requester: "佐藤", title: "会議室の予約", state: "提出済み", approver: "鈴木" },
{ id: "REQ-D02", requester: "田中", title: "備品購入申請", state: "承認済み", approver: "鈴木" },
{ id: "REQ-D03", requester: "高橋", title: "交通費精算", state: "提出済み", approver: "佐藤" },
],
history: [
{ requestId: "REQ-D01", action: "作成", actor: "佐藤" },
{ requestId: "REQ-D02", action: "作成", actor: "田中" },
{ requestId: "REQ-D02", action: "承認", actor: "鈴木" },
],
};
writeJson(LIVE_FILE, initial);
}
// 手順2:バックアップを取る(この時点が「基準時点」)。
function takeBackup() {
const live = readJson(LIVE_FILE);
writeJson(BACKUP_FILE, live);
}
// 手順3:基準時点のあと、業務が続く(新しい依頼、既存の依頼の承認)。
function applyAfterBackupChanges() {
const live = readJson(LIVE_FILE);
live.requests.push({ id: "REQ-D04", requester: "田中", title: "研修参加申請", state: "提出済み", approver: "鈴木" });
live.history.push({ requestId: "REQ-D04", action: "作成", actor: "田中" });
const target = live.requests.find((r) => r.id === "REQ-D01");
target.state = "承認済み";
live.history.push({ requestId: "REQ-D01", action: "承認", actor: "鈴木" });
writeJson(LIVE_FILE, live);
}
// 手順4:バックアップを、元の場所とは別の場所(work/restore/)へ復元する。復元先が既にあれば拒否する。
function restore() {
if (fs.existsSync(RESTORE_DIR)) {
throw new Error("復元先が既に存在します。上書きしません: " + RESTORE_DIR);
}
fs.mkdirSync(RESTORE_DIR, { recursive: true });
const backup = readJson(BACKUP_FILE);
writeJson(RESTORED_FILE, backup);
}
// 手順5:件数・内容・関係の3照合と、戻らない変更の一覧を作る。
function reconcile() {
const backup = readJson(BACKUP_FILE);
const restored = readJson(RESTORED_FILE);
const live = readJson(LIVE_FILE);
const countCheck = {
requests: { backup: backup.requests.length, restored: restored.requests.length, ok: backup.requests.length === restored.requests.length },
history: { backup: backup.history.length, restored: restored.history.length, ok: backup.history.length === restored.history.length },
};
const contentCheck = backup.requests.map((r) => {
const found = restored.requests.find((x) => x.id === r.id);
return { id: r.id, ok: !!found && found.requester === r.requester && found.title === r.title };
});
const relationCheck = restored.history.map((h) => ({
requestId: h.requestId,
ok: restored.requests.some((r) => r.id === h.requestId),
}));
const restoredIds = new Set(restored.requests.map((r) => r.id));
const lostNewRequests = live.requests.filter((r) => !restoredIds.has(r.id)).map((r) => r.id);
const lostStateChanges = live.requests
.filter((r) => restoredIds.has(r.id))
.map((r) => ({ id: r.id, liveState: r.state, restoredState: restored.requests.find((x) => x.id === r.id).state }))
.filter((r) => r.liveState !== r.restoredState);
return { countCheck, contentCheck, relationCheck, unreturnedChanges: { newRequestsNotRestored: lostNewRequests, stateChangesNotRestored: lostStateChanges } };
}
module.exports = { WORK_DIR, LIVE_FILE, BACKUP_FILE, RESTORE_DIR, RESTORED_FILE, setupInitialData, takeBackup, applyAfterBackupChanges, restore, reconcile };
5.3 実行コード(run.js)
// 教材演習用:復元演習を手順どおりに実行する。
const fs = require("node:fs");
const { WORK_DIR, setupInitialData, takeBackup, applyAfterBackupChanges, restore, reconcile } = require("./drill.js");
if (fs.existsSync(WORK_DIR)) fs.rmSync(WORK_DIR, { recursive: true, force: true }); // 演習領域を初期化
console.log("手順1:初期データを作る");
setupInitialData();
console.log("手順2:バックアップを取る(基準時点)");
takeBackup();
console.log("手順3:基準時点のあと、業務が続く(新しい依頼、既存の依頼の承認)");
applyAfterBackupChanges();
console.log("手順4:バックアップを別の場所(work/restore/)へ復元する");
restore();
console.log("手順5:件数・内容・関係の3照合と、戻らない変更の確認");
const result = reconcile();
console.log(JSON.stringify(result, null, 2));
5.4 復元先が既にあるときの拒否を確かめるコード(run_reject_check.js)
restore() は復元先が既にあると例外を投げて止まります。そのまま呼ぶと Node.js の stack(エラーの発生位置の一覧)が stderr に出て終了コード1になるので、この記事では例外を受け止めて内容を表示するコードで確かめます。
// 教材演習用:復元先(work/restore/)が既に存在するときに restore() が上書きせず拒否することを確かめる。
// 先に node run.js を実行して work/restore/ を作っておく。例外を受け止めて内容を表示する(パスの先頭を <examples> に置き換える以外、整形はしない)。
const fs = require("node:fs");
const path = require("node:path");
const { RESTORE_DIR, restore } = require("./drill.js");
if (!fs.existsSync(RESTORE_DIR)) {
console.log("復元先がまだ無い(先に node run.js を実行する)");
process.exit(1);
}
try {
restore();
console.log("復元先が既にあるのに上書きされた(想定外)");
process.exit(2);
} catch (e) {
console.log(`拒否されました: ${e.message.replace(path.dirname(__dirname), "<examples>")}`);
process.exit(0);
}
5.5 演習の設計
| 項目 | 内容 |
|---|---|
| 何のための操作か | バックアップを隔離した場所へ復元し、基準時点と一致すること(3照合)と、基準時点より後の変更が戻らないことを、実際に動かして確かめる。あわせて、復元先が既にあるときに上書きしないことを確かめる |
| 実行前に見るもの | 今いる場所が examples/12-04-restore-drill/ か。work/ は実行のたびに消して作り直される(演習用。他の記事の正本や 11-02 の配置サンドボックスは触らない) |
| コマンド | node run.js のあと node run_reject_check.js |
| 期待結果 | run.js:3照合がすべて ok: true、newRequestsNotRestored に REQ-D04、stateChangesNotRestored に REQ-D01(承認済み→提出済み)。終了コード0。run_reject_check.js:「拒否されました: 復元先が既に存在します…」で終了コード0 |
| 結果の読み方 | countCheck と contentCheck と relationCheck の ok がすべて true か。unreturnedChanges の中身が第5.1節の手順3で加えた変更と一致するか。拒否の表示があり、work/restore/restored.json が書き換わっていないか |
| 失敗したとき | ok: false がある→ backup.json と restored.json を直接比べる。拒否の確認で終了コード1(「復元先がまだ無い」)→ 先に run.js を実行する。終了コード2(上書きされた)→ restore() の存在確認を見直す。「演習領域(work/)の外への操作は拒否します」→ パスの指定を見直す |
| 元に戻せるか | 作るのは work/ の中だけ。work/ を消せば元どおり。稼働中のデータに相当する live.json は復元で書き換えない |
| 業務運用では誰が実施/判断するか | 実施:運用担当(架空)。戻らない変更の扱いと利用再開:運用管理者と業務担当者(架空)。この演習ではすべて Claude Code |
6. 実行結果(復元演習記録)
6.1 復元と3照合(node run.js)
examples/12-04-restore-drill/ で実行した stdout です(整形・省略なし。stderr への出力はありませんでした)。
$ node run.js
手順1:初期データを作る
手順2:バックアップを取る(基準時点)
手順3:基準時点のあと、業務が続く(新しい依頼、既存の依頼の承認)
手順4:バックアップを別の場所(work/restore/)へ復元する
手順5:件数・内容・関係の3照合と、戻らない変更の確認
{
"countCheck": {
"requests": {
"backup": 3,
"restored": 3,
"ok": true
},
"history": {
"backup": 3,
"restored": 3,
"ok": true
}
},
"contentCheck": [
{
"id": "REQ-D01",
"ok": true
},
{
"id": "REQ-D02",
"ok": true
},
{
"id": "REQ-D03",
"ok": true
}
],
"relationCheck": [
{
"requestId": "REQ-D01",
"ok": true
},
{
"requestId": "REQ-D02",
"ok": true
},
{
"requestId": "REQ-D02",
"ok": true
}
],
"unreturnedChanges": {
"newRequestsNotRestored": [
"REQ-D04"
],
"stateChangesNotRestored": [
{
"id": "REQ-D01",
"liveState": "承認済み",
"restoredState": "提出済み"
}
]
}
}
終了コード: 0
読み方:countCheck は依頼3件・履歴3件でバックアップと復元先が一致、contentCheck は3件とも依頼者・件名が一致、relationCheck は復元先の履歴3件がすべて存在する依頼を指しています。unreturnedChanges は、基準時点より後に加えた REQ-D04(新しい依頼)と REQ-D01 の状態変更(稼働中は承認済み、復元先は提出済み)が戻らないことを示しています。
6.2 復元先が既にあるときの拒否(node run_reject_check.js)
run.js の直後に実行した stdout です(整形・省略なし。stderr への出力はありませんでした。パスの先頭はコードの中で <examples> に置き換えて表示しています)。
$ node run_reject_check.js
拒否されました: 復元先が既に存在します。上書きしません: <examples>/12-04-restore-drill/work/restore
終了コード: 0
参考:例外を受け止めずに node -e "require('./drill.js').restore()" と呼ぶと、stdout には何も出ず、stderr に発生位置(drill.js:67)と throw new Error("復元先が既に存在します。上書きしません: " + RESTORE_DIR); の行から始まる stack が出て、終了コード1になります(実行記録に先頭3行を記録)。初版の記事はこの node -e の結果を「拒否されました: …」という stdout があったかのように載せていました(第11節)。
6.3 復元演習記録
| バックアップの基準時点 | 復元先 | 手順 | 件数照合 | 内容照合 | 関係の照合 | 利用可否 | 戻らない変更 | 実施者 | 日時 |
|---|---|---|---|---|---|---|---|---|---|
依頼3件・履歴3件の時点(work/backup.json) | work/restore/restored.json(隔離。既にあれば拒否) | 第5.1節の手順1〜5 | 依頼3件・履歴3件で一致 | 3件とも依頼者・件名が一致 | 復元先の履歴3件すべてが対象の依頼を持つ | 第8.1節参照(復元できたことと利用可否は別) | REQ-D04(新しい依頼)、REQ-D01の状態変更(提出済み→承認済み)が戻らない | Claude Code(演習) | 2026-09-21 |
7. 確認結果
実行環境:macOS 26.6.2、Node.js v24.18.0(node:fs、node:pathのみ使用)、2026-09-21に実行。実行場所は examples/12-04-restore-drill/。演習領域(work/)の外には読み書きしていません。stdout・stderr・終了コードは evidence_public/phase5b2c1-2026-09-21/12-04/run_log.md に整形なしで記録しています。
完了条件との照合:
| 完了条件 | 期待 | 実測 | 判定 |
|---|---|---|---|
| 復元先が本番と隔離されている | work/restore/ のみを使用、既にあれば拒否 | restore() は work/restore/restored.json に書き、run_reject_check.js で拒否を確認 | 一致 |
| 件数・内容・関係の3照合がある | すべて ok: true | 件数2組・内容3件・関係3件、すべて true | 一致 |
| 戻らない変更が具体例で示されている | REQ-D04、REQ-D01 の状態変更 | newRequestsNotRestored: ["REQ-D04"]、stateChangesNotRestored: [REQ-D01 承認済み→提出済み] | 一致 |
| 記事のコードが正本と同一 | drill.js・run.js・run_reject_check.js の全文 | 第5.2〜5.4節は正本の全文 | 一致 |
| 記事の実行結果が実測と同一 | 整形・省略なし | 第6.1〜6.2節は実行記録の stdout そのまま | 一致 |
この記事で確かめたこと:架空データで、別の場所への復元、3照合の一致、戻らない変更の一覧化、復元先が既にあるときの拒否が、正本のコードで実際に成立すること。
この記事で確かめていないこと:
| 範囲 | 理由 | どこで確かめるか |
|---|---|---|
| 実際のバックアップ(規模・保存先・取得方法) | 演習は依頼3〜4件の JSON | 05-04の復旧方針に基づく実際の環境 |
| 実際のデータベースでの復元 | 題材アプリは JSON ファイル保存 | 実際の保存先を決めてから |
| 戻らない変更の扱い(作り直す・諦める) | 関係者の判断で、演習では決めない | 実際の復旧時に運用管理者と業務担当者が決める |
| 利用再開の判断 | 復元できたことと利用可否は別(第8.1節) | 実際の復旧時 |
| 11-02 の配置サンドボックスのデータ(REQ-NEW-001)の復元 | この演習は独立した work/ で行う。11-04で残ったデータは扱っていない | 11-04 の切戻し判断時に、この記事の手順を当てはめる |
残る制限:この演習は、小規模な架空データ(依頼3〜4件)を対象にしたものです。この記事の本文と演習コードはClaude Codeが作成したもので、業務担当者による内容確認は行っていません。
8. 設計を判断する
8.1 復元できたことと、利用可否の判断は別
復元して3照合が一致したことは、「バックアップの内容が正しく戻せた」ことを示すものであり、それだけで利用を再開してよいことにはなりません。戻らない変更(この記事ではREQ-D04、REQ-D01の状態変更)を関係者に伝え、それらをどう扱うか(作り直す、諦めるなど)を決めてから、利用再開を判断します。
8.2 バックアップの頻度と保存先を判断する
| 選択肢 | 内容 | 適する場合 |
|---|---|---|
| バックアップの頻度を高くする | 戻らない変更の量を減らせるが、確認の手間・保存の費用が増える | 変更の頻度が高く、損失の影響が大きい業務 |
| バックアップの頻度を低くする | 確認の手間・費用を抑えられるが、戻らない変更が増える可能性がある | 変更の頻度が低い、または損失の影響が小さい業務 |
この記事の題材アプリ(社内の依頼・承認)では、業務日ごとの変更量は多くないと考えられるため、日次程度の頻度が候補になります(架空の仮定であり、実際の運用では業務担当者と確認する必要があります)。
8.3 コードの切戻しとデータの復元を組み合わせるとき
11-04のコードの切戻しでは、新版の稼働中に増えたデータ(REQ-NEW-001)が残りました。データも基準時点へ戻す必要があるときに、この記事の手順(別の場所へ復元→3照合→戻らない変更の一覧→扱いを決める)を当てはめます。コードだけ戻すか、データも戻すかの判断は 11-04 の第8.2節にあります。
9. 持ち帰る成果物
| 成果物 | 空欄版 | 記入例 |
|---|---|---|
| 復元演習記録ひな形(バックアップの基準時点、復元先、手順、件数照合、内容照合、関係の照合、利用可否、戻らない変更、実施者、日時) | templates/12-04-restore-drill_template.md | templates/12-04-restore-drill_example.md |
| 復元演習コード一式 | examples/12-04-restore-drill/(drill.js、run.js、run_reject_check.js) | 同上 |
| 実行記録(stdout・stderr・終了コード、整形なし) | — | evidence_public/phase5b2c1-2026-09-21/12-04/run_log.md |
自分の業務に使うときの手順は次のとおりです。
- 演習用の架空データでバックアップ(基準時点)を作る
- 基準時点より後の変更を加える
- 別の場所へ復元し、件数・内容・関係の3照合を行う。復元先が既にあれば上書きしない
- 戻らない変更を洗い出し、利用再開の判断材料として記録する
- コード・コマンド・出力・終了コードをそのまま実行記録に残す
10. 次工程への受渡し
次へ渡すもの:復元演習記録、復元演習の実行記録。
次工程での使われ方:13-04(引継ぎ・移行・廃止を行う)では、この演習記録を引継ぎ資料の一部として使います。05-04の復旧方針の見直しにも使います。11-04でデータも戻す必要が出た場合は、この記事の手順を当てはめます。
前工程へ戻る条件:復旧方針そのものに見直しが必要な場合は、05-04に戻って確認します。
11. 根拠と更新情報
- この記事の会社・人物・データはすべて架空の設定です。
- 「基準時点どおり、元どおりではない」という考え方、別の場所への復元、戻らない変更の扱いは、記事C(SAMPLE-C、12-03)と同じものです。
- 制作の来歴:本文はClaude Codeが作成しました。第5節のコードは
examples/12-04-restore-drill/を正本とし、2026-09-21にmacOS 26.6.2・Node.js v24.18.0の環境で実際に実行して、stdout・stderr・終了コードをevidence_public/phase5b2c1-2026-09-21/12-04/run_log.mdに記録しています。人(ユーザー)による実読・内容確認は未実施です。 - 2026-09-21(Phase 5B-2C1):初版(2026-09-20)の第6節は、
run.jsの出力 JSON を1行にまとめて整形したものを「実行結果」として載せ、第5.5節のreconcile()は本体を省略した抜粋だった。また、拒否の確認はnode -e "require('./drill.js').restore()"の結果として「拒否されました: …」という stdout を載せていたが、実際にはこの呼び方では stdout に何も出ず、stderr に例外の stack が出て終了コード1になる。本更新で、記事のコードを正本の全文に、実行結果を再実行の実測そのまま(整形なし)に置き換え、拒否の確認は例外を受け止めて表示するrun_reject_check.jsを正本に加えて実測した。演習の内容(データ・手順・3照合の結果)は変えていない。 - 未確認事項:実際のバックアップの規模・保存先、実際のデータベースでの復元、戻らない変更の扱いの決定、利用再開の判断は、この記事の時点では確認していません。
