【Oracle】ORA-01653: 表を拡張できません ── 原因・緊急対処・HWM回収・再発防止まで完全解説

INSERT や UPDATE を実行中に突然発生する ORA-01653: 表を拡張できません。このエラーは表領域の空き容量不足が原因ですが、「どの表領域を」「どう対処するか」を素早く判断するには、エラーメッセージの読み方から緊急対処・恒久対策まで体系的な理解が必要です。本記事では DBA・開発者双方の視点で ORA-01653 の解決手順を完全解説します。

この記事で解決できること

  • ORA-01653 エラーメッセージの正確な読み方(テーブル名・表領域名・ブロック数)
  • 緊急対処3パターン(AUTOEXTEND有効化・ファイルサイズ拡張・データファイル追加)
  • 表領域・セグメントの空き容量を診断するSQL
  • HWM(高水位標)の概念とスペース回収の方法
  • TEMP表領域・UNDO表領域で発生する類似エラーとの使い分け
  • 再発防止のための監視・AUTOEXTEND設計指針
スポンサーリンク

ORA-01653 とは

ORA-01653 は、Oracle がテーブルのセグメントを拡張しようとしたが、表領域に十分な空き容量がなかった場合に発生するエラーです。

ORA-01653: unable to extend table SCOTT.EMP by 128 in tablespace USERS

エラーメッセージの読み方

項目 意味
スキーマ名 SCOTT テーブルの所有者
テーブル名 EMP 拡張しようとしたテーブル
拡張ブロック数 128 必要だったが確保できなかったブロック数
表領域名 USERS 空き容量が不足している表領域

ブロック数 → 必要バイト数の換算

必要バイト数 = ブロック数 × DB_BLOCK_SIZE

例)128ブロック × 8,192バイト(8KBブロック)= 約1MB

DB_BLOCK_SIZEは SHOW PARAMETER db_block_size で確認できます。

発生メカニズム

Oracle のテーブルはデータが増えるとエクステント(Extent)と呼ばれる連続した領域を追加確保します。エクステントを確保できる空き領域が表領域にない場合に ORA-01653 が発生します。

テーブルへのINSERT/UPDATE

       ↓

現在のエクステントが満杯

       ↓

新しいエクステントを表領域に要求

       ↓

【空き不足】 → ORA-01653 発生

       ↓

【空き十分】 → エクステント確保してINSERT継続

STEP 1:現状診断 ── どの表領域が何MB不足しているか

まず対象の表領域の空き状況を正確に把握します。

表領域の空き容量を確認する

SELECT

  df.tablespace_name,

  ROUND(df.total_mb, 1)        AS total_mb,

  ROUND(fs.free_mb, 1)         AS free_mb,

  ROUND(df.total_mb

        - NVL(fs.free_mb, 0), 1) AS used_mb,

  ROUND((NVL(fs.free_mb, 0)

         / df.total_mb) * 100, 1) AS free_pct

FROM

  (SELECT tablespace_name,

          SUM(bytes) / 1024 / 1024 AS total_mb

   FROM   dba_data_files

   GROUP BY tablespace_name) df

  LEFT JOIN

  (SELECT tablespace_name,

          SUM(bytes) / 1024 / 1024 AS free_mb

   FROM   dba_free_space

   GROUP BY tablespace_name) fs

    ON df.tablespace_name = fs.tablespace_name

ORDER BY free_pct;

データファイルの AUTOEXTEND 状態を確認する

SELECT

  file_name,

  ROUND(bytes   / 1024 / 1024, 1) AS current_mb,

  ROUND(maxbytes/ 1024 / 1024, 1) AS max_mb,

  autoextensible,

  ROUND(increment_by * (SELECT value FROM v$parameter

                        WHERE name = 'db_block_size')

        / 1024 / 1024, 1)          AS increment_mb

FROM dba_data_files

WHERE tablespace_name = 'USERS'

ORDER BY file_name;

MAX_MB の表示に関する注意

autoextensible = NO の場合、maxbytes は 0 と表示されます(拡張しないので上限なし)。

