学習・技術検証用デモ — 本システムは実際の銀行サービスではありません。

公開情報をもとに構築した教育目的のシステムです。実在する個人情報・口座情報・機密情報・認証情報等を入力しないでください。

ミニ銀行ACADEMY SYSTEM LEARNING
教材メニュー
学習進捗0 / 134
あと134項目
ADVANCED · 発展COURSE 09 · BANKING ENGINEERING

銀行エンジニアリング 33:復元と検証(manifest・照合・二者確認・訂正)

バックアップから戻しただけでは、正しく戻ったとは言えません。何を確かめれば再開してよいのか、失われた取引をどう扱うのか、復元後に見つかった誤りをどう直すのかを追います。

42 / 55
BANKING ENGINEERING · 銀行エンジニアリング

v8以降に実装した台帳・記帳エンジンなどを実際に動かし、正常時と異常時の両方から銀行システムの構造を学ぶ。

Prerequisite: BANKING SYSTEM

LEARNING GOALS

このページで学ぶこと

  • バックアップ時点の記録(manifest)と復元後の検証
  • 同じ冪等キーでの再送が二重にならない理由
  • 復元で戻ってしまう同意の失効と、その対処

PLAIN LANGUAGE

まず、ここだけつかむ

1

復元したデータが正しいことは、バックアップ時点の記録(manifest)との一致と、これまでの版の照合の両方で確かめます。

2

バックアップのあとの取引は失われます。顧客のアプリが元の冪等キーで再送すると、ちょうど1回に収束します。

3

復元で戻ってしまう同意の失効は、再開時にアクセストークンをすべて失効させて塞ぎます。

DIFFICULT PARTS, STEP BY STEP

難しいポイントを、順番にほどく

専門用語を覚えることより、「なぜ必要か」「このシステムのどこで使うか」を理解することが目標です。

01

manifest

やさしく言うと

バックアップ時点のデータの指紋です。

なぜ必要?

復元後に、バックアップ時点と同じかを数値で確かめるためです。

Minibankでは

recovery.manifests。件数・最終仕訳・ハッシュ・営業日に加え、グループの勘定残高や、同意・融資・定期預金の状態、さらに書込停止中は変わらない状態の行ごとのハッシュ(digest の方式 3。融資(契約・返済予定・申込・分類と審査のイベント・命令・商品の版)、預金の価格(手数料と利息の実行・その訂正・商品の版)、法人(支払依頼・支払予定・メンバー・組織・設定依頼)、group(事業体・事業体の役割)、Open Banking(クライアント・同意・振込依頼・通知先の登録)、顧客の振込依頼、risk の設定(パラメータ・シナリオ・測定)、twin の設定(モデル・シナリオ)、銀行間送金(支払・決済バッチ)、管理責任者の復旧の記録と方針、締め処理の実行、KYC の状態)。運用者の権限は入れない。digest は方式の版と一緒に外へ控える。

02

検証

やさしく言うと

復元後に、帳簿が矛盾していないかを確かめることです。

なぜ必要?

戻したデータで営業を再開してよいかを判断するためです。

Minibankでは

recovery.verify。核の 9 項目(元帳・Posting・補助元帳・融資・預金価格・Open Banking・Treasury・V19_GROUP・V19_ADAPTER)、運用者の権限(EXTERNAL_OPERATORS)、manifest との比較。manifest 以外の全項目(運用者の権限を含む)が OK で、manifest の比較も OK になった検証があることが提出の条件。

03

外に控えた運用者の一覧

やさしく言うと

障害の前に、運用者の user_id・role・status を、データベースの外へ控えたものです。

なぜ必要?

運用者の権限は書込停止中に『無効化』で変わるので digest に入れられません。外の一覧と比べて、権限が増えていないことだけを確かめるためです。

Minibankでは

復元の宣言の external_operators(任意。1〜500 件の配列)。検証の EXTERNAL_OPERATORS は、一覧を渡せば増える向きだけ NG で、一覧にない人は NG にしない(人数は unlisted_active に出る)。渡さなければ検査は走らず、『検査せず』(declared:false)と出る。NG は、無効化することで解消する(降格は書込停止中は RY001 で止まる。管理責任者の無効化は、その人を除いて有効な管理責任者が 2 人以上残るときだけ)。

04

調整の仕訳

やさしく言うと

誤りを消さずに、差額を新しい仕訳で直すことです。

なぜ必要?

元の記録を残したまま、あとから説明できるようにするためです。

