はじめに
カットオーバーの夜、関係者全員でリリースを見守り、朝になってシステムが無事に立ち上がったことを確認する。プロジェクトルームで拍手が起こり、打ち上げの日程が決まる。
「移行プロジェクト、完了しました」
この瞬間がゴールだと、誰もが思っている。しかし現場を見てきた経験から言えば、本当に難しい問題はここから始まる。
この記事では、メインフレーム移行プロジェクトが「完了」と呼ばれた後に実際に起きる4つの問題と、なぜそれが「完了」のタイミングでは見えなかったのかを解体する。
1. 「完了」の定義が間違っている
KPIが「カットオーバー」止まりになっている
多くの移行プロジェクトのKPIは、以下のように設計されている。
✓ 新システムへの切り替え完了
✓ 並行稼働期間(1〜3ヶ月)の終了
✓ 旧システムの停止
✓ プロジェクト体制の解散
このKPI設計には根本的な欠陥がある。並行稼働の1〜3ヶ月では、本番運用で起こりうる事象の全パターンを通過できない。
1年分のイベントを通さないと「検証」にならない
金融・保険・公共系のシステムには、年に1度しか発生しないイベントが大量に存在する。
| イベント | 発生頻度 |
|---|---|
| 決算処理 | 年1〜4回 |
| 税制改正対応 | 年1回(4月が多い) |
| 年末調整 | 年1回 |
| 利息計算の年度切替 | 年1回 |
| 閏年処理 | 4年に1回 |
| 連休中の大量バッチ | 年数回 |
3ヶ月の並行稼働では、これらのイベントのほとんどを一度も通過しない。「並行稼働で問題が出なかったので移行成功」という判断は、検証範囲が本番運用の4分の1にも満たない状態での判断だ。
本当の意味での検証完了は、最低でも1回の決算期・1回の年度替わりを新システムだけで乗り切った時点になる。プロジェクトのKPIをここに設定していないケースが、実は大多数だ。
2. 問題1:消えた「暗黙知」が本番データで牙を剥く
「再現できなかった」エッジケースの存在
COBOLの静的解析・移行プロセスでは、コードに書かれているロジックは正確に移植できる。しかしコードに書かれていない判断は移植できない。
IF CUST-TYPE = 'S'
PERFORM SPECIAL-DISCOUNT
END-IF.
CUST-TYPE = 'S'が何を意味するのか、コード上のコメントには何も書かれていない。SPECIAL-DISCOUNTという名前から「特別割引」だとは推測できるが、なぜこの顧客区分が存在し、いつどう運用されているかは、コードからは読み取れない。
移行プロジェクトでは、こうした不明点を有識者にヒアリングして仕様化する。しかし、稼働中のシステムで30年に一度しか発動しない条件分岐や、特定の取引先1社のためだけに存在する特例処理は、ヒアリングのテーブルに上がってこない。
担当者の引退・異動後に判明する仕様の謎
メインフレームの運用には、長年携わってきたベテランの「勘」が組み込まれていることがある。
「この処理、なんでこうなってるんですか?」
「昔、〇〇銀行との取引で問題があって、それ以来この処理が入ってるんですよ」
このような会話の中にある知識は、プロジェクトのドキュメントに残らないことが多い。移行プロジェクトの期間中に、その担当者が定年退職してしまうケースも珍しくない。
カットオーバー後、半年〜1年経ってから「あの取引先のケースだけおかしい」という問い合わせが来る。原因を調査すると、移行時にヒアリングが及ばなかった特例処理だったと判明する。このとき、知っていた人はもう社内にいない。
ドキュメント化できなかったツケ
静的解析パイプラインは、コードに存在する構造とロジックを正確に抽出する。しかし「なぜそのロジックが存在するか」という業務文脈は、コード解析だけでは復元できない。
移行プロジェクトの設計段階で、この業務文脈をどれだけ正確にドキュメント化できたかが、カットオーバー後の半年〜1年で表面化する問題の数を左右する。
ここで問われるのが、移行アプローチの選び方だ。コードを機械的に変換するだけのリホストは、構造の移植には強いが、業務文脈の掘り起こしには無力だ。一方で業務知識を理解しながら再設計するリプラットフォーム/リライトは、有識者を巻き込むコストが発生する代わりに、暗黙知をドキュメントとして残す機会になる。「とにかく早く移行したい」という圧力でリホスト一辺倒の方針を選ぶと、暗黙知の掘り起こしという最も重要な工程がまるごと省略される。
3. 問題2:パフォーマンス特性の違いが半年後に露呈する
チャネルI/Oに最適化されていた設計
メインフレームは専用のI/Oプロセッサ(チャネル)を持ち、CPUがI/O待ちで止まることなく大量データを処理できる設計になっている。COBOLバッチは、この特性に最適化された形で書かれている。
メインフレーム:
チャネルI/O ──► 高速・並行I/O処理
バッチは「メモリに1レコードだけ載せて、シーケンシャルに大量処理」
Java/クラウド環境:
汎用ストレージI/O ──► アプリ層でI/O制御
同じロジックを書いても、I/Oの並行度・レイテンシ特性が根本的に違う
開発・テスト環境では数千件規模のデータで検証することが多い。この規模ではパフォーマンスの差は表面化しない。問題は本番データの規模でしか出ない。
「動くが遅い」が決算期や月末バッチで顕在化
移行直後の通常運用では問題が出ないことが多い。問題が出るのは、処理量が跳ね上がるタイミングだ。
- 月末バッチ(処理件数が平日の数倍)
- 決算期(全顧客の一括集計処理)
- ボーナス時期(振込処理の集中)
これらのタイミングで、夜間バッチが朝までに終わらない、オンライン処理がタイムアウトする、といった事象が発生する。カットオーバーから数ヶ月経ち、初めての月末・決算期を迎えたときに発覚するため、「移行は成功した」と思われていた後に問題が露呈する典型例だ。
メインフレームのCOBOLバッチは「1レコード読み込んで変数領域を上書きする」という設計のため、メモリをほとんど消費しない。しかしJavaに移行したシステムで同様の処理を雑に組むと、レコードごとにオブジェクトを生成してしまい、大量データ処理の途中でガベージコレクション(GC)、特にFull GCが頻発してスループットが急激に低下する。最悪の場合はOOM(メモリ不足)でバッチが異常終了する。
さらに、VSAMや高度に最適化されたDB2環境から、クラウド上のコモディティなRDBへ移行した場合、大量バッチの同時実行時に行ロック(Row Lock)やデッドロックが多発するケースも多い。メインフレームのファイルアクセスでは問題にならなかった同時実行制御が、RDBのトランザクション分離レベルの違いによって、データ量が一定の閾値を超えた瞬間にパフォーマンスが指数関数的に悪化することがある。
スケールアップ前提の設計とスケールアウト環境のミスマッチ
メインフレームは「1台で性能を出す」スケールアップ型の設計だ。Javaでクラウドに移行する場合、「複数台に分散すれば性能が出る」というスケールアウト型の前提で設計されることが多い。
しかしCOBOLバッチのロジックには、順序依存性(前のレコードの処理結果が次のレコードの処理に影響する)が組み込まれていることがある。この順序依存性を持つ処理は、単純に並列化できない。
移行時に「クラウドならスケールアウトで何とかなる」という楽観で設計すると、実際には並列化できない処理がボトルネックとして残り、性能要件を満たせない事態になる。
4. 問題3:運用チームのスキルギャップが組織を蝕む
COBOL運用者とJava運用者のメンタルモデルの違い
長年COBOL/メインフレームを運用してきたチームと、新たにJavaシステムを運用するチームでは、障害対応のメンタルモデルが根本的に異なる。
| メインフレーム運用 | Java/クラウド運用 | |
|---|---|---|
| 障害の発見 | SMF/SYSLOGの監視、アベンドコード(S0C7等)からの原因特定 | APM・分散トレーシング、スタックトレース解析 |
| 障害対応の単位 | ジョブ単位(JCLログを追う) | サービス単位(マイクロサービス間のリクエストを追う) |
| 再実行の考え方 | チェックポイントからの再実行が前提 | リトライ・冪等性設計に依存 |
| 「正常」の感覚 | 長年の運用で培われた「いつもと違う」勘 | メトリクスの閾値による定義 |
カットオーバー後、運用を担当するのは多くの場合、新しい技術スタックに不慣れなメンバーか、逆に新技術には強いがメインフレームの業務知識を持たないメンバーだ。両方を兼ね備えた人材は、移行直後にはほぼ存在しない。
障害対応の「勘」が引き継がれていない
ベテランのメインフレーム運用者は、「このエラーコードが出たら、まずこれを確認する」という経験則を持っている。この経験則は、長年の障害対応で培われたものであり、ドキュメント化されていないことが多い。
新システムでは同じ業務ロジックが動いていても、エラーの出方・ログの形式・監視の仕組みがすべて変わる。旧システムでの経験則がそのまま使えない。
新システムのインシデント対応で起きる初動の遅れ
カットオーバー直後にインシデントが発生したとき、「これは仕様通りの動作か、バグか」を即座に判断できる人がいないという状況が起きる。
メインフレーム時代なら、ベテランが「ああ、これはいつものあれだ」と即答できた事象が、新システムでは「原因不明」として長時間調査されることになる。この初動の遅れが、軽微な問題を重大インシデントに発展させる。
5. 問題4:「並行稼働」の終わらせ方を誤る
旧システムを止める判断基準が曖昧なまま進む
多くのプロジェクトは「並行稼働期間を設ける」という方針までは決めるが、「いつ・何を確認できたら旧システムを止めるか」の判断基準を明確にしていない。
判断基準が曖昧なまま進むと、以下のどちらかの極端な結果になる。
- 基準が緩く、本来検証すべき事象を確認しないまま旧システムを停止してしまう
- 基準が示されないまま「念のため」が続き、旧システムが何年も「保険」として居座り続ける
レガシーが「保険」として居座り続けるコスト
後者のケースは想像以上に多い。旧メインフレームのライセンス費用、運用人員、ハードウェア保守費用を払い続けながら、新システムと並行稼働を続ける。
「いつ止めるんですか」という問いに、「まだ不安なので」という答えが返ってくる。この状態が1年、2年と続くと、移行プロジェクトの本来の目的(コスト削減・モダナイゼーション)が達成されないばかりか、メインフレーム側の保守契約(ハードウェア/ソフトウェア)には解約予告期限が存在するという現実的な制約に直面する。
「念のため」と判断を先送りしているうちに解約デッドラインを過ぎてしまい、意図せず保守契約が自動更新される。結果として数千万円〜数億円規模の「延長保守費用」が確定し、移行プロジェクトのサンクコスト化という最悪のシナリオに陥る。判断の先送りは、技術的なリスク回避ではなく、契約上のコストとして跳ね返ってくる。
本当の意味でのカットオーバーはいつなのか
判断基準を明確にするなら、以下のような項目を事前に定義しておく必要がある。
- 最低1回の決算期を新システム単独で乗り切ったか
- 最低1回の年度替わり処理を新システム単独で乗り切ったか
- 想定される異常系(タイムアウト、リトライ、データ不整合)の対応手順が運用チームに定着したか
- インシデント対応の平均解決時間が、旧システム運用時と同水準まで改善したか
- 旧メインフレームの保守契約の解約予告期限がいつで、判断のリミットがどこにあるか
これらを事前にKPIとして定義しないまま並行稼働に入ると、「いつ止めるか」の議論が際限なく続くことになる。
本当の「完了」とは何か
KPIの再定義:カットオーバーではなく定常運用の安定化
「移行プロジェクトの完了」を定義し直すなら、以下のようになる。
誤った完了の定義:
新システムへの切り替え完了 + 並行稼働終了
正しい完了の定義:
新システムへの切り替え完了
+ 最低1サイクルの年次イベント(決算・年度替わり等)を単独で通過
+ 運用チームの障害対応能力が旧システム水準に到達
+ 旧システム停止後、一定期間(3〜6ヶ月)の安定運用を確認
移行後6〜12ヶ月をプロジェクトスコープに含めるべき理由
カットオーバーをゴールに設定したプロジェクトは、その瞬間にチームが解散し、予算もクローズする。問題はその後に発生するため、対応するリソースが組織内に残っていないという事態になる。
正しいプロジェクト設計は、カットオーバー後6〜12ヶ月の「定常化期間」を最初からスコープと予算に含めることだ。この期間は新規開発ではなく、暗黙知の掘り起こし・性能チューニング・運用チームの習熟に充てられる。
この期間を見込んでいないプロジェクトほど、カットオーバー後に「想定外のトラブル」として個別対応に追われ、結果的にコストも期間も当初計画を大きく超過する。
おわりに
メインフレーム移行プロジェクトの「完了」は、カットオーバーの瞬間ではない。新システムが旧システムと同等以上の安定性で、1年を通じて動き続けることを確認できた時点だ。
この記事で挙げた4つの問題──暗黙知の消失、パフォーマンス特性の違い、運用スキルギャップ、並行稼働の終わらせ方──はすべて、「カットオーバー=完了」という誤った定義から生まれる。
打ち上げのタイミングを間違えると、本当の問題に対応するリソースが残っていない。これが、現場で繰り返し見てきた現実だ。
本記事では移行後に表面化する問題を扱ったが、「暗黙知の掘り起こし」「COBOLバッチの順序依存性解析」「移行後の運用設計とランブック作成」については、現在整理中であり、必要に応じて別途まとめる予定である。
また、**「なぜ日本のメインフレームモダナイゼーションが2035年を期限に動き出しているのか」**については、noteの連載で詳しく論じている。
第0章 日本の汎用機市場の現在地と2035年問題(note)