quota 是表空间配额而非权限,控制用户在指定表空间可使用的最大存储量;即使拥有 create table 权限,若无对应表空间 quota 仍会报 ora-01950 错误。
quota 是什么,为什么不能直接用 create tablespace 权限控制用户建表
quota 不是权限,而是配额。用户即使有 create table 权限,若在目标表空间上没分配 quota,create table 会报错:ora-01950: no privileges on tablespace 'users'。这不是权限缺失,是空间额度未授权。
常见误解是给用户 UNLIMITED TABLESPACE 角色就万事大吉——这等于彻底放开所有表空间写入权,生产环境极不安全。
- QUOTA 控制的是「能往哪个表空间写多少数据」,和「能不能建表」是两个维度
-
UNLIMITED TABLESPACE是系统权限,优先级高于 QUOTA,一旦授予,所有 QUOTA 设置自动失效 - QUOTA 只对非 SYSTEM/SYSAUX 等 Oracle 管理表空间有效(如自建的
APP_DATA、REPORT_TBS)
如何给用户分配表空间配额(含 UNLIMITED 和 0 值场景)
用 ALTER USER ... QUOTA 语句设置,必须指定表空间名。语法简单,但值的含义容易混淆:
-
ALTER USER scott QUOTA 10M ON users;:允许在users表空间最多使用 10MB -
ALTER USER scott QUOTA UNLIMITED ON app_data;:不限制,但仅限app_data这一个表空间 -
ALTER USER scott QUOTA 0 ON system;:显式禁止在system表空间创建任何段(即使有权限)
注意:QUOTA 0 不等于撤销权限,它只是堵住写入口;而 REVOKE UNLIMITED TABLESPACE FROM scott 才是收回系统级豁免权。
查 QUOTA 设置和实际占用情况,别只看 DBA_TS_QUOTAS
DBA_TS_QUOTAS 只显示显式分配的 QUOTA(包括 UNLIMITED 和具体数值),但不会告诉你用户已经用了多少。真正要评估风险,得联合查:
-
SELECT * FROM DBA_TS_QUOTAS WHERE username = 'SCOTT';—— 看配额定义 -
SELECT tablespace_name, bytes/1024/1024 MB FROM DBA_SEGMENTS WHERE owner = 'SCOTT' GROUP BY tablespace_name, bytes;—— 看真实占用 -
SELECT tablespace_name, max_bytes/1024/1024 MAX_MB FROM DBA_TS_QUOTAS WHERE username = 'SCOTT' AND max_bytes != -1;——max_bytes = -1表示UNLIMITED,别当成 1 字节
特别注意:如果用户通过 CREATE TABLE AS SELECT 或分区交换等操作间接占用空间,这些也会计入 QUOTA 消耗,但不会触发 DDL 审计日志——得靠定期跑上面的 DBA_SEGMENTS 查询来发现异常增长。
QUOTA 无法限制的操作:临时段、回滚段、LOB 存储子句
QUOTA 只约束「永久段」(如表、索引、物化视图)。以下情况完全绕过 QUOTA 检查:
- 排序临时段:
ORDER BY、GROUP BY使用TEMP表空间,走的是TEMPORARY TABLESPACE配置,和 QUOTA 无关 - 事务回滚:DML 回滚信息写入 UNDO 表空间,由
UNDO_TABLESPACE决定,不受用户 QUOTA 影响 - LOB 字段显式指定表空间:
LOB (content) STORE AS (TABLESPACE archive_tbs)—— 此时占用的是archive_tbs的空间,但 QUOTA 必须提前在该表空间上为用户设好,否则建表失败
也就是说,一个用户 QUOTA 被设为 0,仍可能因大量排序或长事务把 TEMP/UNDO 表空间撑爆——QUOTA 管不了这些,得靠资源计划(Resource Manager)或监控告警补位。











