Oracle中限制用户表空间配额必须用QUOTA子句,授予权限或设默认表空间无效;ORA-01950因无配额而非无建表权;QUOTA是硬上限,0表示禁止写入,UNLIMITED TABLESPACE会覆盖所有QUOTA设置。
直接给结论:oracle 里限制用户在特定表空间能用多少空间,**必须用 alter user ... quota 或建用户时带 quota 子句**;靠授予权限(比如 create table)或默认表空间设置,完全不管用。
ORA-01950 错误到底是什么原因
用户执行 CREATE TABLE 报 ORA-01950: no privileges on tablespace 'USERS',不是没权限建表,而是没被允许往那个表空间写数据。哪怕 GRANT CREATE TABLE TO scott 已执行,只要 scott 在 USERS 表空间没配额,就必然失败。
常见误解:
- 以为设了
DEFAULT TABLESPACE USERS就自动能用 —— 不,DEFAULT TABLESPACE只指定“不写TABLESPACE子句时往哪放”,但不等于“给你开闸” - 以为
GRANT CONNECT, RESOURCE TO user就够了 —— 这两个角色不含任何QUOTA,连 1 字节都不给 - 以为
UNLIMITED TABLESPACE是细粒度控制 —— 它是系统级开关,一旦授予,所有QUOTA设置立即失效
QUOTA 的三种合法赋值方式及真实效果
QUOTA 值不是“建议用量”,而是硬性上限,超了就拒绝 DML/DDL 写入(INSERT、CREATE INDEX 等都会报 ORA-01536)。
-
ALTER USER scott QUOTA 50M ON users;:严格限制为 50MB,超过即停 -
ALTER USER scott QUOTA UNLIMITED ON app_data;:仅对app_data表空间放开,其他表空间仍需单独配额 -
ALTER USER scott QUOTA 0 ON system;:显式禁止写入SYSTEM表空间,哪怕有DBA角色也不行(但注意:这不阻止读,也不影响已存在对象)
特别注意:QUOTA 0 ≠ 撤销权限,它只是堵住写入口;要彻底收回豁免权,得 REVOKE UNLIMITED TABLESPACE FROM scott。
建用户时一次性配齐配额最安全
比起事后 ALTER USER,在 CREATE USER 语句里直接声明配额,能避免“用户已创建但无法建表”的尴尬窗口期。
例如:
CREATE USER app_user IDENTIFIED BY pwd DEFAULT TABLESPACE app_data TEMPORARY TABLESPACE temp QUOTA 200M ON app_data QUOTA 50M ON idx_tbs QUOTA 0 ON system;
这样定义后:
- 用户默认往
app_data写,最多 200MB - 可显式指定
TABLESPACE idx_tbs建索引,但不能超 50MB - 哪怕有
CREATE TABLE权限,也无法在SYSTEM里建任何段
注意:QUOTA 对临时表空间(TEMP)、撤销表空间(UNDOTBS1)无效,语法上不报错,但实际不生效。
查配额和真实占用必须联合看
DBA_TS_QUOTAS 只告诉你“理论上允许多大”,不反映“已经用了多少”。生产环境出问题,往往是因为配额设了但没人监控实际增长。
必须同时查两处:
-
SELECT tablespace_name, max_bytes/1024/1024 MAX_MB FROM DBA_TS_QUOTAS WHERE username = 'SCOTT' AND max_bytes != -1;(max_bytes = -1表示UNLIMITED) SELECT tablespace_name, SUM(bytes)/1024/1024 MB_USED FROM DBA_SEGMENTS WHERE owner = 'SCOTT' GROUP BY tablespace_name;
容易忽略的点:
- 通过
CREATE TABLE AS SELECT、分区交换(EXCHANGE PARTITION)间接生成的对象,也计入配额消耗,但不会触发 DDL 审计日志 - 表空间被
DROP后,DBA_TS_QUOTAS中残留记录仍存在,直到重建同名表空间并设QUOTA 0才清除(10gR2+ 可用DROP TABLESPACE ... DROP QUOTA主动清理)


















