【Oracle】ORA-01950の原因と解決方法|表領域QUOTA不足の直し方

ORA-01950: no privileges on tablespace は、Oracleで表や索引などのセグメントを作成・拡張しようとした時に、対象ユーザーへ表領域の QUOTA が割り当てられていない、または割当量を使い切っている場合に発生します。

よくある場面は、新規ユーザー作成後の CREATE TABLE、既存表への大量INSERT、Data Pumpインポート、索引作成、CTAS、LOBデータ投入です。権限不足に見えますが、通常の CREATE TABLE 権限だけでは足りず、保存先表領域を使うためのQUOTA確認が必要です。

先に結論
まず対象ユーザーの DEFAULT_TABLESPACEDBA_TS_QUOTAS を確認します。必要に応じて ALTER USER user_name QUOTA 1G ON tablespace_name、または管理方針に合う場合のみ QUOTA UNLIMITEDUNLIMITED TABLESPACE を検討します。
スポンサーリンク

ORA-01950とは

Oracle公式の説明では、ORA-01950は指定された表領域に対するユーザーの割当量が不足している時に発生します。対処は、対象表領域に対するユーザーのQUOTAを増やす、または表・索引の作成先表領域を見直すことです。

表領域の基本は 表領域(Tablespace)完全ガイド、ユーザーと表領域の割り当ては 表領域にユーザーを割り当てる方法 も参考になります。

よくある発生パターン

新規ユーザーでCREATE TABLEした

ユーザー作成時にDEFAULT TABLESPACEは指定したものの、QUOTAを付与していないケースです。CREATE TABLE権限があっても表領域を使えません。

INSERTやData Pumpでデータ投入した

表は作れたものの、割り当て済みQUOTAを使い切り、追加のエクステントを確保できないケースです。

索引やLOBが別表領域に作られる

表本体の表領域にはQUOTAがあるが、INDEX表領域やLOB表領域にはQUOTAがないケースです。

PDBや接続先を間違えている

CDB/PDB環境で別のコンテナに接続して確認・設定しており、実際にエラーが出るPDBではQUOTAがないケースです。

まずユーザーと表領域を確認する

最初に、エラーになったユーザー、デフォルト表領域、一時表領域、アカウント状態を確認します。アプリ接続ユーザーとオブジェクト所有者が異なる場合は、どのユーザーがセグメントを作成しているかも確認します。

check-user-default-tablespace.sql
SELECT username,
       default_tablespace,
       temporary_tablespace,
       account_status
FROM dba_users
WHERE username = UPPER('&USER_NAME');

ユーザー作成や権限付与の基本は 新規ユーザー作成と権限付与の完全ガイド、権限全体の確認は ユーザー・権限・ロール完全ガイド も参照してください。

DBA_TS_QUOTASでQUOTAを確認する

ORA-01950では、DBA_TS_QUOTAS の確認が中心です。MAX_BYTES-1 なら、その表領域では無制限QUOTAです。行がない場合は、その表領域に対するQUOTAがありません。

check-tablespace-quota.sql
SELECT username,
       tablespace_name,
       bytes,
       max_bytes,
       blocks,
       max_blocks,
       CASE
         WHEN max_bytes = -1 THEN 'UNLIMITED'
         ELSE ROUND(bytes / 1024 / 1024) || 'MB / ' || ROUND(max_bytes / 1024 / 1024) || 'MB'
       END AS quota_usage
FROM dba_ts_quotas
WHERE username = UPPER('&USER_NAME')
ORDER BY tablespace_name;

現在の表領域使用量そのものを見たい場合は、表領域の使用状況を確認するSQLまとめ も役立ちます。

自分のユーザーで確認するSQL

DBA権限がない場合は、まず自分のユーザーから見える USER_TS_QUOTAS を確認します。ここに対象表領域が出てこない場合、その表領域にQUOTAがない可能性があります。

check-own-quota.sql
SELECT tablespace_name,
       bytes,
       max_bytes,
       CASE
         WHEN max_bytes = -1 THEN 'UNLIMITED'
         ELSE ROUND(bytes / 1024 / 1024) || 'MB / ' || ROUND(max_bytes / 1024 / 1024) || 'MB'
       END AS quota_usage