autoextensible = YES かつ max_mb = 0(maxbytes = 0)の場合は MAXSIZE UNLIMITED(OSのファイルシステム上限まで拡張)を意味します。

autoextensible = YES かつ max_mb に具体的な数値がある場合はその値が上限です。

エラーが起きたテーブルのセグメントサイズを確認する

SELECT

  owner,

  segment_name,

  segment_type,

  ROUND(bytes / 1024 / 1024, 1) AS size_mb,

  blocks,

  extents

FROM dba_segments

WHERE owner = 'SCOTT'

  AND segment_name = 'EMP'

ORDER BY size_mb DESC;

STEP 2:緊急対処 ── 3つのアプローチ

対処A:AUTOEXTEND を有効にする(最速・推奨)

既存のデータファイルに自動拡張を設定します。本番環境で最も素早く対応できる方法です。

-- AUTOEXTEND を ON にして最大 30GB まで 500MB ずつ拡張

ALTER DATABASE DATAFILE

  '/u01/oradata/ORCL/users01.dbf'

  AUTOEXTEND ON

  NEXT 500M

  MAXSIZE 30720M;



-- ファイルパスは dba_data_files で確認

SELECT file_name FROM dba_data_files

WHERE tablespace_name = 'USERS';

NEXT・MAXSIZE の設計指針

NEXT:拡張の単位。小さすぎると頻繁に拡張が走りオーバーヘッドになる。100M〜1G が目安

MAXSIZE:上限。UNLIMITED にするとディスク枯渇リスクがある。ディスク容量の80%程度を目安に設定

対処B:既存データファイルのサイズを手動拡張する

AUTOEXTEND を使いたくない場合や、すぐに一定量を確保したい場合に使います。

-- データファイルを 10GB に拡張

ALTER DATABASE DATAFILE

  '/u01/oradata/ORCL/users01.dbf'

  RESIZE 10240M;

RESIZE で縮小はできない場合がある

セグメントが存在する領域より小さい値に RESIZE しようとするとエラーになります。縮小は HWM を下げる必要があります(後述)。

対処C:新しいデータファイルを追加する

既存ファイルがディスクの制限(最大32GB)に達している場合や、別ディスクに分散させたい場合に使います。

-- 新しいデータファイルを表領域に追加(5GB・AUTOEXTEND ON)

ALTER TABLESPACE USERS

  ADD DATAFILE '/u02/oradata/ORCL/users02.dbf'

  SIZE 5120M

  AUTOEXTEND ON

  NEXT 500M

  MAXSIZE 20480M;

3つの対処法の比較

方法 即効性 DBA権限 ダウンタイム 推奨場面
A. AUTOEXTEND 有効化 ◎ 最速 必要 なし まず試みる第一手
B. RESIZE(手動拡張) ○ 速い 必要 なし 拡張量を明示したいとき
C. データファイル追加 ○ 速い 必要 なし 既存ファイルが上限に達したとき

STEP 3:根本原因の調査と恒久対策

どのテーブルがスペースを大量消費しているか調べる

-- 表領域 USERS のセグメントをサイズ順に確認

SELECT

  owner,

  segment_name,

  segment_type,

  ROUND(bytes / 1024 / 1024, 1) AS size_mb,

  extents

FROM   dba_segments

WHERE  tablespace_name = 'USERS'

ORDER  BY bytes DESC

FETCH FIRST 20 ROWS ONLY;  -- Oracle 12c以降

-- Oracle 11g以前は: WHERE ROWNUM <= 20 を WHERE 句に追加

HWM(高水位標)とスペースの無駄遣い

HWM(High Water Mark)とは、テーブルに書き込まれたことがある最大の位置を示すマーカーです。大量の DELETE を行っても HWM は下がらず、Oracle はその領域をフルスキャン時に読み込み続けます。

-- テーブルの実際の行数とセグメントサイズを比較

SELECT

  a.owner,

  a.table_name,

  a.num_rows,

  ROUND(b.bytes / 1024 / 1024, 1) AS segment_mb

FROM   dba_tables  a

JOIN   dba_segments b

  ON   a.owner        = b.owner

 AND   a.table_name   = b.segment_name

 AND   b.segment_type = 'TABLE'