Minibankでは

pricing.adjust_run。仮受金は専用の取消し。

Level 1 基礎:戻したデータが正しいことを、どう確かめるか

バックアップの直前に、その時点のデータの『指紋』を記録しておきます(manifest)。復元したあとに同じ指紋を取り、一致すれば、復元がバックアップ時点と同じだと分かります。ただし、復元先の中で新しく取った指紋は、復元先が古くても必ず一致してしまいます。だから指紋の digest は、障害の前にデータベースの外へ控えておき、復元を始めるときに入力します。それとは別に、帳簿そのものが矛盾していないかも確かめます。

検証の項目確かめること
元帳と残高(v7)仕訳の借方と貸方の合計、口座の残高と元帳の再計算
Posting(v8)事象と仕訳の対応
補助元帳(v10)総勘定元帳と、預金・定期預金・為替・仮受金・融資の明細
融資(v14)・預金価格(v15)・Treasury(v13)各業務の契約と仕訳の照合
Open Banking(v16)イベントの連番、依頼と振込の対応、無効な同意で生きているトークン
グループ(v19・V19_GROUP)entity・グループ内の移動と、グループの仕訳・勘定残高の照合
基準の銀行の読取り口(v19・V19_ADAPTER)グループの照合とは別に、基準の銀行の読取り口(adapter)が元帳と食い違っていないか
manifest件数・最終仕訳・試算表と残高のハッシュ・営業日に加え、グループの勘定残高と移動の状態、同意・融資・定期預金の状態のハッシュ、さらに書込停止中は変わらない状態の行ごとのハッシュ(融資(契約・返済予定・申込・分類と審査のイベント・命令・商品の版)、預金の価格(手数料と利息の実行・その訂正・商品の版)、法人(支払依頼・支払予定・メンバー・組織・設定依頼)、group(事業体・事業体の役割)、Open Banking(クライアント・同意・振込依頼・通知先の登録)、顧客の振込依頼、risk の設定(パラメータ・シナリオ・測定)、twin の設定(モデル・シナリオ)、銀行間送金(支払・決済バッチ)、管理責任者の復旧の記録と方針、締め処理の実行、KYC の状態。更新日時は除く)が、バックアップ時点と一致するか(digest の方式 3)。復元を経た場合は、外に控えた digest・版との一致も含む
運用者の権限(外に控えた一覧)復元を宣言した周期では必ず出る行。運用者の一覧を渡していれば、一覧にある人の権限が一覧より増えていないか(増えていれば NG。減る向きと、一覧にない人は NG にしない。一覧にない有効な運用者の人数 unlisted_active は情報だけ)。一覧を渡していなければ検査せず(declared:false。OK 扱いだが、権限は調べていない)

Level 2 銀行業務:失われた取引と再送

バックアップのあとに確定し、顧客に『成功』と答えた取引は、復元したデータにはありません。顧客のアプリは、結果が不明なときと同じように、元の冪等キーで再送します。再送は、失われた取引なら1回だけ実行され、すでにある取引なら元の結果を返して二重になりません。

演習では、失われた取引の数と時間幅(RPO)を測り、すべての再送のあとに、主系(正解として残しておいた古い側)と口座の残高が一致することを確かめます。