FROM user_ts_quotas
ORDER BY tablespace_name;
check-current-user.sql
SELECT sys_context('USERENV', 'CURRENT_USER') AS current_user,
       sys_context('USERENV', 'CURRENT_SCHEMA') AS current_schema,
       sys_context('USERENV', 'CON_NAME') AS con_name
FROM dual;

対処1: 対象表領域にQUOTAを付与する

対象ユーザーに、必要な表領域のQUOTAを付与します。本番ではいきなり無制限にせず、用途に応じた上限を設定する方が安全です。

grant-quota-on-tablespace.sql
-- 例: APP_USER に USERS 表領域を 1GB まで許可
ALTER USER app_user QUOTA 1G ON users;

-- 例: 開発環境などで無制限にする
ALTER USER app_user QUOTA UNLIMITED ON users;

ALTER USER の基本操作は ユーザーの情報を変更・削除する方法 にもまとめています。

対処2: CREATE USER時にQUOTAを指定する

新規ユーザー作成時点で、デフォルト表領域とQUOTAを合わせて指定しておくと、作成直後のORA-01950を防げます。

create-user-with-quota.sql
CREATE USER app_user IDENTIFIED BY "password"
  DEFAULT TABLESPACE users
  TEMPORARY TABLESPACE temp
  QUOTA 1G ON users;

GRANT CREATE SESSION, CREATE TABLE TO app_user;
DEFAULT TABLESPACEだけでは足りません
DEFAULT TABLESPACE users は、オブジェクト作成先の初期値を決める設定です。その表領域を実際に使えるかどうかは、QUOTAまたは UNLIMITED TABLESPACE 権限で決まります。

対処3: 作成先表領域を明示する

ユーザーのデフォルト表領域ではなく、別の表領域へ作成したい場合は、DDL側で TABLESPACE を明示します。ただし、その表領域にもQUOTAが必要です。

create-table-in-specific-tablespace.sql
CREATE TABLE app_order (
  order_id NUMBER PRIMARY KEY,
  order_name VARCHAR2(100)
)
TABLESPACE app_data;

テーブル作成時の表領域指定は CREATE TABLE完全ガイド、DML操作の基本は INSERT・UPDATE・DELETE完全ガイド を参照してください。

UNLIMITED TABLESPACEを使うべきか

UNLIMITED TABLESPACE システム権限を付与すると、ユーザーは任意の表領域を無制限に使用できるようになります。Oracleのセキュリティ管理資料でも、ユーザーに任意表領域の無制限利用を許可する方法として説明されています。便利ですが、影響範囲が大きいため本番アプリユーザーへ安易に付与するのは避けたい権限です。

個別QUOTA

表領域ごとに上限を制御できます。アプリユーザーや本番環境ではこちらが基本です。

QUOTA UNLIMITED ON tablespace

特定表領域だけ無制限にします。開発環境や専用スキーマで使いやすい一方、容量監視は必要です。

UNLIMITED TABLESPACE

すべての表領域を無制限に使える強い権限です。DBAや管理用ユーザー以外には慎重に扱います。

grant-unlimited-tablespace.sql
-- 影響が大きいため、本番アプリユーザーには慎重に使う
GRANT UNLIMITED TABLESPACE TO app_user;

-- 取り消す場合
REVOKE UNLIMITED TABLESPACE FROM app_user;

Data Pumpインポートで発生する場合

Data Pumpインポートでは、元環境の表領域名やスキーマ設定をそのまま使おうとして、移行先ユーザーにQUOTAがなくORA-01950になることがあります。移行先の表領域を確認し、必要なら REMAP_TABLESPACE やQUOTA付与を行います。

impdp-quota-check.txt
impdp app_user/password directory=DP_DIR dumpfile=app.dmp logfile=app.log \
  remap_schema=OLD_USER:APP_USER \
  remap_tablespace=OLD_DATA:APP_DATA

表領域不足や移行時の容量問題は 容量不足の緊急対応完全ガイド も参考になります。

CDB/PDB環境で確認すること

Oracle 12c以降のCDB/PDB構成では、接続しているコンテナが違うと、ユーザーやQUOTAを設定したつもりでも実行先PDBでは効いていないことがあります。ローカルユーザー、共通ユーザー、接続サービス名、CON_NAME を確認してからQUOTAを設定します。