WHERE  a.owner = 'SCOTT'

ORDER  BY segment_mb DESC;

HWM を下げてスペースを回収する方法

方法 SQL 特徴
SHRINK SPACE ALTER TABLE t SHRINK SPACE; オンライン実行可。ROW MOVEMENT 有効化が必要
MOVE ALTER TABLE t MOVE; HWM をリセット。インデックス再構築が必要
TRUNCATE TRUNCATE TABLE t; 全データ削除。HWM を完全リセット
MOVE TABLESPACE ALTER TABLE t MOVE TABLESPACE ts; 別表領域に移動しながら HWM をリセット
-- SHRINK SPACE の実行手順

-- 1. ROW MOVEMENT を有効化(必須)

ALTER TABLE SCOTT.EMP ENABLE ROW MOVEMENT;



-- 2. SHRINK SPACE を実行

ALTER TABLE SCOTT.EMP SHRINK SPACE;



-- 3. HWM も下げる場合は COMPACT + 別コマンド

-- ALTER TABLE SCOTT.EMP SHRINK SPACE COMPACT;

-- ALTER TABLE SCOTT.EMP SHRINK SPACE;

SHRINK SPACE の前提条件と注意点

SHRINK SPACEASSM(自動セグメント領域管理) の表領域でのみ使用可能です(手動セグメント管理では不可)

・通常インデックスは維持されます(UNUSABLE にはならない)

・SHRINK SPACE 実行中、テーブルへの DML は一時的にブロックされる場合があります

・一方 ALTER TABLE t MOVE の後はインデックスが UNUSABLE になるため ALTER INDEX idx REBUILD が必要です

TEMP 表領域・UNDO 表領域での類似エラー

ORA-01653 はユーザーデータの表領域(PERMANENT)で発生しますが、TEMP・UNDO でも類似エラーが発生します。

エラー 表領域種別 主な原因 対処
ORA-01653 PERMANENT データ表領域の空き不足 AUTOEXTEND 有効・ファイル追加
ORA-01654 PERMANENT インデックス拡張の空き不足 同上(対象はインデックス)
ORA-01652 TEMP TEMP 表領域の空き不足(ソート等) TEMP 表領域を拡張
ORA-30036 UNDO UNDO 表領域の空き不足 UNDO 表領域を拡張・UNDO_RETENTION 見直し
-- ORA-01652:TEMP 表領域の拡張

ALTER TABLESPACE TEMP

  ADD TEMPFILE '/u01/oradata/ORCL/temp02.dbf'

  SIZE 2048M

  AUTOEXTEND ON

  NEXT 256M

  MAXSIZE 8192M;



-- ORA-30036:UNDO 表領域の拡張

ALTER DATABASE DATAFILE

  '/u01/oradata/ORCL/undotbs01.dbf'

  AUTOEXTEND ON NEXT 512M MAXSIZE 20480M;

再発防止:監視と設計指針

表領域使用率を定期監視する SQL(アラート用)

-- 使用率が 80% を超えた表領域を抽出

SELECT

  df.tablespace_name,

  ROUND(df.total_mb, 0)             AS total_mb,

  ROUND(df.total_mb

        - NVL(fs.free_mb, 0), 0)    AS used_mb,

  ROUND((1 - NVL(fs.free_mb, 0)

         / df.total_mb) * 100, 1)   AS used_pct

FROM

  (SELECT tablespace_name,

          SUM(bytes) / 1024 / 1024 AS total_mb

   FROM   dba_data_files

   GROUP BY tablespace_name) df

  LEFT JOIN

  (SELECT tablespace_name,

          SUM(bytes) / 1024 / 1024 AS free_mb

   FROM   dba_free_space

   GROUP BY tablespace_name) fs

    ON df.tablespace_name = fs.tablespace_name

WHERE  (1 - NVL(fs.free_mb, 0) / df.total_mb) * 100 >= 80

ORDER  BY used_pct DESC;

AUTOEXTEND 設計チェックリスト

