ORA-01950报错但配额已设,问题在于配额未配对目标表空间——需确认建对象时显式指定的表空间(如TBS_IDX)或默认表空间是否匹配,检查dba_ts_quotas中对应记录、大小写及max_bytes值,并核实表空间物理空间是否充足。

ORA-01950报错但配额已设,问题出在哪
有配额仍报ORA-01950,大概率不是配额没设,而是配额没设对地方——用户在目标表空间上查不到DBA_TS_QUOTAS记录,或MAX_BYTES = 0,或大小写不匹配。
Oracle校验配额时只看建对象语句里显式指定的表空间(如TABLESPACE idx_tbs),或用户默认表空间(查DBA_USERS.DEFAULT_TABLESPACE)。哪怕你在USERS上有无限配额,建索引时写了TABLESPACE TBS_IDX,就只检查TBS_IDX上的配额。
- 用双引号创建的表空间名(如
"Idx_Tbs")是大小写敏感的,查DBA_TS_QUOTAS时必须严格匹配 -
MAX_BYTES = 0等效于无配额,不是“没设”,而是“设了禁止” - 查询语句必须带用户名和表空间名全大写(除非建的时候用了双引号):
SELECT tablespace_name, max_bytes FROM dba_ts_quotas WHERE username = 'MY_USER' AND tablespace_name = 'TBS_IDX';
UNLIMITED TABLESPACE权限为何不生效
GRANT UNLIMITED TABLESPACE TO user确实能绕过所有配额检查,但它对SYSTEM和SYSAUX表空间无效——这是Oracle硬编码限制,不是权限配置问题。
更隐蔽的是:如果之前给用户授予过DBA角色,后来又REVOKE DBA,UNLIMITED TABLESPACE权限可能被连带收回(取决于Oracle版本和撤销方式),导致原本可用的配额突然失效。
- 执行
SELECT * FROM dba_sys_privs WHERE grantee = 'MY_USER' AND privilege = 'UNLIMITED TABLESPACE';确认权限是否还在 - 不要依赖
DBA角色来间接获取配额能力,生产环境应显式授QUOTA UNLIMITED ON xxx -
GRANT UNLIMITED TABLESPACE不能解决SYSTEM表空间问题,必须换表空间
建表成功但建索引失败,配额要分表空间配
表和索引可以落在不同表空间。用户能在USERS建表,不代表能在INDEXES建索引——Oracle对索引段分配单独校验目标表空间配额。
典型场景:主键索引建在TBS_IDX,函数索引建在TBS_FUN,每个都得单独配额。漏配任意一个,对应索引就失败。
- 从
CREATE INDEX语句中提取TABLESPACE后的名字,逐个查DBA_TS_QUOTAS - 跨用户建索引(如
CREATE INDEX ON other_user.table)时,检查的是当前执行用户的配额,不是表属主的 - 批量建索引前,先确保所有涉及的表空间都已配额,避免部分成功部分失败
配额生效但空间仍不足,别混淆quota和tablespace容量
ORA-01536: space quota exceeded表示用户配额用完;ORA-01653: unable to extend table才是表空间物理空间不足。两者日志相似,但根因完全不同。
查DBA_TS_QUOTAS发现MAX_BYTES = -1(即无限配额),但建对象仍失败,就要立刻转向查表空间剩余空间:SELECT tablespace_name, bytes/1024/1024 mb_free FROM dba_free_space GROUP BY tablespace_name;
- 配额是“用户能用多少”,表空间大小是“磁盘还剩多少”,二者独立控制
- 即使用户配额无限,若表空间数据文件已满且未开启
AUTOEXTEND,照样无法分配新段 - 临时表空间(
TEMPORARY TABLESPACE)不需要配额,但排序/哈希操作失败可能是TEMP空间不足,而非配额问题
配额逻辑看似简单,实际要同时盯住三处:用户默认表空间、语句显式指定的表空间、以及该表空间本身的物理容量。任一环脱节,ORA-01950就会准时出现。


