check-pdb-container.sql
SHOW CON_NAME;

SELECT sys_context('USERENV', 'CON_NAME') AS con_name,
       sys_context('USERENV', 'SERVICE_NAME') AS service_name,
       sys_context('USERENV', 'CURRENT_USER') AS current_user
FROM dual;
CDB$ROOTで設定していないか確認
アプリがPDBへ接続しているのに、管理作業を CDB$ROOT 側で行っていると、対象PDBのユーザーQUOTAは変わりません。エラーが出ている接続先と同じPDBで確認してください。

索引・LOB・パーティションで起きるケース

表本体だけでなく、索引、LOB、パーティション、サブパーティションが別表領域に作られる設計では、それぞれの表領域にQUOTAが必要です。エラーに出た表領域名を見て、表本体なのか、索引なのか、LOBなのかを切り分けます。

check-object-tablespaces.sql
SELECT owner,
       segment_name,
       segment_type,
       tablespace_name,
       ROUND(bytes / 1024 / 1024) AS mb
FROM dba_segments
WHERE owner = UPPER('&USER_NAME')
ORDER BY tablespace_name, segment_type, segment_name;

QUOTAがあるのにORA-01950が出る場合

対象ユーザーにQUOTAがあるように見えるのにORA-01950が出る場合は、エラーで示された表領域と、実際にQUOTAを付けた表領域が違っていないかを確認します。特に索引表領域、LOB表領域、パーティション表領域、Data Pumpのリマップ漏れで起きやすいです。

表本体とは別のINDEX表領域

表のQUOTAはあるが、CREATE INDEXや主キー作成で使うINDEX表領域にQUOTAがないケースです。

LOB列だけ別表領域

CLOB/BLOBの格納先表領域にQUOTAがなく、大きなLOBデータ投入時に失敗するケースです。

Data PumpのREMAP漏れ

元環境の表領域へ作ろうとして、移行先ユーザーにその表領域のQUOTAがないケースです。

接続先PDB違い

確認したPDBと実行しているPDBが違い、設定したQUOTAが実行先では存在しないケースです。

ORA-01536との違い

ORA-01950

対象表領域に対するQUOTAがない、または使えない時に出やすいエラーです。新規作成や最初の拡張で発生します。

ORA-01536

表領域に対する割当量を超過した時に発生します。すでにQUOTAはあるが、上限まで使い切ったケースを疑います。

ORA-01653

表領域やデータファイル側の空き不足です。ユーザーQUOTAではなく、表領域自体の空き容量やAUTOEXTENDを確認します。

確認と修正の流れ

  1. エラーメッセージに表示された表領域名を確認する
  2. 実行ユーザーとオブジェクト所有者を確認する
  3. DBA_USERS でデフォルト表領域を確認する
  4. DBA_TS_QUOTAS で対象表領域のQUOTA有無と上限を確認する
  5. 必要な表領域に ALTER USER ... QUOTA ... ON ... を実行する
  6. 表・索引・LOB・Data Pumpの作成先表領域が意図通りか確認する
  7. PDB環境では、設定したコンテナとエラーが出る接続先が同じか確認する

よくある質問

CREATE TABLE権限があるのにORA-01950になるのはなぜですか?

CREATE TABLE は表を作る権限です。表領域の領域を使うには、対象表領域へのQUOTAが別途必要です。

DEFAULT TABLESPACEを設定すればQUOTAも付与されますか?

付与されません。DEFAULT TABLESPACEは作成先の初期値であり、使用可能量はQUOTAで制御します。

本番ではQUOTA UNLIMITEDにしてよいですか?

専用表領域で容量監視ができているなら選択肢になります。ただし、複数アプリが同じ表領域を共有する環境では、個別上限を設定した方が影響範囲を抑えやすいです。

まとめ

ORA-01950は、ユーザーが対象表領域を使うためのQUOTAを持っていない、または使い切っている時に発生します。権限不足というより、保存先表領域の割当量不足として切り分けるのが近道です。

まず DBA_USERSDBA_TS_QUOTAS を確認し、必要な表領域にALTER USER ... QUOTA ... ON ... を設定します。本番では UNLIMITED TABLESPACE を安易に付与せず、個別QUOTAと容量監視で管理するのが安全です。

参考