確認項目 推奨設定 確認SQL
AUTOEXTEND 有効化 本番は基本 ON SELECT autoextensible FROM dba_data_files
MAXSIZE の設定 ディスク容量の 70〜80% SELECT maxbytes/1024/1024 FROM dba_data_files
NEXT の単位 100M〜1G(小さすぎない) SELECT increment_by FROM dba_data_files
ディスク残容量 常に 20% 以上確保 OS コマンド(df -h / dir)
表領域使用率監視 80% で警告・90% でアラート 上記の監視 SQL を定期実行

よくある質問(FAQ)

❓ DBA 権限がなくてもできる対処はある? (クリックで開閉)

表領域の拡張は DBA 権限が必要です。一般ユーザーでできる対処としては以下があります。

  • 不要なデータを DELETE して空きを作る(ただし HWM は下がらないためセグメントサイズは変わらない)
  • TRUNCATE TABLE(全データ削除可なら)で HWM をリセット
  • 不要なテーブルを DROP して表領域を解放

根本的な解決には DBA に表領域拡張を依頼してください。

❓ DELETE してもエラーが解消しない理由は? (クリックで開閉)

DELETE はデータを行レベルで削除しますが、Oracle はそのブロックをすぐに他のテーブルの新規エクステントとして再利用しません。削除したブロックは同じテーブルへの新規 INSERT では再利用されますが、別テーブルの新規エクステント確保には使われない場合があります。

また、DELETE で空いた行スロットは既存テーブルへの INSERT には使われますが、セグメント自体のサイズ(HWM)は変わらないため、表領域全体の空き容量には影響しません。

❓ ORA-01653 と ORA-01654 の違いは? (クリックで開閉)

ORA-01653:テーブルのセグメント拡張失敗

ORA-01654:インデックスのセグメント拡張失敗

発生原因・対処法はほぼ同じです。ORA-01654 はインデックスの REBUILD(ALTER INDEX idx REBUILD)後に大量データが追加されたときに起きやすいです。

❓ AUTOEXTEND UNLIMITED にすべき? (クリックで開閉)

MAXSIZE UNLIMITED にするとディスクが枯渇するまで拡張し続けます。本番環境では ディスク容量の 70〜80% を MAXSIZE として設定し、使用率が 80% を超えたらアラートを出して計画的にディスクを追加するのがベストプラクティスです。

MAXSIZE UNLIMITED は開発・検証環境で便利ですが、本番では監視できなくなるリスクがあるため避けることを推奨します。

❓ impdp(Data Pump インポート)中に ORA-01653 が出た場合は? (クリックで開閉)

impdp 中に ORA-01653 が発生するとインポートが失敗します。対処手順は以下のとおりです。

  1. エラーメッセージで表領域名を確認
  2. 対象の表領域を AUTOEXTEND ON または RESIZE で拡張
  3. impdp を CONTENT=DATA_ONLY で再実行(スキーマが作成済みなら)
    または最初から再実行

大量データをインポートする前に、インポート対象のサイズを見積もって事前に表領域を拡張しておくことを推奨します。

まとめ:ORA-01653 対処フロー

フェーズ アクション 主なSQL/コマンド
診断 表領域の空き・データファイル状況を確認 dba_data_files / dba_free_space を SELECT
緊急対処① AUTOEXTEND を有効化 ALTER DATABASE DATAFILE ... AUTOEXTEND ON NEXT 500M MAXSIZE 30G
緊急対処② データファイルを手動拡張 ALTER DATABASE DATAFILE ... RESIZE 10G
緊急対処③ データファイルを追加 ALTER TABLESPACE ... ADD DATAFILE ...
根本対策 HWMを下げてスペース回収 SHRINK SPACE / MOVE / TRUNCATE
再発防止 使用率80%監視・MAXSIZE設定 監視SQLをスケジュール実行

ORA-01653 は放置すると業務停止につながる重大エラーです。まず AUTOEXTEND ON で即時対処し、その後セグメントサイズと HWM を調査して中長期対策を講じるという2段階アプローチが実務での定石です。また、使用率 80% アラートを設定して本番で突然エラーが起きる事態を未然に防ぐことが最善策です。