Level 3 システム:MiniBankでの実装

  • recovery.take_manifest がバックアップ時点の記録を取り、recovery.verify が上の検証を束ねて実行する。結果は追記専用の記録に残り、提出できるのは、照合を始めたあとの最新の検証で manifest 以外の全項目(運用者の権限の行を含む)が OK で、かつその間に、外に控えた digest と一致する manifest の比較が OK になった検証があるときだけ(バックアップ後に再送した取引で manifest との差が出るのは正常)
  • digest 版 3 は、書込停止中は変わらない状態の行ごとのハッシュを含む(融資(契約・返済予定・申込・分類と審査のイベント・命令・商品の版)、預金の価格(手数料と利息の実行・その訂正・商品の版)、法人(支払依頼・支払予定・メンバー・組織・設定依頼)、group(事業体・事業体の役割)、Open Banking(クライアント・同意・振込依頼・通知先の登録)、顧客の振込依頼、risk の設定(パラメータ・シナリオ・測定)、twin の設定(モデル・シナリオ)、銀行間送金(支払・決済バッチ)、管理責任者の復旧の記録と方針、締め処理の実行、KYC の状態。実装の recovery.snapshot の state_hashes_v3 に対応)。書込停止中に変わらないので、再開を詰まらせない。運用者の権限は含めない(書込停止中の『無効化』で変わってしまうため)ので、外に控えた運用者の一覧との一方向の検査(EXTERNAL_OPERATORS)で守る。NG は『復元後に権限が増えている人がいる』という意味で、書込停止中にできるのは『無効化』だけで、役割を下げる変更(降格)は RY001 で止まる。管理責任者の無効化は、その人を除いて有効な管理責任者が 2 人以上残る場合だけで、満たさなければ RY003 で止まる
  • manifest の比較は、差を数値で報告する(仕訳が何件欠けたか、最終仕訳が何か、ハッシュがどう違うか)。manifest を指定しない検証は NOT RUN で、提出の条件にならない
  • 復元を経て再開すると、発行済みの Open Banking のアクセストークンをすべて失効させる。バックアップのあとに顧客が取り消した同意が、復元で ACTIVE に戻ることがあるため。トークンは15分で更新もないので、外部のアプリは顧客の新しい同意をもう一度得る必要がある
  • 復元でイベントの連番も巻き戻る。外部のアプリが覚えている連番が別のイベントを指さないよう、event_id の食い違いで検知して、events API で取り直す
  • 復元後に誤りが見つかったときは、仮受金は専用の訂正(受入の取消し/振替の取消し)、利息・手数料は調整の仕訳(正なら追加、負なら回収)で直す。汎用の取消しは PF002 で拒否される
  • 顧客がすでに使ったお金を戻す訂正は、Posting Engine が残高不足で断る(PE010)。資金を負にしない

異常時:復元後の検証が NG

段階内容
症状検証の manifest の項目だけが NG。ほかは OK
読み方復元がバックアップ時点と一致していない。差は数値で出る(件数の差、最終仕訳、ハッシュ)
よくある原因復元先へ、復元後に書込みが入った(fence の前)。違う(古い)バックアップから戻した。外に控えた digest と食い違うので、検証は NG になる
対応再開しない。復元先で書込みが入った経路を止め、正しいバックアップから戻し直す。差の意味を説明できるまで提出しない。外に控えた値を入力し間違えたときは、abort_restore で書込停止に戻して宣言からやり直す

異常時:運用者の権限(EXTERNAL_OPERATORS)が NG

段階内容
症状検証の『運用者の権限』の行だけが NG。manifest を含むほかの項目は OK のまま、レビューへ提出できない(RY004)
読み方復元後に、外に控えた一覧より権限が増えている人がいる(一覧では無効の人が有効、運用者のはずの人が管理責任者)。NG の詳細の escalations(権限が増えている人の一覧)に user_id が出る。一覧にない人は NG にならない。unlisted_active は一覧にない有効な運用者の人数(情報だけ)
対応書込停止中にできるのは『無効化』(有効から無効への変更)だけで、役割を下げる変更(降格)は RY001 で止まる。管理画面『管理者管理』で無効化して、もう一度検証してから提出する。無効化の対象が管理責任者のときは、その人を除いて有効な管理責任者が 2 人以上残らないと RY003 で止まる。その場合は『復元をやり直す』(abort_restore)で外に控えた一覧を訂正し、宣言し直す
注意『検査せず』(declared:false)は OK ではない。復元の宣言で一覧を渡さなかったので、権限を調べていない。外に控えた一覧があるなら、宣言をやり直す(abort_restore で書込停止に戻して、最初から)

Level 4 アーキテクチャ:復旧の設計は冪等性の設計

復元で取引が失われても、クライアントが同じキーで再送できれば結果は1回に収束します。復旧は『元に戻す』作業ではなく、『失われた分を、同じ意図で、もう一度、ちょうど1回だけ』実行する作業です。冪等キーが表ごとに固定されていることが、その土台です。

どこを確認すればよいか

  • 管理画面『復旧・DR』:検証の結果(項目ごとの OK/NG)、manifest、演習の記録、訂正のフォーム
  • scripts/dr/drill.mjs の出力:RTO・RPO・失われた取引の数・条件

CHECK YOUR UNDERSTANDING

6問で理解チェック

答えを頭の中で考えてから、各項目を開いて確認してください。

Q1運用者の権限は、なぜ digest に入れないのですか?
答え

書込停止中でも『無効化』だけはできるため、digest に入れると正当な無効化で再開が詰まるからです。代わりに、外に控えた一覧と比べ、権限が増えている向きだけを NG にします。

