ACE Director Alum Daniel Morgan, founder of Morgan's Library, is scheduling
complimentary technical Workshops on Database Security for the first 30
Oracle Database customers located anywhere in North America, EMEA, LATAM, or
APAC that send an email to
asra_us@oracle.com. Request a Workshop for
your organization today.
SELECT v.name, v.open_mode, v.restricted, d.status
FROM v$pdbs v, dba_pdbs d
WHERE v.guid = d.guid
ORDER BY v.create_scn;
NAME OPEN_MODE RESTRICTED STATUS
------------------------------ ---------- ---------- -------------
PDB$SEED READ ONLY NO NORMAL
PDBDEV MOUNTED NO NORMAL
ALTER PLUGGABLE DATABASE pdbdev OPEN;
SELECT v.name, v.open_mode, v.restricted, d.status
FROM v$pdbs v, dba_pdbs d
WHERE v.guid = d.guid
ORDER BY v.create_scn;
NAME OPEN_MODE RESTRICTED STATUS
------------------------------ ---------- ---------- -------------
PDB$SEED READ ONLY NO NORMAL
PDBDEV READ WRITE NO NORMAL
SELECT * FROM dba_pdbs;
-- 12.1.0.1 version
--
SELECT * FROM cdb$view(dba_pdbs);
-- 12.1.0.2 version
SELECT * FROM containers(dba_pdbs);
-- 12.1.0.1 version
--
SELECT * FROM cdb$view(cdb_pdbs);
-- 12.1.0.2 version
SELECT * FROM containers(cdb_pdbs);
SELECT table_name, tablespace_name, con_id
FROM dba_tables
WHERE rownum < 6;
SELECT table_name, tablespace_name, con_id
*
ERROR at line 1:
ORA-00904: "CON_ID": invalid identifier
SELECT table_name, tablespace_name, con_id
FROM cdb$view(dba_tables)
WHERE rownum < 6;
Create a Pluggable Database From PDB$SEED
Add a pluggable database container
CREATE PLUGGABLE DATABASE orabase
ADMIN USER uwclass IDENTIFIED BY uwclass
FILE_NAME_CONVERT = ('\pdbseed\', '\orabase\');
CREATE PLUGGABLE DATABASE orabase
*
ERROR at line 1:
ORA-44303: service name exists
-- in *NIX: use backslashes for Windows
CREATE PLUGGABLE DATABASE oradev
ADMIN USER uwclass IDENTIFIED BY uwclass
FILE_NAME_CONVERT = ('/pdbseed/', '/oradev/');
SELECT v.name, v.open_mode, NVL(v.restricted, 'n/a') RESTRICTED, d.status
FROM v$pdbs v, dba_pdbs d
WHERE v.guid = d.guid
ORDER BY v1;
NAME OPEN_MODE RESTRICTED STATUS
------------------------------ ---------- ---------- -------------
ORADEV MOUNTED NO NORMAL
PDB$SEED READ ONLY NO NORMAL
PDBDEV READ WRITE n/a NORMAL
ALTER SESSION SET CONTAINER=oradev;
SELECT name, created, open_mode
FROM v$database;
NAME CREATED OPEN_MODE
----------- -------------------- ---------
ORABASE 28-FEB-2013 15:40:05 MOUNTED
SELECT instance_name, database_status, active_state
FROM v$instance;
INSTANCE_NAME DATABASE_STATUS ACTIVE_STATUS
-------------- ---------------- --------------
orabase ACTIVE NORMAL
SELECT COUNT(*)
FROM dba_tables;
*
ORA-01219: database or pluggable database no open: queries allowed on fixed tables or views only
sho con_name
CON_NAME
---------
ORADEV
ALTER PLUGGABLE DATABASE oradev OPEN;
SELECT COUNT(*)
FROM dba_tables;
Explore Data Files
-- explore physical arch
desc dba_data_files
desc cdb_data_files
SELECT file_name, tablespace_name, online_status
FROM dba_data_files;
SELECT file_name, tablespace_name, online_status, con_id
FROM cdb_data_files;
Explore Users
-- continuing in the PDBDEV container
desc dba_users
desc cdb_users
SELECT username, account_status, lock_date, expiry_date
FROM dba_users
ORDER BY 1;
SELECT username, default_tablespace, temporary_tablespace
FROM dba_users
ORDER BY 1;
SELECT username, default_tablespace, temporary_tablespace, con_id
FROM cdb_users
ORDER BY 1;
SELECT username, default_tablespace, temporary_tablespace, con_id
FROM cdb_users
WHERE username like 'UW%'
ORDER BY 1;
ALTER PLUGGABLE DATABASE orabase OPEN;
SELECT v.name, v.open_mode, NVL(v.restricted, 'n/a') "RESTRICTED", d.status
FROM v$pdbs v, dba_pdbs d
WHERE v.guid = d.guid
ORDER BY v.create_scn;
NAME OPEN_MODE RESTRICTED STATUS
------------------------------ ---------- ---------- -------
PDB$SEED READ ONLY NO NORMAL
PDBDEV MOUNTED n/a NORMAL
ORADEV READ WRITE NO NORMAL
SELECT username, default_tablespace, temporary_tablespace, con_id
FROM cdb_users
WHERE username like 'UW%'
ORDER BY 1;
Warning: You are no longer connected to ORACLE.
SQL> conn sys@orabeta as sysdba
Enter password: *********
Connected.
SQL> GRANT create session TO uwclass;
GRANT create session TO uwclass
*
ERROR at line 1:
ORA-01917: user or role 'UWCLASS' does not exist
SQL> conn sys@orabase as sysdba
Enter password: *********
Connected.
SQL> GRANT create session TO uwclass;
Grant succeeded.
SQL> SELECT COUNT(*) FROM cdb_sys_privs;
COUNT(*)
----------
0
SQL> SELECT COUNT(*) FROM dba_sys_privs;
COUNT(*)
----------
987
SQL> SELECT privilege, admin_option, common
2 FROM dba_sys_privs
3 WHERE grantee = 'UWCLASS';
PRIVILEGE ADM COM
---------------------------------------- --- ---
CREATE SESSION NO NO
col grantee format a30
col granted_role format a30
SELECT *
FROM dba_role_privs
WHERE grantee = 'UWCLASS';
GRANTEE GRANTED_ROLE ADM DEF COM
------------------------------ ------------------------------ --- --- ---
UWCLASS PDB_DBA YES YES NO
Create Pluggable Database From Clone
Create a test database in the same container as an existing test database
CREATE PLUGGABLE DATABASE <new pdb> FROM <existing_pdb>
FILE_NAME_CONVERT=('<path>', '<path');
ALTER PLUGGABLE DATABASE orabase CLOSE;
ALTER PLUGGABLE DATABASE orabase OPEN READ ONLY;
CREATE OR REPLACE VIEW pdb_status AS
SELECT v.name, v.open_mode, NVL(v.restricted, 'n/a') "RESTRICTED", d.status
FROM v$pdbs v, dba_pdbs d
WHERE v.guid = d.guid
ORDER BY v.create_scn;
SELECT * FROM pdb_status;
NAME OPEN_MODE RESTRICTED STATUS
------------------------------ ---------- ---------- -------------
PDB$SEED READ ONLY NO NORMAL
PDBDEV MOUNTED n/a NORMAL
ORABASE READ ONLY NO NORMAL
CREATE PLUGGABLE DATABASE orabase_t FROM orabase
FILE_NAME_CONVERT = ('\uwpdb\', '\uwpdbd\');
SELECT * FROM pdb_status;
NAME OPEN_MODE RESTRICTED STATUS
------------------------------ ---------- ---------- -------------
PDB$SEED READ ONLY NO NORMAL
PDBDEV MOUNTED n/a NORMAL
ORABASE READ ONLY NO NORMAL
ORABASE_T MOUNTED n/a NEW
PDB Creation with UNPLUG/PLUG
Unplug Clause
Unplug Clause
Create from unplugged
ALTER PLUGGABLE DATABASE <pdb_name> UNPLUG INTO '<file_name>';
conn sys@pdbtest as sysdba
-- from inside a pdb
ALTER PLUGGABLE DATABASE pdbtest CLOSE;
ALTER PLUGGABLE DATABASE pdbtest UNPLUG INTO 'pdbtest.xml';
ALTER PLUGGABLE DATABASE pdbtest UNPLUG INTO 'pdbtest.xml'
*
ERROR at line 1:
ORA-65040: operation not allowed from within a pluggable database
-- now correctly from inside cdb$root
conn / as sysdba
ALTER PLUGGABLE DATABASE pdbtest CLOSE;
ALTER PLUGGABLE DATABASE pdbtest UNPLUG INTO 'pdbtest.xml';
-- ftp files to new server
-- the xml file is located at $ORACLE_HOME/database
SQL> CREATE PLUGGABLE DATABASE pdbprod USING 'pdbtest.xml'
2 SOURCE_FILE_NAME_CONVERT = ('\pdbtest\', '\pdbprod\')
3 NOCOPY
4 STORAGE (MAXSIZE 1G MAX_SHARED_TEMP_SIZE 20M)
5 TEMPFILE REUSE;
CREATE PLUGGABLE DATABASE pdbprod USING 'pdbtest.xml'
*
ERROR at line 1:
ORA-65122: Pluggable database GUID conflicts with the GUID of an existing container.
CREATE PLUGGABLE DATABASE pdbprod AS CLONE USING 'pdbtest.xml'
FILE_NAME_CONVERT = ('\pdbtest\', '\pdbprod\')
STORAGE (MAXSIZE 1G MAX_SHARED_TEMP_SIZE 20M);
SELECT con_id, name, open_mode
FROM v$containers
ORDER BY con_id;
SELECT tablespace_name, file_name
FROM cdb_data_files
WHERE con_id = 5
UNION
SELECT tablespace_name, file_name
FROM cdb_temp_files
WHERE con_id = 5;
One way to fix a valid PDB that won't open
ALTER PLUGGABLE DATABASE pdbtest UNPLUG INTO 'c:\temp\pdbtest.xml';
DROP PLUGGABLE DATABASE pdbtest;
CREATE pluggable DATABASE pdbtest USING 'c:\temp\pdbtest.xml' NOCOPY;
ALTER PLUGGABLE DATABASE
Settings Clauses
Default Edition
ALTER PLUGGABLE DATABASE <pdb_name>
conn / as sysdba
ALTER SESSION SET CONTAINER = pdbdev;
CREATE EDITION demo_ed;
ALTER PLUGGABLE DATABASE pdbdev DEFAULT EDITION = demo_ed;
Default Tablespace
ALTER PLUGGABLE DATABASE <pdb_name> DEFAULT TABLESPACE <tablespace_name>;
conn / as sysdba
ALTER SESSION SET CONTAINER = pdbdev;
SELECT tablespace_name
FROM dba_tablespaces;
ALTER PLUGGABLE DATABASE orabase DEFAULT TABLESPACE oradata;
Default Tablespace Type
ALTER PLUGGABLE DATABASE <pdb_name> SET DEFAULT <BIGFILE | SMALLFILE> TABLESPACE;
conn / as sysdba
ALTER SESSION SET CONTAINER = pdbdev;
ALTER PLUGGABLE DATABASE orabase SET DEFAULT BIGFILE TABLESPACE;
Default Temporary Tablespace
ALTER PLUGGABLE DATABASE <pdb_name> DEFAULT TEMPORARY TABLESPACE <tablespace_or_group>;;
conn / as sysdba
ALTER SESSION SET CONTAINER = pdbdev;
ALTER PLUGGABLE DATABASE orabase DEFAULT TEMPORARY TABLESPACE temp_grp;
Rename
ALTER PLUGGABLE DATABASE <pdb_name> RENAME GLOBAL_NAME TO <database>[.domain];
conn / as sysdba
ALTER SESSION SET CONTAINER = pdbdev;
SELECT *
FROM global_name;
-- shutdown
-- reopen in restricted mode
ALTER PLUGGABLE DATABASE pdbdev RENAME GLOBAL_NAME TO pdb$dev;
Set Timezone only in a PDB: Must be done while connected to a PDB ... cannot be done in CDB$ROOT
ALTER PLUGGABLE DATABASE [<pdb_name>] SET TIME_ZONE = '<timezone_region>';
conn sys@pdbdev as sysdba
ALTER SESSION SET CONTAINER = pdbdev;
SELECT value$
FROM props$
WHERE name = 'DBTIMEZONE';
ALTER PLUGGABLE DATABASE pdbdev SET TIME_ZONE = 'Japan';
ORA-30079: cannot alter database timezone when database has TIMESTAMP WITH LOCAL TIME ZONE columns
ALTER SESSION SET CONTAINER = pdbdev;
SELECT value$
FROM props$
WHERE name = 'DBTIMEZONE';
ALTER PLUGGABLE DATABASE pdbdev SET TIME_ZONE = 'Japan';
SELECT value$
FROM props$
WHERE name = 'DBTIMEZONE';
ALTER PLUGGABLE DATABASE pdbdev SET TIME_ZONE = '00:00';
SELECT value$
FROM props$
WHERE name = 'DBTIMEZONE';
Set Timezone only in a PDB: Must be done while connected to a PDB ... cannot be done in CDB$ROOT
ALTER PLUGGABLE DATABASE <pdb_name> SET TIME_ZONE = '< | -> HH:MI';
See Demo Above
Database Files Rename
ALTER PLUGGABLE DATABASE <pdb_name> RENAME FILE '<file_name>' TO '<file_name>';
conn sys@pdbprod as sysdba
ALTER PLUGGABLE DATABASE CLOSE;
ALTER PLUGGABLE DATABASE pdbprod
RENAME FILE
'C:\APP\ORACLE\ORADATA\ORABASE\PDBPROD\PDBSEED_TEMP012014-12-04_10-11-17-PM.DBF' TO 'C:\APP\ORACLE\ORADATA\ORABASE\PDBPROD\PDBPROD_TEMP.DBF';
-- the original file remains in the file system and must be manually removed.
ALTER PLUGGABLE DATABASE pdbdev ADD SUPPLEMENTAL LOG DATA;
Storage
ALTER PLUGGABLE DATABASE <pdb_name> STORAGE <UNLIMITED | <size_clause>>;
ALTER PLUGGABLE DATABASE pdbdev STORAGE UNLIMITED;
Storage
ALTER PLUGGABLE DATABASE <pdb_name> STORAGE (MAX_SHARED_TEMP_SIZE <UNLIMITED | <size_clause>);
ALTER PLUGGABLE DATABASE pdbdev STORAGE (MAX_SHARED_TEMP_SIZE UNLIMITED);
Datafile Clause
Datafile Online / Offline
ALTER PLUGGABLE DATABASE <pdb_name> DATAFILE ALL <ONLINE | OFFLINE>;
conn / as sysdba
ALTER SESSION SET CONTAINER = pdbdev;
ALTER PLUGGABLE DATABASE pdbdev CLOSE;
SELECT open_mode
FROM v$pdbs;
SELECT file#, status, enabled
FROM v$datafile;
ALTER PLUGGABLE DATABASE pdbdev DATAFILE ALL OFFLINE;
*
ERROR at line 1:
ORA-01145: offline immediate disallowed unless media recovery enabled
ALTER PLUGGABLE DATABASE pdbdev DATAFILE ALL ONLINE;
SELECT file#, status, enabled
FROM v$datafile;
ALTER PLUGGABLE DATABASE pdbdev OPEN;
Recovery Clauses
Backup and Recover a PDB
ALTER PLUGGABLE DATABASE <pdb_name> RECOVER [AUTOMATIC] [FROM '<location>' DATABASE;
-- there are also RECOVERY TABLESPACE, DATAFILE, LOGFILE, and CONTINUE variants.
ALTER PLUGGABLE DATABASE pdbdev RECOVER AUTOMATIC DATABASE;
Backup and Recover a PDB
ALTER PLUGGABLE DATABASE <pdb_name> <BEGIN | END> BACKUP;
conn / as sysdba
ALTER PLUGGABLE DATABASE pdbdev BEGIN BACKUP;
*
ERROR at line 1:
ORA-65046: operation not allowed from outside a pluggable database
ALTER SESSION SET CONTAINER = PDBDEV;
ALTER PLUGGABLE DATABASE pdbdev BEGIN BACKUP;
*
ERROR at line 1:
ORA-01123: cannot start online backup; media recovery not enabled
conn / as sysdba
SHUTDOWN IMMEDIATE;
STARTUP MOUNT;
ALTER DATABASE ARCHIVELOG;
ALTER DATABASE OPEN;
ALTER PLUGGABLE DATABASE pdbdev OPEN;
ALTER SESSION SET CONTAINER = PDBDEV;
ALTER PLUGGABLE DATABASE pdbdev BEGIN BACKUP;
ALTER PLUGGABLE DATABASE pdbdev END BACKUP;
Change State Clauses
Open Read Write
ALTER PLUGGABLE DATABASE <pdb_name> OPEN READ [WRITE] [UPGRADE] [RESTRICTED] [FORCE]
[INSTANCES = <('<instance_name>' | <ALL [EXCEPT ('<instance_name'>)] >);
ALTER PLUGGABLE DATABASE pdbdev OPEN
READ WRITE FORCE;
Open Read Only
ALTER PLUGGABLE DATABASE <pdb_name> OPEN READ ONLY <instances_clause>;
ALTER PLUGGABLE DATABASE pdbdev OPEN READ ONLY;
Open Resetlogs
ALTER PLUGGABLE DATABASE <pdb_name> OPEN RESETLOGS <instances_clause>;
ALTER PLUGGABLE DATABASE pdbdev OPEN RESETLOGS;
Open/Close a single PDB
ALTER PLUGGABLE DATABASE <pdb_name> CLOSE [IMMEDIATE];
ALTER PLUGGABLE DATABASE orabase CLOSE;
Open/Close all PDBs
ALTER PLUGGABLE DATABASE ALL CLOSE [IMMEDIATE];
ALTER PLUGGABLE DATABASE ALL CLOSE;
Open PDB in READ ONLY mode
ALTER PLUGGABLE DATABASE <pdb_name> <CLOSE | OPEN> READ ONLY;
conn / as sysdba
-- must be closed
ALTER PLUGGABLE DATABASE orabase OPEN READ ONLY;
Open PDB in READ ONLY RESTRICTED mode
ALTER PLUGGABLE DATABASE <pdb_name> OPEN READ ONLY RESTRICTED;
conn / as sysdba
ALTER PLUGGABLE DATABASE orabase CLOSE;
ALTER PLUGGABLE DATABASE orabase OPEN READ ONLY RESTRICTED;
DROP PLUGGABLE DATABASE
Drop a pluggable database from its container
DROP PLUGGABLE DATABASE <pdb_name> [INCLUDING DATAFILES];
ALTER PLUGGABLE DATABASE orabase CLOSE;
DROP PLUGGABLE DATABASE orabase INCLUDING DATAFILES;
Common Objects
This demo shows undocumented behaviour that, for all I know, might have a negative impact on your relationship with Oracle Support so use this for personal education purposes only and do not replicate this in any supported environment.
You will see from the demo, at right, that what I have done has corrupted the data dictionary. The object appears to be on PDB 3 ... but it is not.
A good lesson for those tampering with what is undocumented and unsupported. Interestingly enough, in this case, a database reboot cleared the issue so it, in some manner, related to internal caching.
/* Enable container_data sharing=object */
alter session set "_ORACLE_SCRIPT"=TRUE;