2.

Oracle セグメント完全ガイド(Table / Index / Extent / ASSM / PCTFREE)

編集
この記事の要点
  • セグメント (Segment) は Oracle で「特定オブジェクトが使う領域全体」を指す論理単位
  • 種類: Table / Index / Cluster / Temporary / Rollback (Undo) / LOB
  • セグメントは複数の Extent の集まり、Extent は連続した Block の集まり
  • USER_SEGMENTS / DBA_SEGMENTS でサイズ・配置を確認
  • ASSM (Automatic Segment Space Management) が現在の標準。フリーリスト管理を自動化
  • PCTFREE / PCTUSED で行追加用の予約領域と再利用閾値を制御

セグメントの位置づけ

Oracle の物理構造と論理構造の関係:

論理構造 (Logical Structure)
    Database
    └── Tablespace(論理的なグルーピング)
        └── Segment(特定オブジェクトの領域全体)★ 本記事のテーマ
            └── Extent(連続した Block の集まり)
                └── Block(最小 I/O 単位、通常 8KB)

物理構造 (Physical Structure)
    Database
    └── Datafile (.dbf)
        └── OS File System Block

1 セグメント = 1 オブジェクト(基本的に)。例えば EMPLOYEES テーブルには EMPLOYEES セグメントが割り当てられ、その下に複数の Extent、さらに Block が並びます。

セグメントの種類

種類用途
Table Segment通常テーブルの行データEMPLOYEES
Index SegmentB-Tree インデックスのデータEMP_PK
Cluster Segmentクラスタ表の共通領域INDEX / HASH CLUSTER
Temporary SegmentORDER BY / GROUP BY / HASH JOIN 等の中間結果TEMP テーブルスペース
Rollback / Undo Segment更新前イメージ(UNDO データ)UNDOTBS1
LOB SegmentCLOB / BLOB 本体(大容量カラム)LOB$_xxx
Partition Segmentパーティション表 / 索引の各パーティションEMP_P_2024_01

セグメントを確認する

-- 自分が所有するセグメント一覧
SELECT segment_name, segment_type, tablespace_name,
       bytes / 1024 / 1024 AS size_mb,
       extents, blocks
FROM   user_segments
ORDER BY bytes DESC;

-- 全 DB のセグメント(DBA 権限)
SELECT owner, segment_name, segment_type, tablespace_name,
       bytes / 1024 / 1024 AS size_mb
FROM   dba_segments
WHERE  tablespace_name = 'USERS'
ORDER BY bytes DESC;

-- 特定テーブルが使う Extent
SELECT segment_name, extent_id, blocks, bytes
FROM   user_extents
WHERE  segment_name = 'EMPLOYEES'
ORDER BY extent_id;

-- セグメントの未使用領域(HWM 下の Free Block)
SELECT segment_name, blocks AS total_blocks,
       (blocks - blocks * (1 - PCT_FREE/100)) AS free_estimate
FROM   user_segments s, user_tables t
WHERE  s.segment_name = t.table_name;

STORAGE 句

セグメント作成時に Extent サイズや拡張ルールを指定できます。Locally Managed Tablespace では多くが無視されますが、知っておく価値はあります。

CREATE TABLE big_log (
    id   NUMBER PRIMARY KEY,
    body CLOB
)
TABLESPACE app_data
PCTFREE 10                              -- 行追加用に 10% 予約
PCTUSED 40                              -- 使用率 40% を切ったらフリーリスト復帰
INITRANS 4                              -- 初期トランザクションスロット数
STORAGE (
    INITIAL 64K                         -- 最初の Extent サイズ
    NEXT 1M                             -- 次の Extent サイズ
    PCTINCREASE 0                       -- Extent サイズの自動拡大率(旧)
    MINEXTENTS 1
    MAXEXTENTS UNLIMITED
    BUFFER_POOL DEFAULT                 -- バッファプール指定
);

PCTFREE と PCTUSED

ブロック内の領域管理パラメータです。UPDATE で行サイズが増えるかどうかで選びます。

用途PCTFREEPCTUSED
更新が少ない (INSERT only)10 (デフォルト)40
UPDATE で行が膨らむ (例: status カラム更新)20〜3040
UPDATE で大きく膨らむ (CLOB 追記)40〜5030
INSERT only ログ系(最大充填)0〜199

Row Migration / Chaining

