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 SPACE は ASSM(自動セグメント領域管理) の表領域でのみ使用可能です(手動セグメント管理では不可)
・通常インデックスは維持されます(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 が発生するとインポートが失敗します。対処手順は以下のとおりです。
- エラーメッセージで表領域名を確認
- 対象の表領域を AUTOEXTEND ON または RESIZE で拡張
- 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% アラートを設定して本番で突然エラーが起きる事態を未然に防ぐことが最善策です。