【実務・中級編】 PSB(プログラム仕様ブロック)生成プロセス – 階層型DBMS

PSB(プログラム仕様ブロック)生成プロセス:近代アプリケーションから見た階層型DBMS権限統制の極意

こんにちは。チーフアーキテクトの私だ。
今日のコードレビューで、また「なんとなくコピペで作られたようなPSB(Program Specification Block)」を見かけた。

「リレーショナルデータベース全盛のこの時代に、なぜ今さら階層型DBMS(IMSなど)のPSBなのか?」と思うかもしれない。しかし、金融、航空、インフラといった社会の基幹を支え続ける極限のミッションクリティカル領域において、データの物理的局所性とポインタチェーンによる高速なナビゲーショナル・アクセスは、未だに代替不可能な戦闘力を持っている。

そして、その基盤上で稼働するCOBOLやPL/I等のアプリケーションがデータベースに触れる際、唯一にして最大の門番となるのが「PSB」と「PCB(Program Communication Block)」の生成プロセスだ。

今回は、このPSBのアーキテクチャの本質と、実務の現場で絶対に踏んづけてはならない地雷、そして堅牢な設計パターンについて、私の知見を余すところなく伝授しよう。

—

1. PSBとPCBのアーキテクチャ:なぜ「見える世界」を制限するのか

リレーショナルデータベース(RDBMS)であれば、ビュー(View)や行レベルセキュリティ(RLS)、あるいはスキーマ権限によってアクセス制御を行う。しかし、階層型DBMSの世界では、データ構造自体がポインタの網の目(ツリー構造)であり、アプリケーションが迷い込んだが最後、全データベースを破壊しかねない構造上のリスクを抱えている。

ここで登場するのが PSB だ。

  • PSB (Program Specification Block): 1つのアプリケーションプログラムがアクセスできるデータベースの「境界」と「権限」を定義したメタデータ構造体。
  • PCB (Program Communication Block): PSBを構成する部品であり、単一のデータベースに対するビューとアクセス意図(入出力の方向)を定義したもの。

チーフアーキテクトとして断言するが、PSB設計の本質は「セキュリティ」ではなく「スコープの極限までの絞り込み」にある。 アプリケーションが知る必要のないセグメント(レコード)の存在を隠蔽し、バグや不正アクセスによるデータ汚染の確率を物理的にゼロへと近づけるための防壁なのだ。

—

2. PSB生成プロセス:マクロ定義からジェネレーションまでの実務

PSBは、人間が読み書きするソースコード(通常はアセンブラマクロ)から、システムジェネレーションユーティリティを経て、実行時制御ブロックへとコンパイルされる。

以下のコード例を見てほしい。これが、実務で使われる標準的なPSBジェネレーションのソース定義(IMS形式)だ。

  • PSBGEN: 顧客管理サブシステム用 PSB 定義
  • 対象プログラム: CUSTUPD0 (顧客情報更新バッチ)


PRINT NOGEN

  • PSBのマクロ定義開始(LANG=COBOLを指定し、通信領域などをCOBOL向けに最適化)

PSBGEN LANG=COBOL, <-- ホスト言語指定 PSBNAME=CUSTPSB <-- PSBのモジュール名

  • 1つ目のPCB: 顧客マスターデータベースへのアクセス定義

PCB TYPE=DB, <-- データベース用PCB DBDNAME=CUSTDB, <-- 対象DBD(物理DB名) PROCOPT=A <-- 処理オプション: A(All/全許可)

  • 階層構造における機密保護とビューの制限(SENSEG: 感応セグメント)

SENSEG NAME=CUSTSEG, <-- 根(ルート)セグメント PARENT=0, <-- 親なし PROCOPT=U <-- このセグメントは更新可能 SENSEG NAME=ACCSSEG, <-- 子セグメント(口座情報) PARENT=CUSTSEG, <-- 親はCUSTSEG PROCOPT=G <-- 参照(Get)のみ許可(機密保護) SENSEG NAME=LOGSEG, <-- 孫セグメント(監査ログ) PARENT=ACCSSEG, <-- 親はACCSSEG PROCOPT=L <-- ログ追加のみ(Load/Log)

  • PSBジェネレーションの終了

PSBGENEND
END

このコードのレビューポイント(プロの眼)

1. `PROCOPT=A` の安易な使用の禁止
PCBレベルで `PROCOPT=A`(All:参照・追加・置換・削除すべて許可)を指定するのは、設計をサボっている証拠だ。本当にそのプログラムがデータベース全体を削除する権限を持つべきか? 最小権限の原則に従い、必要な最小限のオプション(`G`:Getのみ、`U`:Updateなど)に絞るべきである。
2. `SENSEG` によるきめ細やかな権限剥奪
上記の例では、ルートである顧客セグメントは更新(`U`)できるが、機密性の高い口座セグメント(`ACCSSEG`)は参照(`G`)しかできないよう制限している。このように、同一のデータベースであっても、プログラムの役割に応じて「見えるセグメント」と「操作権限」を非対称に定義するのが正しい設計だ。

—

3. 堅牢な設計パターン:アンチパターンからの脱却

設計レビューで私が必ず差し戻す、よくある悪手と、その対策を共有しよう。

アンチパターン:全能型「ゴッドPSB」の乱立

  • 症状: すべてのバッチプログラムで同じ巨大なPSB(例: `ALLDBPSB`)を使い回している。
  • リスク: 1つのプログラムのバグやSQL(DL/Iコール)のミスが、本来触るべきではない基幹セグメントを破壊する。また、データベースの物理構造を変更した際の影響範囲が全プログラムに波及し、ビルドとテストが地獄と化す。
  • 対策(堅牢な設計): 「1プログラム・1PSB(原則)」を徹底せよ。プログラムのユースケース(参照専用、特定月次バッチ等)ごとに専用のPSBを生成し、アクセスするセグメントも極限まで削ぎ落とせ。

—

4. パフォーマンス上の注意点とトラブルシューティング

「PSB定義がパフォーマンスに影響するのか?」と侮るなかれ。階層型DBMSの内部挙動を知る者にとって、ここは極めて重要なポイントだ。

1. バッファプール競合とPSBのサイズ

PSBが生成する制御ブロック(Control Block)は、オンライン処理時やバッチ実行時にメモリ(CSA/ECSA領域など)にロードされる。
あまりにも多くの `SENSEG` を定義した肥大化したPSBや、不必要に多数のPCBを束ねたPSBは、領域を圧迫し、スワップやメモリ不足によるスループット低下を引き起こす。

2. ポインタ検証オーバーヘッド

`SENSEG` で複雑なパス(階層を飛び越えた定義など)を定義すると、DBMSのモジュール(DL/Iインナー)がセグメントの位置を特定するためのセグメント・サーチ・ルックアップ(SSA)の解決に余計なCPUサイクルを消費する。
スキーマ定義(DBD)とPSB(SENSEG)の階層構造は常に一致させ、無駄なポインタ追跡が発生しないパスを設計すること。

—

チーフアーキテクトからのメッセージ

階層型DBMSのPSB生成プロセスは、単なる「おまじないのコンパイル作業」ではない。それは、アプリケーションとデータの間にある「信頼の契約書」であり、システム全体の堅牢性を担保する最後の砦だ。

次に君たちがコードや定義を書くとき、こう自問してほしい。
「このPSBは、このプログラムに本当に不要なデータを見せていないか?」
「権限は最小限に絞られているか?」

この細部へのこだわりこそが、何十年も止まらないシステムを作り上げるエンジニアの矜持だ。妥協のない設計を期待する。

コメント

タイトルとURLをコピーしました