ORA-01950报错根本原因是用户在索引目标表空间(如TBS_IDX)缺乏配额,而非权限不足;即使拥有CREATE INDEX或UNLIMITED TABLESPACE权限,只要该表空间未授予对应配额(查DBA_TS_QUOTAS为空或max_bytes=0),建索引即失败。
ora-01950 报错根本不是权限问题,而是索引创建时目标表空间没配额——哪怕用户有 create index 权限、甚至 unlimited tablespace,只要索引要写入的那个表空间没给该用户配额,照样报错。
为什么建索引会单独触发 ORA-01950
建索引和建表不同,索引可以显式指定 TABLESPACE,且常被放在独立的表空间(如 TBS_IDX、INDEXES),而这个表空间往往和用户的默认表空间不一致。Oracle 在分配索引段时,只检查当前用户在该索引目标表空间上的配额,跟默认表空间或建表权限完全无关。
- 常见现象:用户在
USERS表空间能建表,但执行CREATE INDEX ... ON table_name ... TABLESPACE TBS_IDX就报错 - 查不到配额记录?说明压根没授权;查到
max_bytes = 0?等同于禁止写入 - 即使索引是为别人表建的(比如
CREATE INDEX idx ON other_user.table),也必须检查当前执行用户的配额,不是表属主的
怎么快速定位索引该配哪个表空间的配额
先确认索引语句里写的表空间名,再查这个表空间是否在 DBA_TS_QUOTAS 里有对应记录:
SELECT tablespace_name, max_bytes/1024/1024 AS mb FROM dba_ts_quotas WHERE username = 'YOUR_USER' AND tablespace_name = 'TBS_IDX';
- 返回空行 → 用户在
TBS_IDX上完全没配额 -
mb是 0 或很小 → 配额不足,需扩容 -
max_bytes = -1→ 已设为UNLIMITED,可排除配额问题 - 注意大小写:若数据库启用了区分大小写(如通过
SEC_CASE_SENSITIVE_LOGON=TRUE或使用双引号建表空间),tbs_idx和TBS_IDX视为不同名称
DBA 必须用什么语句授配额
必须由 SYS、SYSTEM 或具备 ALTER USER 权限的 DBA 账户执行,普通用户无法自授:
- 给固定配额(推荐用于测试或小数据场景):
ALTER USER your_user QUOTA 500M ON TBS_IDX; - 给无限制配额(全量迁移、生产环境索引重建常用):
ALTER USER your_user QUOTA UNLIMITED ON TBS_IDX; - 别误用
GRANT UNLIMITED TABLESPACE TO your_user:它绕过所有表空间配额控制,多数安全策略禁止启用,且不解决单表空间缺失配额的问题 - 如果索引分散在多个表空间(如主键在
TBS_IDX、函数索引在TBS_FUN),每个都得单独配
容易被忽略的复合场景
最常踩坑的是「跨用户对象 + 多表空间」组合:
- 表属于
USER_A,但你在USER_B下建索引 → 检查USER_B在索引表空间的配额,不是USER_A的 - 表和索引分别在
TBS_DAT和TBS_IDX→ 用户必须同时在两个表空间都有配额,缺一不可 - 用 DataGrip、DBeaver 等工具建索引时,界面可能默认填了表空间名,但你没意识到它正在往哪个表空间写
- 某些 ETL 工具(如 Dataphin、OGG)会在内部自动建索引,报错时需翻日志确认它试图使用的表空间名
配额不是“设一次就永远有效”的静态配置——当索引变大、分区增加、或表空间被管理员清理后,max_bytes 可能被重置为 0,这类隐性失效最难排查。


















