システムを旧版に戻す前に:データ変更と取引の切り戻しを確認する
新しい版が注文を保存した後、問題が見つかった。旧プログラムは再配布できても、新形式の金額や状態を読めない。そんな仮定では、どこまで戻せるのでしょうか。一つの金額の仕様を追い、読み取り互換性を準備する順序と、変更後の取引を照合する範囲を考えます。
本稿では、公開人数ではなく、更新後に残った状態を見ていく。旧版で読める状態はどれか、外部で既に実行した取引はどれか。戻すという一つの操作を、データの復帰と業務の後始末に分けて考える必要がある。
この記事の目次
新版の10.50 USDを、旧版は読めるか
互換性を一つのデータで追う。旧版は金額を整数の円で保存し、新版は小数を含む外貨と通貨コードを保存する仕様だとする。新版が10.50とUSDを書き込んだ後、旧版だけへ戻すと、通貨を読めない、あるいは円と誤認する可能性がある。バイナリの起動成功は、取引の復帰成功ではない。これは仕様を仮定した失敗経路で、特定製品の不具合報告ではない。
比較するのは、先に旧版でも読める列を追加する、読み取り側を移してから新形式の書き込みを始める、切替時に書き込みを止める、という案だ。旧形式への丸め変換では10.50の精度や通貨の意味を失うため、単に逆変換を用意しただけで「元どおり」とはいえない。変換が保存すべき情報を列挙して試す。
公開群と観測期間の設計はカナリアの観測範囲へ分ける。本稿の受入れは、旧版が新版の書き込みを読めるか、戻した後も請求や取消しが完了するかという互換性に置く。
読み取りの準備と、新形式の書き込みを分ける
AWSのSandeep Pokkunuriは、2019年の実務解説で、形式変更を「先に新旧両方を読めるようにする段階」と「新形式を書き始める段階」に分ける例を示している。新形式を書いた後に戻れるのは、その形式を読める準備済みの版であり、変更前の全ての版ではない。AWS「Ensuring rollback safety during deployments」
大切なのは二段階という回数そのものではなく、途中の組み合わせでもデータを解釈できることだ。実際の形式変更には、保存データ、通信相手、旧版が残る場所など固有の条件がある。提供企業による経験の説明であり、この方式で全ての変更が安全になるという保証ではない。
準備が一部へしか届いていないうちに新形式を書き始めると、まだ古い読み手が失敗し得る。旧形式を読む機能を削除する時期も、古いデータが残っていないかという別の確認が要る。「直前の版に戻せる」という言葉を、更新後にどのデータを読み、どの処理を続けられるのかへ具体化したい。
共有データと外部の取引まで、戻す範囲を追う
以下は実務資料を踏まえた編集上の提案である。対象を絞る前に、変更の影響がどこまで届くかを図にする。利用者を分けても、共通のデータベース、待ち行列、外部接続先を使っていれば、そこを通じて別の利用者へ影響する可能性がある。
特定の利用者だけに新画面を表示する変更と、共有テーブルの意味を変える変更は同じではない。前者は表示を切り替えて戻せる設計にしやすい。一方、後者は少数の書き込みでも、旧版が使う情報を壊す可能性がある。少ない人数という説明より、共有状態へ何を残すかの説明が重要になる。
外部への送信も同様だ。通知や請求を実行した後、プログラムを戻しても相手が受け取ったものは消えない。技術的な切り戻しとは別に、取り消し、訂正、照合が必要な行為を挙げておく。自動で戻す機能があるというだけで、業務上の後始末まで自動になるわけではない。
同じ受注システムでも、進めてよい変更は違う
架空の受注システムで、検索画面の並び順だけを変更するとする。保存形式には手を付けず、対象者を分けられ、誤表示を観測でき、旧表示へ切り替える経路も確認済みなら、少数へ公開して使い勝手を確かめる案が成立する。
条件を変え、新画面と同時に注文状態の保存形式を変更するとしよう。旧版が新状態を解釈できないなら、公開人数を減らしても切り戻しの問題は消えない。この場合は、読み取り互換性の準備や変更の分割へ戻る方が先である。すぐ出せないことを、カナリアの割合調整で解消しようとしない。
さらに、新形式を読める準備はできたが、月次請求まで使わない情報があるとする。昼間の画面操作が正常だっただけでは、その処理の証拠にならない。代表的な請求処理を別環境で検証するなど、まだ観測していない経路を埋めてから対象を拡大する。
これらは実績データではなく仮想例である。選択が逆転する条件は、人数ではなく、変更が残す状態と、その状態を読み戻す能力にある。
自動停止した後の仕事も、公開前に決める
停止後も、新版で更新した取引の照合は残る。対象を追える記録を用意し、旧版へ戻すと不整合が増える場合は書き込み停止と前進修正も選択肢にする。公開群・観測期間の設計はカナリアの観測範囲へ譲り、以下では「旧版が新版の記録を正しく読めるか」を受入れ条件にする。
欠落、重複、外部の状態を別々に照合する
AWSの切替ガイドは、受付の凍結、最終同期、接続先変更を分け、新規取引が生じた後の切り戻しではデータの扱いが必要になると説明する。以下はその境界を受注へ当てはめた編集上の照合案であり、AWSがこの業務例を試験した結果ではない。
最終同期点以後に受け付けた取引と、同期点より前に受け付けて切替後も決済や取消しが進む取引を対象にし、注文ID、再試行を含めた要求のID、外部決済の取引IDを対応させる。受付を止めたつもりでも、夜間連携が書き込み続けるなら境界は閉じていない。記録の値と関係の一般的な受入れはデータ移行の照合で扱う。ここで追加するのは、切替後に増えた取引と外部で実行済みの行為を、どの状態へ復帰させるかという判断だ。
例えば、受け付けた注文はO401・O402・O403の三件、新側にも三件あるが、内訳はO401・O401・O402だったと仮定する。総件数は一致しても、O403は欠落し、O401は重複している。ただし履歴行を保存する仕様なら同じ注文IDが複数行あるのは正常なこともある。この例では注文の正本は一ID一件と決めており、履歴や請求明細の行数を混ぜない。
さらにO402が新側では取消済み、外部では決済成功だったとする。欠けた注文の補完、重複注文の整理、取消しと入金の不一致は別の修復である。どのシステムを正本にするかも状態ごとに決める。外部の決済記録を取得できないなら、不一致がないとは結論せず、確認できるまでその取引の再請求を止める。
再送のキーがあるだけで二重処理を防げるとも限らない。例えばStripeの冪等なリクエストの仕様は、同じキーの最初の処理結果を返す一方、24時間以上経過したキーを削除でき、削除後の再利用では新しい要求になると説明する。これは同社APIの条件で、すべての決済に共通の保証ではない。旧版へ戻した際のキーの保存・再利用条件と決済の現在状態を確かめ、照合済みの結果を再実行しない。
旧側への反映後も、注文と請求・取消しの対応を再照合できるなら、その経路で復帰する案を選べる。外部状態が不明、IDの対応が失われた、変換で金額の意味が失われる場合は、受付や影響処理を止めて修復する案を先に比較する。三件という仮定から事故率や復旧時間は推定できない。戻す許可の条件は、プログラムの起動ではなく、未解決の取引を増やさず業務を再開できる証拠に置く。
公開中の観測と、停止後の復帰を分ける
少数公開の観測設計は、対象・期間・比較群の判断で扱う。本稿はその先の、停止後に旧版とデータの意味を保って戻れるかという問いを扱う。Google SRE Workbook「Canarying Releases」は実務書であり、全業種の障害減少率や共通の安全閾値を示す実験ではない。
業務を再開できる証拠から、戻すか決める
承認の場では、「最初は少数です」に続けて、どの共有部分へ影響するか、どの処理を見れば失敗が分かるか、更新後の何をどの版へ戻せるかを説明してもらう。その説明が曖昧なら、公開範囲をさらに小さくしても、学べることと残る危険は曖昧なままである。
旧版が更新後のデータを正しく読み、未解決の請求や取消しを増やさず再開できるなら、その経路で復帰する。保存形式や外部の状態が不明なら、旧プログラムが起動しただけで戻したとは扱わず、書き込み停止や前進修正を先に比べる。復帰の目安は、版の名前ではなく、残った取引を正しく引き継げることに置きたい。