Q2復元の宣言で運用者の一覧を渡さなかったら、運用者の権限は調べられますか?
答え

調べられません。検証には『検査せず』(declared:false)と出ます。OK に見えても、権限は調べていません。AML など digest に入らない状態も、DB は見つけないので、人が確認します。

Q3運用者の権限が NG のとき、manifest などほかの項目が OK なら提出できますか?
答え

できません(RY004)。無効化して、もう一度検証します(降格は書込停止中は RY001 で止まります)。管理責任者の無効化は、その人を除いて有効な管理責任者が 2 人以上残る場合だけできます(そうでなければ RY003。その場合は復元をやり直して一覧を訂正します)。

Q4manifest を指定しない検証で提出できますか?
答え

できません。manifest の項目は NOT RUN で、全項目 OK になりません(RY004)。

Q5失われた取引を同じキーで再送すると二重になりますか?
答え

なりません。失われたものは1回だけ実行され、あるものは元の結果を返します。

Q6復元のあとに再開すると、Open Banking のトークンは?
答え

すべて失効します。外部のアプリは顧客の新しい同意が必要です。

ここまで読めましたか?

完全に暗記する必要はありません。大切な考え方を説明できそうなら押してください。

SOURCE TRAIL

根拠と関連教材

CURRENT IMPLEMENTATIONは確認したrepository内の実装です。HISTORICAL IMPLEMENTATIONは導入・修正の履歴で、後続migrationによる再定義があり得ます。RELATED LESSONは教材への案内で、実装の一次Sourceではありません。ASSUMPTIONは仮定、UNKNOWNは未確認を表します。

確認基点: d02eae8914f39cbf06bfe422dc39c71886f82b3e / 2026-09-11。稼働環境への適用確認: UNKNOWN。パス実在の自動検査と、記述した技術的事実の確認は別です。

Implementation Status: IMPLEMENTED IN MINIBANK(この教材が扱うコードの範囲)

  • RELATED LESSON/docs/be-dr-writer-fencing書込停止と再開
  • RELATED LESSON/docs/be-openbanking-events-webhooksイベントの連番と pull による取り直し
  • RELATED LESSON/docs/be-gl-subledger補助元帳の照合
  • CURRENT IMPLEMENTATIONsupabase/migrations/20260930190000_v20_digest_v3_review.sqlrecovery.snapshotバックアップ時点の記録(件数・最終仕訳・試算表と残高のハッシュ・営業日など。v19で entity・仕訳・グループ内移動の件数を追加し、Freeze Hardening で、グループの勘定残高・移動の状態・同意・融資・定期預金の状態ハッシュを追加。digest 版 3 で、書込停止中は変わらない状態の行ごとのハッシュ(主なもの: 融資・価格・法人・group・Open Banking・振込依頼・risk/twin の設定・銀行間送金・KYC)を追加し、再監査で、並べ替えのいらない方式(行ごとの md5 の合計と件数)に変え、group の事業体・Open Banking の同意と通知先・管理責任者の復旧・締め処理の実行も加えた。運用者の権限は入れない)
  • CURRENT IMPLEMENTATIONsupabase/migrations/20260930190000_v20_digest_v3_review.sqlrecovery.verifyこれまでの版の照合を束ね、manifest と突き合わせる検証(v19でグループの照合を追加、Freeze Hardening で基準銀行の adapter の独立検査と、digest の方式の版の突合を追加。digest 版 3 で、外に控えた運用者の一覧と比べ、権限が増えている向きだけを NG とする EXTERNAL_OPERATORS を追加。再監査で、復元を宣言した周期では必ずこの行を出し、一覧が未申告なら declared:false の「検査せず」とし、申告ありなら一覧にない有効な運用者の人数 unlisted_active も出す)
  • CURRENT IMPLEMENTATIONsupabase/migrations/20260930130000_v17_reliability.sqlgl.reverse_suspense_receipt / gl.reverse_suspense_clear仮受金の受入・振替の専用の訂正(汎用の取消しは PF002)
  • CURRENT IMPLEMENTATIONsupabase/migrations/20260930130000_v17_reliability.sqlpricing.adjust_run利息・手数料の実行の誤りを、調整の仕訳で直す
  • CURRENT IMPLEMENTATIONscripts/banking/v17-recovery.test.mjs状態機械・書込停止・書込世代・manifest と検証・トークン失効・訂正・演習記録のDBテスト