查表空间前必须先切换到目标pdb容器,因默认连接cdb$root时dba_data_files仅显示cdb级文件;若在cdb中建表空间,pdb用户将因无权限而报ora-01950;需确认pdb处于read write状态、路径隔离、禁用alter database default tablespace等cdb级命令。

查表空间前必须先切换到目标PDB容器
直接连上 Oracle 12c 默认进的是 CDB$ROOT,此时执行 SELECT * FROM dba_data_files 查出来的是 CDB 级别的数据文件,和你的业务 PDB 完全无关。不切容器就操作,等于在错的地方干活。
正确流程是:
- 用
SHOW CON_NAME确认当前容器名 - 用
SELECT name, open_mode FROM v$pdbs查目标 PDB 是否为READ WRITE(只读或未打开的 PDB 无法建表空间) - 执行
ALTER SESSION SET CONTAINER = orclpdb1切入目标 PDB - 再查
dba_data_files或建表空间
PDB 表空间文件路径必须严格隔离
Oracle 不允许 PDB 的数据文件和 CDB 混放。哪怕只是路径上少了个子目录,启动或 DML 时就可能报 ORA-65043: invalid file name 或挂载失败。
典型路径结构:
- CDB 数据目录:
/opt/oracle/oradata/ORCL/ - 对应 PDB
ORCLPDB1的合法路径:/opt/oracle/oradata/ORCL/ORCLPDB1/(末尾带 PDB 名) - 必须提前
mkdir -p /opt/oracle/oradata/ORCL/ORCLPDB1/并确保 Oracle 用户有读写权限
错误示例:CREATE TABLESPACE tbs1 DATAFILE '/opt/oracle/oradata/ORCL/tbs1.dbf' SIZE 100M —— 这会建在 CDB 目录下,PDB 用户无权使用,后续建表直接报 ORA-01950。
PDB 中不能用 CDB 级表空间管理命令
像 ALTER DATABASE DEFAULT TABLESPACE 这类命令是 CDB 级的,在 PDB 里执行只会报 ORA-65040: operation not allowed from within a pluggable database。
在 PDB 内设置默认表空间,只能通过用户级操作:
- 创建用户时指定:
CREATE USER hr IDENTIFIED BY pwd DEFAULT TABLESPACE users; - 或后续修改:
ALTER USER hr DEFAULT TABLESPACE users; - 注意:该表空间必须已存在于当前 PDB,且用户有配额(
ALTER USER hr QUOTA UNLIMITED ON users)
COMMON 用户建的表空间对所有 PDB 可见但不可直接用
在 CDB$ROOT 用 c## 用户建的表空间(如 CREATE TABLESPACE cdb_tbs ...),会出现在所有 PDB 的 dba_tablespaces 里,但本地用户默认没权限访问 —— 这不是 bug,是设计隔离。
若真要跨 PDB 共享表空间(极少见),必须显式授权:
- 在 CDB$ROOT 中:
GRANT UNLIMITED TABLESPACE TO c##user CONTAINER=ALL; - 但更推荐的做法是:每个 PDB 自己建自己的表空间,避免权限、路径、维护耦合
真正容易被忽略的是路径隔离和容器上下文切换——这两点一旦出错,现象都是“表空间明明存在却用不了”,排查时容易反复绕回权限或语法问题,而实际卡在了最开始的 ALTER SESSION SET CONTAINER 那一步。











