Db2の「とりあえず週次で全REORG」をやめる ― REORGCHKでいつやるかを判断する
「毎週日曜の深夜、全テーブルに REORG と RUNSTATS を流している」——Db2の現場でよく見る運用です。定期的にやっておけば安心と考えがちですが、この「とりあえず全部・定期的に」という方針が、かえって性能問題を引き起こすことがあります。
この記事では、REORG と RUNSTATS が何をしているのかを整理したうえで、「いつ・どのテーブルに実行すべきか」を自分で判断できるようになることを目標にします。判断の中心になるのが REORGCHK です。
そもそもREORGは何を直しているのか
テーブルは INSERT・UPDATE・DELETE を繰り返すと物理的に断片化します。断片化は主に3種類です。
| 種類 | 何が起きるか | 影響 |
|---|---|---|
| オーバーフロー行 |
VARCHAR の更新で行が元ページに収まらず別ページへ移動、元位置にポインタだけ残る |
1行の読み取りに2回のI/O |
| ページの低密度化 |
DELETE 多発でページ内に空きが増える |
同じ件数を読むのに多くのページI/O |
| 空ページの滞留 |
DELETE で空になったページが残り続ける |
スキャンで空ページを読み飛ばすコスト |
REORG はデータを物理的に再配置して、これらを解消します。断片化していないテーブルをREORGしても得るものはなく、後述のロックや実行時間といったコストだけが残ります。
REORGCHK:やるべきかを「測ってから」決める
断片化しているかは REORGCHK で測れます。
# 全テーブルを現在の統計で診断(統計は更新しない)
db2 "REORGCHK CURRENT STATISTICS ON TABLE ALL"
# 特定テーブルを診断(同時にRUNSTATSも実行)
db2 "REORGCHK UPDATE STATISTICS ON TABLE <スキーマ>.<テーブル>"
実機で流すと、こういうヘッダと表が出ます。
F1: 100 * OVERFLOW / CARD < 5
F2: 100 * (data page の有効スペース使用率) > 70
F3: 100 * (必須ページ数 / 合計ページ数) > 80
SCHEMA.NAME CARD OV NP FP ... F1 F2 F3 REORG
見るのは右端の REORG 列です。F1/F2/F3 それぞれの閾値を外れると、その位置に * が立ちます。
| REORG列 | 意味 |
|---|---|
--- |
3条件とも問題なし → REORG不要 |
*-- |
F1(オーバーフロー行)が閾値超過 |
-*- |
F2(スペース効率)が閾値超過 |
*** |
全条件で要REORG |
落とし穴1:自動RUNSTATSが業務ピークに走って計画が変わる
自動RUNSTATSは「統計が古い」とDb2が判断したタイミングで走ります。それが業務時間中でも、です。現在の設定を確認します。
db2 "GET DB CFG FOR <DB名>" | grep -iE "AUTO_RUNSTATS|AUTO_REORG|AUTO_STMT_STATS"
実機の既定はこうなっていました。
自動 RUNSTATS (AUTO_RUNSTATS) = ON
リアルタイム統計 (AUTO_STMT_STATS) = ON
自動再編成 (AUTO_REORG) = OFF
デフォルトで自動RUNSTATSはONです。何もしなければ、Db2が勝手なタイミングで統計を更新し、計画が変わり得る状態です。手動管理に切り替えるなら次のようにします。
db2 "UPDATE DB CFG FOR <DB名> USING AUTO_RUNSTATS OFF"
手動に切り替えたら、テーブルの性質でタイミングを決めます。
| テーブル種別 | RUNSTATSのタイミング |
|---|---|
| 日次バッチで大量 INSERT/DELETE | バッチ完了直後 |
| 参照系メイン・更新少 | 週次または月次 |
| 安定したマスター | データ変更時のみ |
自動RUNSTATSを手動に切り替える判断基準と、実行計画が変わった事例は本の第10章で扱っています。
落とし穴2:REORG直後のバッチがかえって遅い
REORGは正しく効いているのに、直後の初回スキャンだけは「整ったばかりで温まっていない」状態になります。だからREORGはバッチの直前ではなく、直後か業務の合間に置きます。
推奨スケジュール例(夜間)
22:00 夜間バッチ開始
02:00 夜間バッチ完了
02:15 REORG 実行(先に物理を整える)
04:30 RUNSTATS 実行(整った状態をカタログへ反映)
05:00 REBIND / パッケージキャッシュのフラッシュ
06:00 早朝バッチ開始
順番が大事です。REORG → RUNSTATS → 再バインド の順にすることで、「整った物理」と「最新の統計」と「その統計を使う新しい計画」が揃います。
この順番で流しても遅いままなら、原因は統計の鮮度ではありません。パターン別の切り分けは別記事にまとめています。
インプレース vs オフライン
REORGには2モードあります。メンテナンス枠の有無で選びます。
| モード | 特徴 | 向くケース |
|---|---|---|
| オフライン(既定) | 実行中はテーブルロック。短時間で完了 | 深夜メンテ枠がある |
| インプレース | 業務中に実行可。完了まで時間がかかる | 24時間稼働で枠がない |
# オフライン(テーブルロックあり)
db2 "REORG TABLE <スキーマ>.<テーブル>"
# インプレース(オンライン実行、非同期)
db2 "REORG TABLE <スキーマ>.<テーブル> INPLACE START"
# インプレースの進捗確認
db2pd -db <DB名> -reorg
# インプレースの停止
db2 "REORG TABLE <スキーマ>.<テーブル> INPLACE STOP"
# テーブルREORGの後は索引の再編成も
db2 "REORG INDEXES ALL FOR TABLE <スキーマ>.<テーブル>"
AUTO_REORGを使うなら性質を理解して
Db2には REORGCHK の結果に基づく自動REORG(AUTO_REORG)もあります。
db2 "GET DB CFG FOR <DB名>" | grep -i auto_reorg
db2 "UPDATE DB CFG FOR <DB名> USING AUTO_REORG ON"
ただし AUTO_REORG はインプレースREORGとして実行されます。前述のとおりインプレースは時間がかかるため、大きなテーブルを多数抱えるシステムでは自動REORGが長時間走り続けることがあります。業務特性を見て、自動か手動かを選んでください。
REORGには容量の副作用もあります。USE 句を付けないREORGは同じ表スペース内にコピーを作るため、表は縮んでも表スペースの割り当ては増えます。空きを取り戻す目的で流すなら USE は必須です。
まとめ
| 項目 | 着眼点 |
|---|---|
| REORGCHK |
--- はREORG不要。F3だけの * は改善限定的。測ってから決める
|
| 自動RUNSTATS | 既定でON。実行タイミングを制御できず計画変更リスク |
| REORGの順番 | REORG → RUNSTATS → 再バインド。バッチ直前は避ける |
| インプレース | 業務中可だが長時間・非同期。完了まで見届ける |
| 索引REORG | テーブルREORG後に忘れず実行 |
📕 もっと深く:Db2運用を12章で体系化した本を書きました
この記事で扱ったRUNSTATS・REORGの制御は、Db2運用の一領域にすぎません。
Db2はRDBMS市場でシェア数%。情報が少なく、頼れるのは膨大な公式マニュアルだけ——そんな現状を変えたくて、「なぜこの値にするのか」「この障害のとき次に何を見るのか」という、マニュアルに載っていない現場の文脈を1冊にしました。実機で検証した内容と、Db2の設計上そうなる理由をまとめました。
アーキテクチャ/構成パラメーター選定/セキュリティ/バックアップ・リカバリ/HADR/pureScale/日常点検の自動化/メモリ・ロック競合/SQLチューニング/RUNSTATS・REORG(本記事の深掘り版)/MON_GET監視/現場の難題集まで、全12章+運用シェルスクリプト集です。
現場で「これはハマった」というREORG/統計まわりのネタがあれば、コメントで教えてください。
Discussion