PCTFREE が小さすぎると、UPDATE で行サイズが増えたときに同じブロックに収まらず別ブロックに移動(Row Migration)し、後続の SELECT が 2 ブロックを読む羽目に。

-- Row Migration の検出
ANALYZE TABLE employees COMPUTE STATISTICS;
SELECT table_name, chain_cnt
FROM   user_tables
WHERE  chain_cnt > 0;

-- 解消: 再構築
ALTER TABLE employees MOVE;
-- インデックスは UNUSABLE になるので再構築
ALTER INDEX emp_pk REBUILD;

ASSM (Automatic Segment Space Management)

Oracle 9i 以降の標準のフリースペース管理方式。旧来のフリーリスト方式に比べ、並列 INSERT のホットブロック競合を減らします。

-- ASSM が有効か確認
SELECT tablespace_name, segment_space_management
FROM   dba_tablespaces;
-- segment_space_management = AUTO → ASSM

-- 新規 Tablespace を ASSM で作成
CREATE TABLESPACE app_data
DATAFILE '/u01/oradata/app_data01.dbf' SIZE 100M
EXTENT MANAGEMENT LOCAL
SEGMENT SPACE MANAGEMENT AUTO;   -- ★

-- ASSM 配下では PCTUSED / FREELISTS / FREELIST GROUPS は無視される
-- PCTFREE のみ有効

Segment Advisor

未使用領域 (HWM の下の空き) や Row Migration を検出するアドバイザ。

-- セグメントアドバイザ実行
DECLARE
    task_id NUMBER;
BEGIN
    DBMS_ADVISOR.CREATE_TASK('Segment Advisor', task_id, 'my_task');
    DBMS_ADVISOR.CREATE_OBJECT('my_task', 'TABLE', 'HR', 'EMPLOYEES',
                                NULL, NULL, NULL);
    DBMS_ADVISOR.EXECUTE_TASK('my_task');
END;
/

-- 結果確認
SELECT message, more_info
FROM   user_advisor_findings
WHERE  task_name = 'my_task';

-- 推奨アクション: ALTER TABLE ... SHRINK SPACE
ALTER TABLE employees ENABLE ROW MOVEMENT;
ALTER TABLE employees SHRINK SPACE COMPACT;
ALTER TABLE employees SHRINK SPACE;
ALTER TABLE employees DISABLE ROW MOVEMENT;

Temporary Segment と Undo Segment

通常テーブルとは扱いが違う 2 つの特殊セグメントです。

Temporary Segment:
  - ORDER BY / GROUP BY / HASH JOIN / SUBQUERY などで中間結果を保持
  - TEMP テーブルスペースに作られる
  - セッション終了で開放
  - 監視: V$SORT_USAGE / V$TEMPSEG_USAGE
  - 不足: ORA-01652 unable to extend temp segment

Undo Segment:
  - UPDATE / DELETE 前の旧データを保持(ROLLBACK と Read Consistency のため)
  - UNDO テーブルスペースに作られる
  - UNDO_RETENTION で保持時間制御
  - 不足: ORA-01555 snapshot too old / ORA-30036 unable to extend undo

セグメントの削除と縮小

-- セグメント削除 (テーブル削除)
DROP TABLE old_table;          -- セグメントも消える(10g+ はゴミ箱経由)
DROP TABLE old_table PURGE;    -- ゴミ箱を経由せず即削除

-- 空のセグメントを残してデータだけ消す
TRUNCATE TABLE big_log;        -- 高速、Extent は MINEXTENTS まで残る
TRUNCATE TABLE big_log DROP STORAGE;   -- Extent も解放

-- セグメントの SHRINK
ALTER TABLE t ENABLE ROW MOVEMENT;
ALTER TABLE t SHRINK SPACE;
ALTER TABLE t DISABLE ROW MOVEMENT;

FAQ

Q: テーブルが思ったよりサイズが大きい
A: HWM 下に未使用領域がある可能性。Segment Advisor で確認し、SHRINK で縮小。Row Migration が多いなら MOVE で再構築。

Q: パーティションテーブルのセグメントは?
A: パーティションごとに 1 セグメント。DBA_SEGMENTSpartition_name で識別できます。

Q: LOB セグメントが肥大化する
A: 旧バージョンの SecureFile LOB は削除しても自動解放されないことが。ALTER TABLE ... MODIFY LOB ... (SHRINK SPACE) で縮小。

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. 表領域
  2. セグメント
  3. エクステント
  4. データブロック

最近更新/作成されたページ