ORA-01950本质是用户在目标表空间无配额,即使有CREATE TABLE权限也会失败;需通过GRANT QUOTA显式分配,或谨慎使用UNLIMITED TABLESPACE权限。
ORA-01950:用户没有表空间中的权限,本质是没配额
遇到 ora-01950: no privileges on tablespace 'users',不是权限没给全,而是该用户在目标表空间里压根没分配配额。即使有 create table 权限,没配额照样建表失败——oracle 会直接拦在物理存储环节。
常见错误现象:
• 用户能登录、能查数据,但一执行 CREATE TABLE t AS SELECT ... 就报 ORA-01950
• DBA_TS_QUOTAS 视图里查不到该用户的记录,或 MAX_BYTES 是 -1(表示未设)
• 用 ALTER USER ... DEFAULT TABLESPACE 改了默认表空间,但忘了同步配额
- 配额必须显式授予,不会随角色(如
CONNECT或RESOURCE)自动继承 - 配额作用域是「表空间级」,不是数据库级;一个用户可在
USERS配 10M,在DATA01配 100M,互不影响 -
UNLIMITED TABLESPACE系统权限可绕过所有配额检查,但属于高危授权,生产环境应避免
GRANT QUOTA ON TABLESPACE:给固定大小配额的写法
给用户分配具体字节数配额,用 GRANT QUOTA <size> ON TABLESPACE <ts_name></ts_name></size>。大小支持单位(K、M、G),不区分大小写,但必须紧贴数字、无空格。
典型使用场景:
• 新建应用用户,限定其只能用 500M 存储日志表
• 测试账号隔离资源,防止单个用户占满共享表空间
-
GRANT QUOTA 500M ON TABLESPACE USERS TO app_user;—— 正确 -
GRANT QUOTA 0 ON TABLESPACE USERS TO app_user;—— 允许建空表(段头),但无法插入数据(无空间) -
GRANT QUOTA 1G ON TABLESPACE USERS TO app_user;—— 注意:1G = 1024M,不是 1000M - 若用户已存在配额,该语句会覆盖原值(不是累加)
UNLIMITED QUOTA:谨慎开启的两种方式
真正“不限制”有两种等效写法,但底层行为一致:跳过所有配额校验。别信“UNLIMITED 比 UNLIMITED TABLESPACE 更安全”这种说法——它们效果完全一样,只是语法路径不同。
容易踩的坑:
• 用 GRANT UNLIMITED TABLESPACE TO user; 后,DBA_TS_QUOTAS 里仍查不到该用户的记录(因为配额机制被绕过了)
• 撤销时必须用 REVOKE UNLIMITED TABLESPACE FROM user;,不能用 ALTER USER ... QUOTA 0 ON ...
-
GRANT UNLIMITED TABLESPACE TO app_admin;—— 授予系统权限,影响全局 -
ALTER USER app_admin QUOTA UNLIMITED ON USERS;—— 表空间级无限配额,只对 USERS 生效 - 两者都让 Oracle 完全忽略该用户在此表空间的
MAX_BYTES检查 - 监控时注意:
V$TABLESPACE_USAGE_METRICS仍会计量,但不会触发配额告警
查配额和清理残留:DBA_TS_QUOTAS 是唯一真相源
判断用户实际有没有配额、是多少,唯一可信来源是 DBA_TS_QUOTAS。别依赖 DBA_USERS.DEFAULT_TABLESPACE 或角色权限来推测。
性能与兼容性提醒:
• 查询 DBA_TS_QUOTAS 不走索引,大库中可能稍慢,但这是元数据视图,影响极小
• 所有 Oracle 版本(11gR2 起)字段一致,MAX_BYTES 为 -1 表示无限,0 表示禁止分配新段
SELECT username, tablespace_name, max_bytes FROM DBA_TS_QUOTAS WHERE username = 'APP_USER';- 若结果为空,说明该用户在此表空间**没有任何配额**(哪怕有
UNLIMITED TABLESPACE权限,这里也查不到) - 清理旧配额用
ALTER USER app_user QUOTA 0 ON USERS;,不是DROP或REVOKE - 注意:
QUOTA 0≠ 删除配额,它仍是显式设置,会出现在DBA_TS_QUOTAS中
DEFAULT TABLESPACE 带过去了,配额没带。最稳妥的做法是:建用户后,立刻跟一条 GRANT QUOTA 或明确写 QUOTA 0,别留空白状态。










