Download as pdf or txt
Download as pdf or txt
You are on page 1of 32

Oracle Multitenant 12c

Oracle Multitenant

Oracle Multitenant is a new option for Oracle Database 12c Enterprise Edition that helps customers reduce IT costs
by simplifying consolidation, provisioning, upgrades, and more. It is supported by a new architecture that allows a
container database to hold many pluggable databases. And it fully complements other options, including Oracle Real
Application Clusters and Oracle Active Data Guard. An existing database can be simply adopted, with no change, as a
pluggable database; and no changes are needed in the other tiers of the application.

Oracle Database 12c supports a new architecture that lets you have many “sub databases” inside a single “super
database”. From now on, we shall use the official terminology. The “super database” is the multitenant container
database — abbreviated as CDB; and the “sub database” is the pluggable database — abbreviated as PDB. In other
words, the new architecture lets you have many PDBs inside a single CDB. (In 12.1, the maximum number is 252.) We
shall refer to the new architecture as the multitenant architecture.

We clearly now need a term for the old kind of database, the only kind of database that was supported through
Oracle Database 11g. We shall call this a non-CDB. Oracle Database 12c Release 1 supports both the new multitenant
architecture and the old non-CDB architecture. In other words, you can certainly upgrade a pre-12.1 database, which
necessarily is a non-CDB, to a 12.1 non-CDB and continue to operate it as such. But, if you choose, you can adopt the
12.1 non-CDB into a CDB as a PDB

Every CDB has the following containers:

 One root container, named CDB$ROOT. The root contains the master set of data dictionary views, which have
metadata regarding the root as well as every child pluggable database within the CDB.

 One static seed container, named PDB$SEED. This container exists solely as a template for providing data files
and metadata used to create new pluggable databases within the CDB.

 Zero, or one or more, pluggable databases (with a maximum of 252). Each pluggable database is self-
contained and functions like an isolated non-CDB database. Additionally, each pluggable database contains its
own data files and application objects (users, tables, indexes and so on). When connected to a pluggable
database, there is no visibility to the root container or any other pluggable databases present within the CDB.

Each of these components is called a container. Therefore, the root is a container, the seed is a container, and each
PDB is a container. Each container has a unique container ID and name within a CDB

Ahmed Fathi - Senior Oracle Consultant P ag e |1


Email: ahmedf.dba@gmail.com Blog: http://ahfathi.blogspot.com LinkedIn: http://linkedin.com/in/ahmedfathieg
Oracle Multitenant 12c

Benefits of the Multitenant Architecture

 Cost reduction
By consolidating hardware and sharing database memory and files, you reduce costs for hardware, storage,
availability, and labor.
 Easier and more rapid movement of data and code
By design, you can plug a PDB into a CDB, unplug the PDB from the CDB, and then plug this PDB into a
different CDB. Therefore, you can easily move an application's database back end from one server to another.
 Easier management and monitoring of the physical database
The CDB administrator can attend to one physical database (one set of files and one set of database
instances) rather than split attention among dozens or hundreds of non-CDBs. Backup strategies and disaster
recovery are simplified.
 Separation of data and code
Although consolidated into a single physical CDB, PDBs mimic the behavior of traditional non-CDBs. For
example, if a user error causes data loss, then a PDB administrator can use point-in-time recovery to retrieve
the lost data without affecting other PDBs.
 Ease of performance tuning
It is easier to collect performance metrics for a CDB than for multiple non-CDBs. It is easier to size one SGA
than several SGAs.
 Support for Oracle Database Resource Manager
In a CDB, one concern is contention for system resources among the PDBs running on the same server.
Another concern is limiting resource usage for more consistent, predictable performance. To address such
resource contention, usage, and monitoring issues, you can use Oracle Database Resource Manager.
 Fewer patches and upgrades
It is easier to apply a patch to one CDB than to multiple non-CDBs and to upgrade one CDB than to upgrade
several non-CDBs.

Database Environment Before Database Consolidation Single CDB

Ahmed Fathi - Senior Oracle Consultant P ag e |2


Email: ahmedf.dba@gmail.com Blog: http://ahfathi.blogspot.com LinkedIn: http://linkedin.com/in/ahmedfathieg
Oracle Multitenant 12c

Multitenant Architecture Diagram

The following list highlights some key points to understand about the new architecture:

• A connection to the CDB database is synonymous with connecting to the CDB$ROOT root container. The main
purpose of the root container is to house metadata for any associated PDBs.
• You can access the root container via the SYS user, just as you would a non-CDB database. In other words, when
logged in to the database server, you can use OS authentication to connect directly to the root container without
specifying a username and password (sqlplus / as sysdba). You do not need a listener running to connect to the root
container.
• The seed pluggable database container (PDB$SEED) only exists as a template for creating new pluggable databases.
You can connect to the seed, but it is read-only, meaning you can’t issue transactions against it.
• Besides the two default containers (root and seed), for this particular CDB, additional pluggable databases have
been manually created, named PDB_1 and PDB_n.
• Pluggable databases exist within individual namespaces. Pluggable databases must be unique within the CDB, but
objects within a pluggable database follow the namespace rules of a non-CDB database. For example, tablespace
names and user names have to be unique within the individual pluggable databases, but not within the CDB.
• Each pluggable database has its own SYSTEM and SYSAUX tablespaces and, optionally, a TEMP tablespace. If a
pluggable database does not have its own TEMP file, it can consume resources in the root container TEMP file.
• The SYSTEM tablespace of each pluggable database contains information regarding the pluggable database
metadata, such as its users and objects; these metadata are accessible via the DBA/ALL/USER-level views from the
pluggable database and are visible via CDB-level views from the root container.

Ahmed Fathi - Senior Oracle Consultant P ag e |3


Email: ahmedf.dba@gmail.com Blog: http://ahfathi.blogspot.com LinkedIn: http://linkedin.com/in/ahmedfathieg
Oracle Multitenant 12c

• You can set the time zones for the CDB and all associated PDBs or you can set the time zone individually per PDB.
• Figure shows a non-RAC configuration, so there is only one memory allocation and one set of background
processes. In other words, there is one instance. All pluggable databases within the CDB use the same instance and
background processes. If this were a RAC configuration, then any connections to the RAC instance would share that
instance and background processes.
• The CDB instance is started and stopped while connected as SYS to the root container. You can’t start/stop the CDB
instance while connected to a pluggable database.
• There is one initialization parameter file that is read by the instance when starting. A privileged user connected to
the root container can modify all initialization parameters. In contrast, a privileged user connected to a pluggable
database can only modify parameters applicable to the currently connected pluggable database. When connected to
a pluggable database and modifying initialization parameters, these modifications only apply to the currently
connected pluggable database and persist for the pluggable database across database restarts. The
ISPDB_MODIFIABLE column in V$PARAMETER shows which parameters are modifiable while connected as a
privileged user to a pluggable database.
• Application users can only access the pluggable databases via a network connection. Therefore, a listener must be
running and listening for service names corresponding to associated pluggable databases. If a listener is not running,
then there is no way for an application user to connect to a pluggable database.
• The individual pluggable databases aren’t stopped or started database instance. When you start/stop a pluggable
database, you are not allocating memory or starting/stopping background processes. Rather, pluggable databases are
either made available or not (open or closed).
• There is one set of control files for the CDB. The control files are managed while connected to the root container as
a privileged user.
• There is one UNDO tablespace for the CDB. All pluggable databases within the CDB use the same UNDO tablespace
(if RAC, then one active undo tablespace per instance).
• There is one thread of redo (per instance) that is managed while connected to the root container as a user with
appropriate privileges. Only privileged connections to root can enable archiving or switching online logs. Connections
to users with SYSDBA privileges to pluggable databases cannot alter online redo or archiving settings.
• There is one alert log and set of trace files for a CDB. Any applicable database messages for associated pluggable
databases are written to the common CDB alert log.
• Each container is assigned a unique container ID. The root container is assigned a container ID of 1; the seed
database is assigned a container ID of 2. Each subsequently created pluggable database is assigned a unique
sequential container ID.
• There is one FRA for the CDB. Separate directories are not created for pluggable databases within the FRA. RMAN
backup files, control files, and online redo logs are placed in a directory associated with the CDB and are not
segregated by pluggable database.
• The Flashback Database feature is turned on and off via a privileged connection to the root container. You cannot
enable flashback at the pluggable database level.
• AWR, ADDM, and ASH reports are issued across all PDBs in the CDB. Resource consumption is identified per
pluggable database.
• When resolving SQL performance issues, queries are associated with a particular pluggable database via the
CON_ID column in views such as V$SQL and V$SQLAREA.

Ahmed Fathi - Senior Oracle Consultant P ag e |4


Email: ahmedf.dba@gmail.com Blog: http://ahfathi.blogspot.com LinkedIn: http://linkedin.com/in/ahmedfathieg
Oracle Multitenant 12c

• While connected to the root container with SYSDBA or SYSBACKUP privileges, you have the option of backing up all
the data files within the CDB (root, seed, and all pluggable databases) via one backup command. You also have the
choice of performing B&R tasks at a pluggable database level of granularity.
• While connected directly to a pluggable database with SYSDBA or SYSBACKUP privileges, you can only back up and
recover data files associated with the currently connected pluggable database; you cannot view or operate on the
root container data files or other pluggable database data files.
• An incomplete recovery of the entire CDB must be performed with a connection to the root container with SYSDBA
or SYSBACKUP privileges. All data files within the CDB (root container and associated pluggable databases) are
unavailable during an incomplete recovery of the entire CDB.
• A direct connection to a pluggable database with SYSDBA or SYSBACKUP privileges can perform an incomplete
recovery only on the currently connected pluggable database without affecting any other pluggable databases within
the CDB.
• Because there is a shared UNDO tablespace, any point-in-time incomplete recoveries of a pluggable database will
also have to temporarily restore the root container’s UNDO tablespace to an auxiliary database location so that it can
participate in the point-in-time recovery of the pluggable database.

Summary of Pluggable Database Terms

Term Meaning
Container database (CDB), A database capable of housing one or more pluggable databases
multitenant database
Pluggable database, (PDB) A set of data files and metadata that can be seamlessly transferred from
one CDB to another
Root container A master set of data files and metadata containing information regarding all containers within
a CDB. The root container is named CDB$ROOT.
Container A collection of data files and metadata. Can be root, seed, or a pluggable database.
Seed pluggable database A template of data files and metadata used to create new pluggable databases. The seed
pluggable database is named PDB$SEED.
Plugging Associating the metadata and data files of a pluggable database with a CDB
Unplugging Disassociating the metadata and data files of a pluggable database from a CDB
Cloning Creating a pluggable database from a copy of another database (seed, PDB, or non-CDB)
CON_ID A unique identifier for each container within a CDB. The CDB-level views contain a CON_ID
column that identifies the container with which the information being viewed is associated
CDB data dictionary views Views that contain metadata regarding all pluggable databases within a CDB. These views
only display meaningful information when queried via a privileged connection from the root
container. The pluggable databases must be open for use.
non-CDB database An Oracle database created without the pluggable database feature enabled (the only type of
database that was available prior to 12c)

Data Dictionary Architecture in a CDB


At a physical level, an Oracle database consists of a bunch of files: data files as well as bootstrap files, such as control
files, spfile, and so on. The physical data files implement the logical entity tablespace, which in turn implements
tables. Tables hold only three kinds of data:
 Metadata that describes the Oracle system
 Metadata that describes the user schema
 Actual user data

Ahmed Fathi - Senior Oracle Consultant P ag e |5


Email: ahmedf.dba@gmail.com Blog: http://ahfathi.blogspot.com LinkedIn: http://linkedin.com/in/ahmedfathieg
Oracle Multitenant 12c

Prior to Oracle Database 12c, the metadata that describes the Oracle system and the metadata that describes the
user schema were stored collectively in a set of tables (Obj$, Tab$, Col$, and so on) that are referred to as the data
dictionary. The data dictionary tables were stored in dedicated tablespaces, namely SYSTEM and SYSAUX.

Initially, when you create the database, the data dictionary tables have only Oracle system-related metadata. Later
on, when a user creates data, the data dictionary tables contain user and system metadata. The user tablespace
contains only user data.

In Oracle Database 12c the data dictionary tables are horizontally partitioned: one subset containing the Oracle
system metadata is stored in the Root database and another subset containing user metadata is stored in the PDB.
Now, transporting an application database from one database to another means Oracle processes just copy the files
containing user data and user metadata. The user metadata is stored in the SYSTEM and SYSAUX tablespaces of the
PDB, and the system metadata is stored in the SYSTEM and SYSAUX tablespaces of the CDB.

The data dictionary in the PDB contains pointers to the data dictionary in the root. Internally, Oracle-supplied objects
such as data dictionary table definitions and PL/SQL packages are represented only in the root. This architecture
achieves two main goals within the CDB:

Ahmed Fathi - Senior Oracle Consultant P ag e |6


Email: ahmedf.dba@gmail.com Blog: http://ahfathi.blogspot.com LinkedIn: http://linkedin.com/in/ahmedfathieg
Oracle Multitenant 12c

 Reduction of duplication
For example, instead of storing the source code for the DBMS_ADVISOR PL/SQL package in every PDB, the
CDB stores it only in CDB$ROOT, which saves disk space.
 Ease of database upgrade
If the definition of a data dictionary table existed in every PDB, and if the definition were to change in a new
release, then each PDB would need to be upgraded separately to capture the change. Storing the table
definition only once in the root eliminates this problem.
Metadata and Object Links
The CDB uses an internal mechanism to achieve the preceding goals. Specifically, Oracle Database uses the following
automatically managed pointers:
 Metadata links
Oracle Database stores metadata about dictionary objects only in the root. For example, the column
definitions for the OBJ$ dictionary table, which underlies the DBA_OBJECTS data dictionary view, exist only in
the root. The OBJ$ table in each PDB uses an internal mechanism called a metadata link to point to the
definition of OBJ$ stored in the root.
The data corresponding to a metadata link resides in its PDB, not in the root. For example, if you create table
mytable in hrpdb and add rows to it, then the rows are stored in the PDB files. The data dictionary views in
the PDB and in the root contain different rows. For example, a new row describing mytable exists in the OBJ$
table in hrpdb, but not in the OBJ$ table in the root. Thus, a query of DBA_OBJECTS in the root and
DBA_OBJECTS in hrdpb shows different result sets.
 Object links
In some cases, Oracle Database stores the data (not metadata) for an object only once in the root. For
example, AWR data resides in the root. Each PDB uses an internal mechanism called an object link to point to
the AWR data in the root, thereby making views such as DBA_HIST_ACTIVE_SESS_HISTORY and
DBA_HIST_BASELINE accessible in each separate container.
Oracle Database automatically creates and manages object and metadata links. Users cannot add, modify, or remove
these links.

CDB data dictionary views

When the current container is the root, a common user can query CDB_ views to see metadata for the root and for
PDBs for which this user is privileged. When the current container is a PDB, however, a user can view data dictionary
information for the current PDB only. To an application connected to a PDB, the data dictionary appears as it would
for a non-CDB.

Ahmed Fathi - Senior Oracle Consultant P ag e |7


Email: ahmedf.dba@gmail.com Blog: http://ahfathi.blogspot.com LinkedIn: http://linkedin.com/in/ahmedfathieg
Oracle Multitenant 12c

Creating a CDB
To use the pluggable database feature, you have to specifically create a pluggable enabled CDB. There are a several
different techniques for creating a CDB:
 Manually issuing the SQL CREATE DATABASE command
 Using DBCA
 Generating the required scripts with the DBCA, and then manually running the scripts to create a CDB
 Using RMAN to duplicate an existing CDB

Focus to create a database with the CREATE DATABASE command and the DBCA.
Using the DBCA
You can use the DBCA utility to create a CDB through either a graphical interface or the command-line mode. When
using the graphical interface, you’ll be prompted as to whether or not you want to create a CDB.

Creating Manually with SQL

First, ensure that your ORACLE_SID, ORACLE_HOME, and PATH variables are set for your CDB environment
$ export ORACLE_SID=CDB1
$ export ORACLE_HOME=/u01/app/oracle/product/12.1.0.1/db_1
$ export PATH=$ORACLE_HOME/bin:$PATH
Next, create a parameter initialization file in the ORACLE_HOME/dbs directory. Make certain you set the
ENABLE_PLUGGABLE_DATABASE parameter to TRUE. Here, create a file named initCDB.ora and placed within it the
following parameter:
db_name='CDB'
enable_pluggable_database=true
audit_trail='db'
control_files='/u01/dbfile/CDB/control01.ctl','/u01/dbfile/CDB/control02.ctl'
db_block_size=8192
db_domain=''
memory_target=629145600
memory_max_target=629145600
open_cursors=300

Ahmed Fathi - Senior Oracle Consultant P ag e |8


Email: ahmedf.dba@gmail.com Blog: http://ahfathi.blogspot.com LinkedIn: http://linkedin.com/in/ahmedfathieg
Oracle Multitenant 12c

processes=300
remote_login_passwordfile='EXCLUSIVE'
undo_tablespace='UNDOTBS1'

Next, ensure you have created any directories referenced in the parameter file and the CREATE DATABASE
statement:
$ mkdir -p /u01/dbfile/CDB/pdbseed
$ mkdir -p /u01/dbfile/CDB
$ mkdir -p /u01/oraredo/CDB
Now, start up your database in nomount mode, and execute create database command.
$ sqlplus / as sysdba
SQL> startup nomount;
SQL> CREATE DATABASE CDB
MAXLOGFILES 16
MAXLOGMEMBERS 4
MAXDATAFILES 1024
MAXINSTANCES 1
MAXLOGHISTORY 680
CHARACTER SET US7ASCII
NATIONAL CHARACTER SET AL16UTF16
DATAFILE '/u01/dbfile/CDB/system01.dbf' SIZE 500M
EXTENT MANAGEMENT LOCAL
UNDO TABLESPACE undotbs1 DATAFILE '/u01/dbfile/CDB/undotbs01.dbf' SIZE 800M
SYSAUX DATAFILE '/u01/dbfile/CDB/sysaux01.dbf' SIZE 500M
DEFAULT TEMPORARY TABLESPACE TEMP TEMPFILE '/u01/dbfile/CDB/temp01.dbf' SIZE 500M
DEFAULT TABLESPACE USERS DATAFILE '/u01/dbfile/CDB/users01.dbf' SIZE 50M
LOGFILE GROUP 1 ('/u01/oraredo/CDB/redo01a.rdo') SIZE 50M,
GROUP 2 ('/u01/oraredo/CDB/redo02a.rdo') SIZE 50M
USER sys IDENTIFIED BY foo
USER system IDENTIFIED BY foo
USER_DATA TABLESPACE userstbs DATAFILE '/u01/dbfile/CDB/userstbsp01.dbf' SIZE 500M
ENABLE PLUGGABLE DATABASE
SEED FILE_NAME_CONVERT = ('/u01/dbfile/CDB','/u01/dbfile/CDB/pdbseed');
Close/open the seed PDB and run postcreation scripts.
- Set the session with a new parameter:
SQL> alter session set "_oracle_script"=true;
- Close and open the seed PDB:
SQL> alter pluggable database pdb$seed close;
SQL> alter pluggable database pdb$seed open;
- Execute catalog.sql and other postcreation scripts.
SQL>?/rdbms/admin/catalog.sql
SQL>?/rdbms/admin/catblock.sql
SQL>?/rdbms/admin/catproc.sql
SQL>?/rdbms/admin/catoctk.sql
SQL>?/rdbms/admin/owminst.plb
SQL>?/sqlplus/admin/pupbld.sql
Note: To get the full list of scripts executed and the sequence of execution to follow, run DBCA to create CDB and in
the last step, generate the scripts only. The scripts are created in the $ORACLE_BASE/admin/<cdb_name>/scripts
directory. The shell script <cdb_name>.sh is the first script to read.

Ahmed Fathi - Senior Oracle Consultant P ag e |9


Email: ahmedf.dba@gmail.com Blog: http://ahfathi.blogspot.com LinkedIn: http://linkedin.com/in/ahmedfathieg
Oracle Multitenant 12c

Verifying that a CDB was created


To verify whether a database was created as a CDB, first connect to the root container as SYS sqlplus / as sysdba, You
can now confirm that the CDB was successfully created via this query. If a database was created as a CDB, the CDB
column of V$DATABASE will contain a YES value:
SQL> select name, cdb from v$database;
NAME CDB
--------- ---
ORCLCDB YES
At this point, you should have two containers in your CDB database: the root container and the seed pluggable
database. You can check with this query:
SQL> select con_id, name from v$containers;
CON_ID NAME
---------- ------------------------------
1 CDB$ROOT
2 PDB$SEED

Administrating the Root Container


When you manage a CDB, you are connecting to the root container as SYS and performing tasks as you would with a
non-CDB database. However, there are several points to be aware of that are specific to maintaining a CDB. The
following tasks can only be performed while connected to the root container with SYSDBA privileges:
• Starting/stopping instance
• Enabling/disabling archive log mode
• Managing instance settings that affect all databases within the CDB, such as overall memory size
• B&R of all data files within the database
• Managing control files (adding, restoring, removing, and so on)
• Managing online redo logs
• Managing the root UNDO tablespace
• Managing the root TEMP tablespace
• Creating common users and roles

Connecting to the Root Container


Connecting to the root container as SYS allows you to perform all the tasks you normally associate with database
administration. You can connect as SYS locally from the database server through OS authentication or a network
connection (which requires a listener and password file).
Through OS Authentication : $ sqlplus / as sysdba
Through Network :$ sqlplus user/pass@connection_string as sysdba
You can verify the SYS connection to the root container:
SQL> show user con_id con_name
SQL> SELECT SYS_CONTEXT('USERENV', 'CON_ID') AS con_id,SYS_CONTEXT('USERENV', 'CON_NAME') AS
cur_container,SYS_CONTEXT('USERENV', 'SESSION_USER') AS cur_user FROM DUAL;

Starting/Stopping the Root Container


You can only start/stop the CDB while connected as a privileged user to the root container. The procedure for starting
and stopping the root container is the same as for a non-CDB database. To start a CDB, first connect as SYS, and issue
the startup command:

Ahmed Fathi - Senior Oracle Consultant P a g e | 10


Email: ahmedf.dba@gmail.com Blog: http://ahfathi.blogspot.com LinkedIn: http://linkedin.com/in/ahmedfathieg
Oracle Multitenant 12c

$ sqlplus / as sysdba
SQL> startup;

Starting the CDB database does not open any associated pluggable databases. You can open all pluggable databases
with this command:
SQL> alter pluggable database all open;

To shut down a CDB database, issue the following command:


SQL> shutdown immediate;

Just as with a non-CDB database, the prior line shuts down the CDB instance and disconnects any users connected to
the database. If any pluggable databases are open, they are closed, and users are disconnected.

Creating a Pluggable Database within a CDB


When you instruct Oracle to create a pluggable database, it is actually copying data files from an existing database
(seed, pluggable database, or non-CDB) and then instantiating the CDB with the new pluggable database’s metadata.
The key here is to correctly reference what database you want Oracle to use as a template for creating the new
pluggable database.
There are several tools for creating (cloning) a pluggable database; namely the CREATE PLUGGABLE DATABASE SQL
statement, the DBCA utility, and Enterprise Manager Cloud Control. You can use any of the following sources to
create a pluggable database:
• Seed database
• Existing pluggable database (either local or remote)
• Non-CDB database
• Unplugged pluggable database
Creation of a PDB from Seed
The CREATE PLUGGABLE DATASE statement can be used to create a pluggable
database by copying the seed database’s data files. To do this, first connect to the
root container database as the SYS user:
$ sqlplus / as sysdba
The following SQL statement creates a pluggable database named SALESPDB:
SQL> CREATE PLUGGABLE DATABASE pdb1 ADMIN USER pdbadm IDENTIFIED BY
foo FILE_NAME_CONVERT = ('/u01 /oracle/oradata/CDB/pdbseed','/u01
/oracle/oradata/CDB/pdb1');

Pluggable Database Creation Options :


Parameter Description
ADMIN USER A local user that is created and used for administrative tasks. This user is assigned the
PDB_DBA role.
MAXSIZE Maximum amount of storage a pluggable database can consume; if not specified, then there
is no limit to the amount of storage a pluggable database can use
MAX_SHARED_TEMP_SIZE Maximum amount of shared temporary tablespace that can be used by sessions connected to
the pluggable database
DEFAULT TABLESPACE Specifies the default permanent tablespace assigned to new users created within the
pluggable database
DATAFILE Path and file name of the data file associated with the default tablespace
PATH_PREFIX Specifies that any new data files added to the pluggable database must exist within this
directory or its subdirectories

Ahmed Fathi - Senior Oracle Consultant P a g e | 11


Email: ahmedf.dba@gmail.com Blog: http://ahfathi.blogspot.com LinkedIn: http://linkedin.com/in/ahmedfathieg
Oracle Multitenant 12c

FILE_NAME_CONVERT Specifies the location of the seed database data files and the location where they should be
copied
Note: If you’re using OMF DB_CREATE_FILE_DEST or New parameter PDB_FILE_NAME_CONVERT, you don’t need to
specify the FILE_NAME_CONVERT clause when creating a pluggable database, because Oracle automatically
determines the names and locations of the pluggable database data files.
Then use the cdb_pdbs view to verify that the new PDB and its tablespaces exist:
SQL> SELECT * FROM cdb_pdbs;
SQL> SELECT * FROM cdb_tablespaces;
SQL> SELECT * FROM cdb_data_files;

Cloning an Existing Pluggable Database

This technique copies the files associated with the source PDB to a new location and
associates the copied files with the new PDB. You can clone a PDB that resides in the
same CDB (Local) or in a different CDB (Remote). If in a different CDB, then you must
use a database link to specify the remote CDB that contains the PDB to be cloned.

Local
In this example an existing pluggable database (pdb1) is used to create a new
pluggable database (pdb3).
First, connect to the root container, and place the existing source pluggable database
in read-only mode:
$ sqlplus / as sysdba
SQL> alter pluggable database pdb1 close;
SQL> alter pluggable database pdb1 open read only;
Now, run the following SQL to create the new pluggable database:
SQL> CREATE PLUGGABLE DATABASE pdb3 FROM pdb1
FILE_NAME_CONVERT = ('/u01/app/oracle/oradata/CDB/pdb1','/u01/dbfile/CDB/pdb3')
STORAGE (MAXSIZE 6G MAX_SHARED_TEMP_SIZE 100M);

Note: If the underlying file system of a PDB supports storage snapshots, then you may specify the SNAPSHOT COPY
clause to clone a PDB using storage snapshots. In this case, Oracle Database does not make a complete copy of
source data files, but creates a storage-level snapshot of the underlying file system, and uses it to create PDB clones.
Snapshot copies make cloning almost instantaneous. Built on copy-on-write capability of underlying file system and
Supported on ZFSSA, ACFS, NetApp

Remote
You can also create a pluggable database as a clone of a remote pluggable database. First, you need to create a
database link from the CDB to the pluggable database that will serve as the source for the clone. Both the local user
and the user specified in the database link must have the CREATE PLUGGABLE DATABASE privilege.
This example shows a local connection as SYS to the root container. This is the database in which the new pluggable
database will be created:
$ sqlplus / as sysdba
In this database, create a database link to the pluggable database in the remote CDB. The remote CDB contains a
pluggable database named pdb1, with a user that has been created with the CREATE PLUGGABLE DATABASE privilege
granted to it. This is the user that will be used in the database link:

Ahmed Fathi - Senior Oracle Consultant P a g e | 12


Email: ahmedf.dba@gmail.com Blog: http://ahfathi.blogspot.com LinkedIn: http://linkedin.com/in/ahmedfathieg
Oracle Multitenant 12c

SQL> CREATE DATABASE LINK pdb1dblink CONNECT TO pdb1adm IDENTIFIED BY foo USING
'cdr2hostname:1521/pdb1';

Next, connect to the remote database that contains the pluggable database that will be cloned:
$ sqlplus sys/foo@cdr2hostname:1521/pdb1 as sysdba
Close the pluggable database, and open it in read-only mode:
SQL> alter pluggable database pdb1 close;
SQL> alter pluggable database pdb1 open read only;

Now, connect to the destination CDB as SYS, and create the new pluggable database by cloning the remote pluggable
database, as shown:
$ sqlplus / as sysdba
SQL> CREATE PLUGGABLE DATABASE pdb3 FROM pdb1@pdb1dblink
FILE_NAME_CONVERT = ('/u01/app/oracle/oradata/CDB/pdb1','/u01/dbfile/CDB2/pdb3');

Cloning from a Non-CDB Database


You can use any of the following techniques to create a PDB from an existing non-CDB:

 Execute DBMS_PDB.DESCRIBE on a non-CDB in Oracle Database 12c


You place a non-CDB in a transactionally consistent state, and then run the
DBMS_PDB.DESCRIBE function to generate XML metadata about this database.
While connected to the root in the CDB, you execute the CREATE PLUGGABLE
DATABASE statement to create a PDB from the existing non-CDB.

Note: When using the DBMS_PDB package to convert a non-CDB to a pluggable


database, the non-CDB must be Oracle12c or higher.
 Use Oracle Data Pump with or without transportable tablespaces
You can use Oracle Data Pump to define a data set on a non-CDB. This non-CDB can
be in the current or a previous Oracle Database release, for example, Oracle
Database 10g. You create an empty PDB in an existing CDB, and then use Oracle Data Pump to import the data set
into the PDB.
 Use Oracle GoldenGate replication.

Methods to migrating pre-12.1 or 12.1 non-CDB to CDB


There are two methods to migrate a non-container 11g database to a 12c CDB.
The first method consists of two steps:
1. Upgrade the 11g database (or any other previous Oracle Database release) to
12c non-CDB.
2. Plug in the 12c non-CDB into a CDB: Use DBMS_PDB.DESCRIBE procedure to
generate the XML file to plug the data files into the CDB as a new PDB. This is the
fastest solution.
The second method consists of two steps:
1. Precreate a PDB in the CDB from the seed PDB. This operation establishes an
Oracle Database 12c dictionary in the newly created PDB.
2. Use either export/import (Data Pump or not) or replication to load the 9i, 10g,
11g data into the newly created PDB of the CDB.

Ahmed Fathi - Senior Oracle Consultant P a g e | 13


Email: ahmedf.dba@gmail.com Blog: http://ahfathi.blogspot.com LinkedIn: http://linkedin.com/in/ahmedfathieg
Oracle Multitenant 12c

Plug a Non-CDB into CDB Using DBMS_PDB


First, place the non-CDB in read-only mode:
SQL> startup mount;
SQL> alter database open read only;
Then, run the DBMS_PDB package to create an XML file that describes the structure of the non-CDB database:
SQL> BEGIN
dbms_pdb.Describe(pdb_descr_file =>'/orahome/oracle/ncdb.xml');
END;
/
After the XML file is created, shut down the non-CDB database:
SQL> shutdown immediate;
Next, set your oracle OS variables (such as ORACLE_SID and ORACLE_HOME), and connect
to the CDB database that will house the non-CDB as a pluggable database:
$ sqlplus / as sysdba
Now, you can optionally check to see if the non-CDB is compatible with the CDB in which it
will be plugged.
When you run this code provide the directory and name of the XML file that was created
previously:
SET SERVEROUTPUT ON
DECLARE
hold_var BOOLEAN;
BEGIN
hold_var := dbms_pdb.Check_plug_compatibility( pdb_descr_file =>
'/orahome/oracle/ncdb.xml');
IF hold_var THEN
dbms_output.Put_line('YES');
ELSE
dbms_output.Put_line('NO');
END IF;
END;
/
If there are no compatibility issues, a YES is displayed by the prior code; a NO is displayed if the pluggable database is
not compatible. You can query the contents of the PDB_PLUG_IN_VIOLATIONS view for details on why a pluggable
database is not compatible with a CDB
Next, use the following SQL to create a pluggable database from the non-CDB. You must specify details such as the
name and location of the previously created XML file, the location of the non-CDB data files, and the location where
you want the new data files created:
SQL> CREATE PLUGGABLE DATABASE pdb2 USING '/orahome/oracle/ncdb.xml'
COPY FILE_NAME_CONVERT = ('/u01/dbfile/orcl/','/u01/dbfile/CDB/pdb2/');
Now, connect as SYS to the newly created pluggable database:
$ sqlplus sys/foo@crdhostname:1521/pdb2' as sysdba
As a last step, run the following script:
SQL> @?/rdbms/admin/noncdb_to_pdb.sql
You should now be able to open the pluggable database and begin using it.

Ahmed Fathi - Senior Oracle Consultant P a g e | 14


Email: ahmedf.dba@gmail.com Blog: http://ahfathi.blogspot.com LinkedIn: http://linkedin.com/in/ahmedfathieg
Oracle Multitenant 12c

Creation of a PDB by Plugging in an Unplugged PDB

A) Unplugging a Pluggable Database from a CDB


Before plugging a pluggable database into another CDB, it must first be unplugged. Unplugging translates to
disassociating a pluggable database from a CDB and generating an XML file that describes the pluggable database
being unplugged. This XML file can be used in the future to plug the pluggable database into another CDB.
Here are the steps required to unplug a pluggable database:
1. Close the pluggable database (which changes its open mode to MOUNTED)
2. Unplug the pluggable database via the ALTER PLUGGABLE DATABASE ... UNPLUG command
First, connect to the root container as the SYS user, and then close the pluggable database:
$ sqlplus / as sysdba
SQL> alter pluggable database pdb1 close immediate;
Next, unplug the pluggable database. Make sure you specify a directory that exists in
your environment for the location of the XML file:
SQL> alter pluggable database pdb1 unplug
into'/orahome/oracle/dba/pdb1.xml';
The XML file contains metadata regarding the pluggable database, such as its data files.
This XML is required if you want to plug the pluggable database into another CDB.
B) Plugging an Unplugged Pluggable Database into a CDB
Before a pluggable database can be plugged into a CDB, it must be compatible with a
CDB in terms of data file endianness and compatible database options installed. You can
verify the compatibility via the DBMS_PDB package.
You must provide as input to the package the directory and name of the XML file created
when the pluggable database was unplugged.
SET SERVEROUTPUT ON
DECLARE
hold_var BOOLEAN;
BEGIN
hold_var :=
dbms_pdb.Check_plug_compatibility(pdb_descr_file => '/orahome/oracle/dba/ pdb1.xml');
IF hold_var THEN
dbms_output.Put_line('YES');
ELSE
dbms_output.Put_line('NO');
END IF;
END;
/
If there are no compatibility issues, a YES is displayed by the prior code; a NO is displayed if the pluggable database is
not compatible. You can query the contents of the PDB_PLUG_IN_VIOLATIONS view for details on why a pluggable
database is not compatible with a CDB.
Plugging in a pluggable database is done with the CREATE PLUGGABLE DATABASE command. When you plug a
pluggable database into a CDB, you must provide some key pieces of information, using these two clauses:
• USING clause: This clause specifies the location of the XML file created when the pluggable database was unplugged
• COPY FILE_NAME_CONVERT clause: This clause specifies the source of the pluggable database data files and the
location where the pluggable database data files will be created within the destination CDB.

Ahmed Fathi - Senior Oracle Consultant P a g e | 15


Email: ahmedf.dba@gmail.com Blog: http://ahfathi.blogspot.com LinkedIn: http://linkedin.com/in/ahmedfathieg
Oracle Multitenant 12c

To plug in a pluggable database, connect to the CDB as a privileged user, and run the following:
SQL> CREATE PLUGGABLE DATABASE pdb1 USING '/orahome/oracle/dba/pdb1.xml'
COPY FILE_NAME_CONVERT = ('/u01/app/oracle/oradata/CDB1/pdb1, '/u01/dbfile/CDB2/pdb1');
You can now open the pluggable database and begin using it.

Checking the Status of Pluggable Databases


You can view the status of all pluggable databases within a CDB while connected as a privileged user in the root
container. For instance, a user with DBA privileges can report on the status of all pluggable databases via this query:
SQL> select pdb_id, pdb_name, status from cdb_pdbs;
PDB_ID PDB_NAME STATUS
---------- ------------ -------------
3 PDB1 NORMAL
2 PDB$SEED NORMAL
4 PDB3 NORMAL
This next query reports on whether or not the pluggable databases are open:
SQL> select con_id, name, open_mode from v$pdbs;
CON_ID NAME OPEN_MODE
---------- ------------------------------ ----------
2 PDB$SEED READ ONLY
3 PDB1 READ WRITE
4 PDB3 READ WRITE

Note: If you run the prior queries while connected directly to a pluggable database, no information will be displayed
in CDB_PDBS. Also, the V$PDBS will only display information for the currently connected pluggable database.

Common and Local Users and Privileges


Every user that owns objects that define the database is common. User-created users are either local or common.

A common user is a database user that has the same identity in the root and in every existing and future PDB. Every
common user can connect to and perform operations within the root, and within any PDB in which it has privileges.
Every common user is either Oracle-supplied or user-created. Examples of Oracle-supplied common users are SYS and
SYSTEM.
The name of every user-created common user must begin with the characters c## or C##, every common user is
uniquely named across all containers. The schemas for a common user can differ in each container
$ sqlplus / as sysdba

Ahmed Fathi - Senior Oracle Consultant P a g e | 16


Email: ahmedf.dba@gmail.com Blog: http://ahfathi.blogspot.com LinkedIn: http://linkedin.com/in/ahmedfathieg
Oracle Multitenant 12c

SQL> CREATE USER c##abc IDENTIFIED BY abc CONTAINER=ALL;

A local user is a database user that is not common and can operate only within a single PDB, cannot log in to another
PDB or to the root. The name of a local user must not begin with the characters c## or C## and must only be unique
within its PDB. A local user cannot be created in the root
The syntax is the same as in a traditional or non-CDB. This is in keeping with the application transparency goal for
PDBs. The syntax for commands in a PDB are identical to commands in a non-CDB.
SQL> CONNECT system@pdb1
SQL> CREATE USER abc_local IDENTIFIED BY local123;
Note: The DROP USER and ALTER USER commands are identical, as the commands in a non- CDB.

Common and Local Privileges

A privilege becomes common or local based on the way it is granted. A privilege granted across all containers is a
common privilege. A privilege granted in a specific PDB is local.
Common and local users can exercise common and local privileges that have been granted in the context of the PDB
to which they are connected. A common user can be granted both common and local privileges. That means the
privileges granted to a common user can be different in every PDB.
A common privilege is granted to a grantee in all containers.
SQL> GRANT create session TO c##abc CONTAINER=ALL;
SQL> GRANT drop user TO c##user CONTAINER=ALL;
SQL> REVOKE drop user FROM c##_user CONTAINER=ALL;
A local privilege is granted to a grantee in one container.
SQL> GRANT advisor TO u1;
SQL> GRANT alter user TO local_user CONTAINER=CURRENT;
SQL> REVOKE alter user FROM local_user;

Common and Local Roles

Every Oracle-supplied role is common. In Oracle-supplied scripts, every privilege or role granted to Oracle-supplied
users and roles is granted commonly, with one exception: system privileges are granted locally to the common role
PUBLIC. User-created roles are either local or common
A common role is a database role that exists in the root and in every existing and future PDB. Common roles are
useful for cross-container operations. Every common role is either user-created or Oracle-supplied. All Oracle-
supplied roles are common, such as DBA and PUBLIC. User-created common roles must have names starting with C##
or c##.
A local role exists only in a single PDB, just as a role in a non-CDB exists only in the non-CDB. A local role can only
contain roles and privileges that apply within the container in which the role exists. PDBs in the same CDB may
contain local roles with the same name.
A user can create common roles if the user has the CREATE ROLE privilege, and SET CONTAINER for all PDBs. A
common user can create a local role if the user has the CREATE ROLE and SET CONTAINER privileges for that PDB. The
CONTAINER clause determines whether the role is common or local. A common role must begin with C## characters.
Any role can be granted to any role or user. It does not matter whether the user or role is defined to be local or
common.
A common role is created in all containers.
SQL> CREATE ROLE c##r1 CONTAINER=ALL;

Ahmed Fathi - Senior Oracle Consultant P a g e | 17


Email: ahmedf.dba@gmail.com Blog: http://ahfathi.blogspot.com LinkedIn: http://linkedin.com/in/ahmedfathieg
Oracle Multitenant 12c

Common roles granted commonly


SQL> GRANT c##r1 TO c##user CONTAINER=ALL;

A local role is created in one container.


SQL> CREATE ROLE l_role1 ;
SQL> CREATE ROLE L_HR CONTAINER=CURRENT;
Common roles granted locally
SQL> GRANT c##r2 TO l_user;
Grant a common role to a common user locally.
SQL> GRANT c##_role TO c##_user CONTAINER=CURRENT;
Grant a local role to a common user locally.
SQL> GRANT l_role TO c##_user CONTAINER=CURRENT;
Local roles granted locally
SQL> GRANT hr_mgr TO hr_user;
Revoke a common role commonly.
SQL> REVOKE c##_role FROM c##_user CONTAINER=ALL;
Revoke a local or common role locally.
SQL> REVOKE local_role FROM local_user;

Note: GRANT and REVOKE are mostly unchanged. The syntax has been extended with the CONTAINER clause so that
common and local roles can be granted or revoked commonly or locally.

Ahmed Fathi - Senior Oracle Consultant P a g e | 18


Email: ahmedf.dba@gmail.com Blog: http://ahfathi.blogspot.com LinkedIn: http://linkedin.com/in/ahmedfathieg
Oracle Multitenant 12c

Listener and Services in a Pluggable Database Environment


Each new PDB is assigned a service name: the service name is the PDB name given at PDB creation concatenated with
domain name. If you create or plug a PDBtest PDB, its service name
is PDBtest concatenated with domain name. The container service
names must be unique within a CDB, and even across CDBs that
register with the same listener.
The root container service name is the CDB name given at the CDB
creation concatenated with domain name.
You can verify which services are running by connecting as SYS to
the root container and querying:
SQL> SELECT name, network_name, pdb FROM v$services ORDER BY pdb, name;
SQL> SELECT name, pdb FROM cdb_services;
You can view the services names using Server Control utility as follows:
$ srvctl config database -db cdb1
You can also verify which services a listener is listing for via the lsnrctl utility:
$ lsnrctl services
Oracle recommends that you configure an additional service (besides the default service) for any applications that
need to access a pluggable database. You can manually configure services by using the SRVCTL utility or the
DBMS_SERVICE package.
Using the DBMS_SERVICE package in an environment without Oracle Restart:
SQL> EXEC DBMS_SERVICE.CREATE_SERVICE('hrpdb','hrpdb')
SQL> EXEC DBMS_SERVICE.START_SERVICE('hrpdb')

Using the SRVCTL utility in a Grid Infrastructure environment with Oracle Restart:
$ srvctl add service -db mycdb -service hrpdb -pdb hrpdb
$ srvctl start service -db mycdb -service hrpdb
Caution If you have multiple CDB databases on one server, ensure that the pluggable database service names are
unique across all CDB databases on the server. It’s not advisable to register two pluggable database databases with
the exact same name with one common listener. This will lead to confusion as to which pluggable database you are
actually connecting to.

Connections to Containers in a CDB


You can connect to a pluggable database either of the following techniques:
 Use the ALTER SESSION SET CONTAINER statement
In this case, the user requires the SET CONTAINER system privilege in the container. This connection doesn’t
require a listener or password file.
$ sqlplus / as sysdba
SQL> alter session set container=pdb1;

 Connect directly to a PDB.


To connect to a desired PDB, use either EasyConnect or the alias from the tnsnames.ora file. In this case, the
user requires the CREATE SESSION privilege in the container
$ sqlplus username/password@hostname:port/service_name

Ahmed Fathi - Senior Oracle Consultant P a g e | 19


Email: ahmedf.dba@gmail.com Blog: http://ahfathi.blogspot.com LinkedIn: http://linkedin.com/in/ahmedfathieg
Oracle Multitenant 12c

$ sqlplus username/password@net_service
SQL> CONNECT sys@CDB1 AS SYSDBA
SQL> CONNECT sys@PDBtest AS SYSDBA
SQL> CONNECT local_user1@hostname1:1521/PDBHR
SQL> CONNECT common_user2@PDBdev

Switching Connection
Two possible ways to switch connection between containers within a CDB:
Reconnect
SQL> CONNECT / AS SYSDBA
SQL> CONNECT local_user1@PDBdev

Use ALTER SESSION statement


SQL> CONNECT sys@PDBtest AS SYSDBA
SQL> ALTER SESSION SET CONTAINER=PDBHR;
SQL> SHOW CON_NAME
SQL> ALTER SESSION SET CONTAINER=CDB$ROOT;

Notes:
- Using CONNECT allows connection under common or local user.
- Using ALTER SESSION SET CONTAINER allows connection under common user only who is granted new
system privilege SET CONTAINER.
 AFTER LOGON triggers do not fire.
 Transactions that are not committed nor rolled back in the original container are still in a pending
state while switching to another container and when switching back to the original container.

Showing the Currently Connected Pluggable Database


From SQL*Plus there are a couple of easy techniques for displaying the name of the pluggable database that you’re
currently connected to. This example uses the SHOW command to display the container ID, the name, and the user:
SQL> show user con_id con_name
SQL> SELECT SYS_CONTEXT('USERENV', 'CON_ID') AS con_id, SYS_CONTEXT('USERENV', 'CON_NAME')
AS cur_container, SYS_CONTEXT('USERENV', 'SESSION_USER') AS cur_user
FROM DUAL;
SQL> SELECT SYS_CONTEXT('USERENV', 'SERVICE_NAME') as service_name, SYS_CONTEXT('USERENV',
'DB_UNIQUE_NAME') as db_unique_name, SYS_CONTEXT('USERENV', 'INSTANCE_NAME') as
instance_name, SYS_CONTEXT('USERENV', 'SERVER_HOST') as server_host from dual;
If you need to view when a pluggable database was created, you can query the CDB_PDB_HISTORY view,
COL db_name FORM A10
COL con_id FORM 999
COL pdb_name FORM A15
COL operation FORM A16
COL op_timestamp FORM A10
COL cloned_from_pdb_name FORMAT A15
SELECT db_name,con_id,pdb_name,
operation,op_timestamp,
cloned_from_pdb_name
FROM cdb_pdb_history
WHERE con_id > 2
ORDER BY con_id;

Ahmed Fathi - Senior Oracle Consultant P a g e | 20


Email: ahmedf.dba@gmail.com Blog: http://ahfathi.blogspot.com LinkedIn: http://linkedin.com/in/ahmedfathieg
Oracle Multitenant 12c

Starting/Stopping CDB Instance and Pluggable Database


In a non-RAC environment, a CDB runs with a single instance. The instance is started/stopped exactly the same way
as for non-CDB databases.

Ahmed Fathi - Senior Oracle Consultant P a g e | 21


Email: ahmedf.dba@gmail.com Blog: http://ahfathi.blogspot.com LinkedIn: http://linkedin.com/in/ahmedfathieg
Oracle Multitenant 12c

Note: When you start/stop a pluggable database, you aren’t starting/stopping an instance. Rather, you are making
the pluggable database either available or unavailable, open or closed. You can change the open mode of a pluggable
database from either a connection to the root container as SYS or a direct connection to the pluggable database as
SYS.
To change the open mode of a pluggable database from the root container, do as follows:
$ sqlplus / as sysdba
SQL> alter pluggable database pdb1 open;

You can also start a pluggable database in a particular state, such as read-only or restricted mode:
SQL> startup pluggable database pdb1 open read only;
SQL> alter pluggable database pdb1 open restricted;

To close a pluggable database, you can specify the name of the pluggable database:
SQL> alter pluggable database pdb1 close immediate;

You can also open or close all pluggable databases while connected to the root container as SYS:
SQL> alter pluggable database all open;
SQL> alter pluggable database all close immediate;

From Pluggable
To open/start a pluggable database, connect to the pluggable database as SYS:
$ sqlplus sys/foo@salespdb as sysdba
SQL> startup;
Or
SQL> alter pluggable database open;

To shut down the database, issue the following command:


SQL> shutdown immediate;
Or
SQL> alter pluggable database close;

Modifying a PDB Settings with the ALTER PLUGGABLE DATABASE Statement


When the current container is a PDB, an ALTER PLUGGABLE DATABASE statement with any of the following clauses
modifies the PDB:
database_file_clauses
set_time_zone_clause
DEFAULT TABLESPACE clause
DEFAULT TEMPORARY TABLESPACE clause
RENAME GLOBAL_NAME clause
SET DEFAULT { BIGFILE | SMALLFILE } TABLESPACE clause
DEFAULT EDITION clause
pdb_storage_clause
pdb_state_clause
Examples
Bringing a Data File Online for a PDB
SQL> alter pluggable database datafile '/u03/oracle/pdb1_01.dbf' online;

Ahmed Fathi - Senior Oracle Consultant P a g e | 22


Email: ahmedf.dba@gmail.com Blog: http://ahfathi.blogspot.com LinkedIn: http://linkedin.com/in/ahmedfathieg
Oracle Multitenant 12c

Changing the Default Tablespaces for a PDB


SQL> alter pluggable database default tablespace pdb1_tbs;

Changing the Default Temporary Tablespaces for a PDB


SQL> alter pluggable database default temporary tablespace pdb1_temp;

Changing the Default Tablespace Type for a PDB


SQL> alter pluggable database set default bigfile tablespace;

Setting Storage Limits for a PDB


SQL> alter pluggable database storage(maxsize 2g);
SQL> alter pluggable database storage(maxsize unlimited);
SQL> alter pluggable database storage(max_shared_temp_size 500m);
SQL> alter pluggable database storage(max_shared_temp_size unlimited);
SQL> alter pluggable database storage unlimited;

Changing global database name


SQL> alter pluggable database open restricted force;
SQL> alter pluggable database rename global_name to pdb1a.localdomain;
SQL> alter pluggable database close immediate;
SQL> alter pluggable database open;

Changing Time zone for PDB


SQL> alter pluggable database set time_zone='GMT';

Changing the Open Mode of a PDB


SQL> alter pluggable database close immediate;
SQL> alter pluggable database open read only;
SQL> alter pluggable database open force;

Using the ALTER SYSTEM Statement to Modify a PDB

You can use an ALTER SYSTEM statement to change the way a PDB operates. When the current container is a PDB,
you can run the following ALTER SYSTEM statements:
ALTER SYSTEM FLUSH SHARED_POOL / BUFFER_CACHE
ALTER SYSTEM ENABLE / DISABLE RESTRICTED SESSION
ALTER SYSTEM SET USE_STORED_OUTLINES
ALTER SYSTEM SUSPEND / RESUME
ALTER SYSTEM CHECK DATAFILES
ALTER SYSTEM REGISTER
ALTER SYSTEM KILL SESSION
ALTER SYSTEM DISCONNECT SESSION
ALTER SYSTEM SET initialization_parameter
All other ALTER SYSTEM statements affect the entire CDB and must be run by a common user in the root.
Some ALTER SYSTEM statements can be run from within a PDB but still affect the whole CDB such as ALTER SYSTEM
CHECKPOINT except those in read only or offline. Other ALTER SYSTEM statements affect the entire CDB and must be
run by a common user in the root such as ALTER SYSTEM SWITCH LOGFILE, unless you set the CDB_COMPATIBLE
parameter to FALSE, which enables you to get a behavior similar to a non-CDB when issuing SQL commands inside a
PDB.

Ahmed Fathi - Senior Oracle Consultant P a g e | 23


Email: ahmedf.dba@gmail.com Blog: http://ahfathi.blogspot.com LinkedIn: http://linkedin.com/in/ahmedfathieg
Oracle Multitenant 12c

ALTER SYSTEM SET initialization_parameter

There is a single SPFILE per CDB to store parameters. Values of parameters are associated with the root and apply to
the root and serve as default values for all other containers.
The ALTER SYSTEM SET initialization_parameter statement can modify only some initialization parameters for PDBs.
All initialization parameters can be set for the root. For any initialization parameter that is not set explicitly for a PDB,
the PDB inherits the root's parameter value. PDB parameters are stored in the root container.
You can modify an initialization parameter for a PDB when the ISPDB_MODIFIABLE column is TRUE for the parameter
in the V$SYSTEM_PARAMETER view. The following query lists all of the initialization parameters that are modifiable
for a PDB:
SQL> SELECT NAME FROM V$SYSTEM_PARAMETER WHERE ISPDB_MODIFIABLE='TRUE' ORDER BY NAME;

When the current container is a PDB, run the ALTER SYSTEM SET initialization_parameter statement to modify the
PDB. The statement does not affect the root or other PDBs.
SCOPE Setting Behavior
MEMORY The initialization parameter setting is changed in memory and takes effect immediately in the PDB. The new
setting affects only the PDB. The setting reverts to the value set in the root in the any of the following cases:
 An ALTER SYSTEM SET statement sets the value of the parameter in the root with SCOPE equal to
BOTH or MEMORY, and the PDB is closed and re-opened. The parameter value in the PDB is not
changed if SCOPE is equal to SPFILE, and the PDB is closed and re-opened.
 The CDB is shut down and re-opened.
SPFILE The initialization parameter setting is changed for the PDB in the SPFILE. The new setting takes effect in any of
the following cases:
 The PDB is closed and re-opened.
 The CDB is shut down and re-opened.
BOTH The initialization parameter setting is changed in memory, and it is changed for the PDB in the SPFILE. The new
setting takes effect immediately in the PDB and persists after the PDB is closed and re-opened or the CDB is
shut down and re-opened. The new setting affects only the PDB.
When a PDB is unplugged from a CDB, the values of the initialization parameters that were specified for the PDB with
SCOPE=BOTH or SCOPE=SPFILE are added to the PDB's XML metadata file. These values are restored for the PDB
when it is plugged in to a CDB.
Note: A text initialization parameter file (PFILE) cannot contain PDB-specific parameter values.

Tablespaces in PDBs
In a non-CDB, all the tablespaces belong to one database. In the CDB, one set of tablespaces belong to the root
container, and each PDB has its own set of tablespaces.
The UNDO tablespace is common to all PDBs, that is, there is only one active UNDO tablespace per CDB.
Create a permanent tablespace in the root container:
SQL> CONNECT system@cdb1
SQL> CREATE TABLESPACE tbs_CDB DATAFILE '/u1/app/oradata/cdb/cdb_users01.dbf' SIZE 100M;
Create a permanent tablespace in a PDB:
SQL> CONNECT system@PDB1
SQL> CREATE TABLESPACE tbs_PDB1 DATAFILE '/u1/app/oradata/cdb/pdb1/users01.dbf' SIZE 100M;

Ahmed Fathi - Senior Oracle Consultant P a g e | 24


Email: ahmedf.dba@gmail.com Blog: http://ahfathi.blogspot.com LinkedIn: http://linkedin.com/in/ahmedfathieg
Oracle Multitenant 12c

Temporary Tablespace
A CDB can have only one default temporary tablespace. As with a non-CDB there
can be other temporary tablespaces to which users can be assigned. The default
temporary tablespace is a shared resource for all PDBs, that is, any user in any PDB
will use the CDB default temporary tablespace unless that user is assigned to a
specific temporary tablespace.

A default temporary tablespace can be set for each PDB. A PDB may have multiple
temporary tablespaces, but only one default per PDB. When you create a user you
can specify a temporary tablespace to be used by that user. If a temporary
tablespace is not specified, the default tablespace for the PDB is used. If a default tablespace has not been specified
for the PDB, the temporary tablespace for the CDB is used.
SQL> CONNECT pdb1_admin@pdbhr
SQL> ALTER PLUGGABLE DATABASE DEFAULT TEMPORARY TABLESPACE local_temp;

The default temporary tablespace in the CDB is shared by all the PDBs. The amount of space a single PDB can use in
the shared temporary tablespace can be set in the PDB by:
SQL> ALTER PLUGGABLE DATABASE STORAGE (MAX_SHARED_TEMP_SIZE 500M);

Dropping a Pluggable Database


The DROP PLUGGABLE DATABASE statement drops a PDB. You can drop a PDB when you want to move the PDB from
one CDB to another or when you no longer need the PDB.
You may need to drop a pluggable database. You may want to do so because you don’t need the pluggable database
anymore or because you are transferring (unplugging/plugging) to a different CDB and you want to drop the
pluggable database from the original CDB. If you need to remove a pluggable database, you can do it in two ways:

 Drop the pluggable database and its data files. (INCLUDING DATAFILES)
$ sqlplus / as sysdba
SQL> alter pluggable database pdb1 close immediate;
SQL> drop pluggable database pdb1 including datafiles;

 Drop the pluggable database, and leave its data files in place. (KEEP DATAFILES) default - The PDB's temp file
is removed even when KEEP DATAFILES is specified
$ sqlplus / as sysdba
SQL> alter pluggable database pdb1 close immediate;
SQL> drop pluggable database pdb1;

When you drop a PDB, the control file of the CDB is modified to eliminate all references to the dropped PDB. Archived
redo log files and backups associated with the PDB are not removed, but you can use Oracle Recovery Manager
(RMAN) to remove them.

Backup, Recovery, Flashback CDB and PDBs


Backup
You can use Recovery Manager (RMAN) or Enterprise Manager to back up and recover entire CDBs, partial CDBs,
individual whole PDBs, or partial PDBs such as tablespace/datafile of specific PDBs.
The CDB or PDBs are the possible targets for RMAN; an individual PDB is a valid RMAN TARGET database. Connect to
the root or a PDB as a user with SYSDBA or SYSBACKUP privilege .

Ahmed Fathi - Senior Oracle Consultant P a g e | 25


Email: ahmedf.dba@gmail.com Blog: http://ahfathi.blogspot.com LinkedIn: http://linkedin.com/in/ahmedfathieg
Oracle Multitenant 12c

$ export ORACLE_SID=cdb1
$ rman TARGET /
$ rman TARGET jim@pdb1

CDB Backup: Whole CDB Backup


A whole database backup of a CDB can be, in a similar way to non-CDBs, either
backup sets or image copies of the entire set of data files, namely the root data
files and all PDBs data files, and the control file.
$ rman TARGET /
RMAN> BACKUP DATABASE PLUS ARCHIVELOG;

PDB Backup: Whole PDB Backup


A whole PDB backup backs up the entire set of data files of an individual PDB
$ rman TARGET /
RMAN> BACKUP PLUGGABLE DATABASE sales_pdb;
RMAN> BACKUP PLUGGABLE DATABASE sales_pdb, hr_pdb;
RMAN> BACKUP PLUGGABLE DATABASE hr_pdb PLUS ARCHIVELOG;

PDB Backup: Partial PDB Backup


A partial PDB backup backs up the data files named tablespaces of individual PDBs
$ rman TARGET /
RMAN> BACKUP TABLESPACE sales_pdb:tbs2;
RMAN> BACKUP TABLESPACE hr_pdb:system, sales_pdb:sysaux;
RMAN> BACKUP TABLESPACE sysaux, hr_pdb:sysaux;

Recovery

In a CDB, the granularity of media recovery is very flexible and can be done for the entire CDB, for a PDB, for a
tablespace, for a data file, or even for a block.

Instance Failure
Crash and instance recovery is supported for a CDB as a whole, because there is one single instance for the root and
all its PDBs. When the instance crashes, the only possible instance recovery is a CDB instance recovery.
The instance recovery is performed while opening the root. There is no way to perform a PDB instance recovery.

Media Failure: CDB or PDB Tempfile Recovery


If a tempfile belonging to the CDB or PDB temporary tablespace is lost or damaged, The CDB instance can start up
with a missing temporary file. If any of the temporary files do not exist when the CDB instance is started, they are
created automatically and the CDB opens normally. Or you can decide a manual re-creation instead.
The PDB can open with a missing temporary file. If any of the temporary files do not exist when the PDB is opened,
they are not created automatically. They are automatically recreated at CDB startup. Or you can decide a manual re-
creation instead.

Media Failure: Control File Loss


Similar to non-CDBs, if a controlfile is missing or corrupted, because controlfiles belong to the CDB, the instance soon
crashes and a whole CDB media recovery is required.

Ahmed Fathi - Senior Oracle Consultant P a g e | 26


Email: ahmedf.dba@gmail.com Blog: http://ahfathi.blogspot.com LinkedIn: http://linkedin.com/in/ahmedfathieg
Oracle Multitenant 12c

$ rman TARGET /
RMAN> STARTUP NOMOUNT;
RMAN> RESTORE CONTROLFILE FROM AUTOBACKUP;
RMAN> ALTER DATABASE MOUNT;
RMAN> RECOVER DATABASE;
RMAN> ALTER DATABASE OPEN RESETLOGS;
RMAN> ALTER PLUGGABLE DATABASE ALL OPEN;

Media Failure: Redo Log File Loss


Similar to non-CDB procedures, Depending on whether a whole redo log group or only a redo log member is missing,
follow the same procedures as those for non-CDBs.

Media Failure: In NOARCHIVELOG Mode


The loss of any data file from a CDB in NOARCHIVELOG mode requires complete restoration of the CDB, including
control files and all data files of the root and all PDBs. If you have incremental backups, then you need to perform the
restore and recover operations on the CDB.
With the database in NOARCHIVELOG mode, recovery is possible only up to the time of the last backup. So users
must reenter all changes made since that backup.

Media Failure: root SYSTEM or UNDO datafile


Similar to non-CDBs, If the missing or corrupted data file belongs to the root container SYSTEM or UNDO tablespace,
then the CDB instance will require shutdown, and a media recovery is required.
$ rman TARGET /
RMAN> RESTORE TABLESPACE undo1;
RMAN> RECOVER TABLESPACE undo1;
RMAN> ALTER DATABASE OPEN;
RMAN> ALTER PLUGGABLE DATABASE ALL OPEN;

Media Failure: root SYSAUX Datafile


Similar to non-CDBs, If the data file that is missing or corrupted is a data file of the root tablespaces other than
SYSTEM or UNDO, you offline the tablespace, and then perform a tablespace media recovery. The CDB remains open
while restoring and recovering the missing root datafile.
$ rman TARGET /
RMAN> ALTER TABLESPACE sysaux OFFLINE IMMEDIATE;
RMAN> RESTORE TABLESPACE sysaux;
RMAN> RECOVER TABLESPACE sysaux;
RMAN> ALTER TABLESPACE sysaux ONLINE;

Media Failure: PDB SYSTEM Datafile


If the data file that is missing or corrupted belongs to a PDB and more specifically to the SYSTEM tablespace, the CDB
must be closed unless the PDB is already closed.
If the PDB was closed at the time issue, the users can still work in other PDBs during the PDB recovery. If the PDB was
still open at the time issue, users cannot work at all in any other PDB because the CDB needs to be shut down and
mounted.
$ rman TARGET /
RMAN> STARTUP MOUNT; — useless on closed PDB —
RMAN> RESTORE TABLESPACE sales_pdb:system;
RMAN> RECOVER TABLESPACE sales_pdb:system;
RMAN> ALTER DATABASE OPEN; — useless on closed PDB —

Ahmed Fathi - Senior Oracle Consultant P a g e | 27


Email: ahmedf.dba@gmail.com Blog: http://ahfathi.blogspot.com LinkedIn: http://linkedin.com/in/ahmedfathieg
Oracle Multitenant 12c

RMAN> ALTER PLUGGABLE DATABASE sales_pdb OPEN;

Media Failure: PDB Nonsystem Datafile


Similar to non-CDBs, If the data file that is missing or corrupted belongs to a PDB and more specifically to any
tablespace other than SYSTEM tablespace, the PDB need not be closed. The data file with the error is taken OFFLINE
IMMEDIATE. Media recovery for that data file is required and performed in a similar way to media recovery of a set of
tablespaces. During that recovery time, users can work with other PDB tablespaces and within other PDBs.

SQL> CONNECT system@sales_pdb


SQL> ALTER TABLESPACE tbs2 OFFLINE IMMEDIATE;
RMAN> CONNECT TARGET /
RMAN> RESTORE TABLESPACE sales_pdb:tbs2;
RMAN> RECOVER TABLESPACE sales_pdb:tbs2;
SQL> ALTER TABLESPACE tbs2 ONLINE;

Media Failure: PITR


Recovering a PDB to a point in time does not affect all parts of the CDB—the whole CDB is still opened and, therefore,
all other PDBs are opened. After recovering a PDB to a specified point in time, when you open the PDB using the
RESETLOGS option, a new incarnation of the PDB is created. The PDB RESETLOGS does not perform a RESETLOGS for
the CDB. PDB resetlogs is similar to a database resetlogs.
 A PDB record in the controlfile is updated.
 Each redo log record carries PDB ID in the redo header. This is how recovery knows which redo applies to
which PDB. Redo logs are shared by all PDBs—redo from each PDB is written to a single set of redo logs.
A PDB incarnation is a subincarnation of the CDB. For example, if the CDB is incarnation 5, and a PDB is incarnation 3,
then the fully specified incarnation number of the PDB is (5, 3). The initial incarnation of a PDB is 0. To view the
incarnation of a PDB, query the V$PDB_INCARNATION view.
PDB PITR
RMAN> ALTER PLUGGABLE DATABASE PDB1 CLOSE;
RMAN> RUN {
SET UNTIL SCN = 1851648 ;
RESTORE pluggable DATABASE pdb2_1;
RECOVER pluggable DATABASE pdb2_1
AUXILIARY DESTINATION='/u01/app/oracle/oradata';
ALTER PLUGGABLE DATABASE pdb2_1 OPEN RESETLOGS;
}
PDB Tablespace PITR
RMAN> RECOVER TABLESPACE PDB1:TEST_TBS UNTIL SCN 832972 AUXILIARY DESTINATION
'/tmp/CDB1/reco';
RMAN> ALTER TABLESPACE PDB1:TEST_TBS ONLINE;

Flashback CDB
You can configure Flashback Database for the CDB as you would do for any non-CDB, Restrictions
• You cannot flash back the root alone without flashing back the entire CDB.
• Flashback Database operations on a CDB may not be permitted if point-in-time recovery has been performed on
any of its PDBs. When point-in-time recovery is performed on a PDB, you cannot directly rewind the CDB to a point
that is earlier than the point at which DBPITR for the PDB was performed.
RMAN> SHUTDOWN IMMEDIATE
RMAN> STARTUP MOUNT

Ahmed Fathi - Senior Oracle Consultant P a g e | 28


Email: ahmedf.dba@gmail.com Blog: http://ahfathi.blogspot.com LinkedIn: http://linkedin.com/in/ahmedfathieg
Oracle Multitenant 12c

RMAN> FLASHBACK DATABASE TO SCN 10;


RMAN> ALTER DATABASE OPEN RESETLOGS;
RMAN> ALTER PLUGGABLE DATABASE ALL OPEN;

Viewing Information About CDBs and PDBs with SQL*Plus

Viewing Identifying Information About Each Container in a CDB


COLUMN NAME FORMAT A8
SELECT NAME, CON_ID, DBID, CON_UID, GUID FROM V$CONTAINERS ORDER BY CON_ID;

NAME CON_ID DBID CON_UID GUID


-------- ---------- ---------- ---------- --------------------------------
CDB$ROOT 1 2621979045 1 DD7C48AA5A4504A2E04325AAE80A403C
PDB$SEED 2 4093507576 4093507576 FC6BA9D180B0C463E0431901A8C09102
PDB1 3 3358636534 3358636534 FC6C6C3A0C0ECC51E0431901A8C0B531
PDB3 4 3966983391 3966983391 FC6CBA2CF03ACEEAE0431901A8C021EB

Viewing Container ID, Name, and Status of Each PDB


COLUMN PDB_NAME FORMAT A15
SELECT PDB_ID, PDB_NAME, STATUS FROM DBA_PDBS ORDER BY PDB_ID;

PDB_ID PDB_NAME STATUS


---------- --------------- -------------
2 PDB$SEED NORMAL
3 PDB1 NORMAL
4 PDB3 NORMAL

Viewing the Name and Open Mode of Each PDB


COLUMN NAME FORMAT A15
COLUMN RESTRICTED FORMAT A10
COLUMN OPEN_TIME FORMAT A30
SELECT NAME, OPEN_MODE, RESTRICTED, OPEN_TIME FROM V$PDBS;

NAME OPEN_MODE RESTRICTED OPEN_TIME


--------------- ---------- ---------- ------------------------------
PDB$SEED READ ONLY NO 22-JUN-14 02.06.23.399 PM
PDB1 READ WRITE NO 22-JUN-14 09.47.48.768 PM
PDB3 READ WRITE NO 22-JUN-14 03.38.47.616 PM

Showing the Users in Multiple PDBs


COLUMN PDB_NAME FORMAT A15
COLUMN USERNAME FORMAT A30
SELECT p.PDB_ID, p.PDB_NAME, u.USERNAME
FROM DBA_PDBS p, CDB_USERS u
WHERE p.PDB_ID > 2 AND p.PDB_ID = u.CON_ID
ORDER BY p.PDB_ID;

PDB_ID PDB_NAME USERNAME


---------- --------------- ------------------------------
3 PDB1 SYS
3 PDB1 FLOWS_FILES
3 PDB1 OLAPSYS
3 PDB1 PDB1ADMIN
3 PDB1 SI_INFORMTN_SCHEMA
..
..

Ahmed Fathi - Senior Oracle Consultant P a g e | 29


Email: ahmedf.dba@gmail.com Blog: http://ahfathi.blogspot.com LinkedIn: http://linkedin.com/in/ahmedfathieg
Oracle Multitenant 12c

Showing the Data Files for Each PDB in a CDB


COLUMN PDB_ID FORMAT 999
COLUMN PDB_NAME FORMAT A8
COLUMN FILE_ID FORMAT 9999
COLUMN TABLESPACE_NAME FORMAT A10
COLUMN FILE_NAME FORMAT A60
SELECT p.PDB_ID, p.PDB_NAME, d.FILE_ID, d.TABLESPACE_NAME, d.FILE_NAME
FROM DBA_PDBS p, CDB_DATA_FILES d
WHERE p.PDB_ID = d.CON_ID
ORDER BY p.PDB_ID;

PDB_ID PDB_NAME FILE_ID TABLESPACE FILE_NAME


------ -------- ------- ---------- ---------------------------------------------------------
2 PDB$SEED 5 SYSTEM /u01/app/oracle/oradata/ORCLCDB/pdbseed/system01.dbf
2 PDB$SEED 7 SYSAUX /u01/app/oracle/oradata/ORCLCDB/pdbseed/sysaux01.dbf
3 PDB1 10 USERS /u01/app/oracle/oradata/ORCLCDB/PDB1/PDB1_users01.dbf
3 PDB1 9 SYSAUX /u01/app/oracle/oradata/ORCLCDB/PDB1/sysaux01.dbf
3 PDB1 8 SYSTEM /u01/app/oracle/oradata/ORCLCDB/PDB1/system01.dbf
4 PDB3 13 USERS /u01/app/oracle/oradata/ORCLCDB/PDB3/PDB1_users01.dbf
4 PDB3 12 SYSAUX /u01/app/oracle/oradata/ORCLCDB/PDB3/sysaux01.dbf
4 PDB3 11 SYSTEM /u01/app/oracle/oradata/ORCLCDB/PDB3/system01.dbf

Showing the Temp Files in a CDB


COLUMN CON_ID FORMAT 999
COLUMN FILE_ID FORMAT 9999
COLUMN TABLESPACE_NAME FORMAT A15
COLUMN FILE_NAME FORMAT A60
SELECT CON_ID, FILE_ID, TABLESPACE_NAME, FILE_NAME
FROM CDB_TEMP_FILES
ORDER BY CON_ID;

CON_ID FILE_ID TABLESPACE_NAME FILE_NAME


------ ------- --------------- ------------------------------------------------------------
1 1 TEMP /u01/app/oracle/oradata/ORCLCDB/temp01.dbf
2 2 TEMP /u01/app/oracle/oradata/ORCLCDB/pdbseed/pdbseed_temp01.dbf
3 3 TEMP /u01/app/oracle/oradata/ORCLCDB/PDB1/temp01.dbf
4 4 TEMP /u01/app/oracle/oradata/ORCLCDB/PDB3/temp01.dbf

Showing the Services Associated with PDBs


COLUMN NETWORK_NAME FORMAT A30
COLUMN PDB FORMAT A15
COLUMN CON_ID FORMAT 999
SELECT PDB, NETWORK_NAME, CON_ID FROM CDB_SERVICES
WHERE PDB IS NOT NULL AND CON_ID > 2
ORDER BY PDB;

PDB NETWORK_NAME CON_ID


--------------- ------------------------------ ------
PDB1 pdb1 3
PDB3 pdb3 4

Viewing the History of PDBs


COLUMN DB_NAME FORMAT A10
COLUMN CON_ID FORMAT 999
COLUMN PDB_NAME FORMAT A15
COLUMN OPERATION FORMAT A16
COLUMN OP_TIMESTAMP FORMAT A10

Ahmed Fathi - Senior Oracle Consultant P a g e | 30


Email: ahmedf.dba@gmail.com Blog: http://ahfathi.blogspot.com LinkedIn: http://linkedin.com/in/ahmedfathieg
Oracle Multitenant 12c

COLUMN CLONED_FROM_PDB_NAME FORMAT A15


SELECT DB_NAME, CON_ID, PDB_NAME, OPERATION, OP_TIMESTAMP, CLONED_FROM_PDB_NAME
FROM CDB_PDB_HISTORY
WHERE CON_ID > 2
ORDER BY CON_ID;

DB_NAME CON_ID PDB_NAME OPERATION OP_TIMESTA CLONED_FROM_PDB


---------- ------ --------------- ---------------- ---------- ---------------
SEEDDATA 3 PDB$SEED UNPLUG 24-MAY-13
ORCLCDB 3 PDB$SEED PLUG 22-JUN-14 PDB$SEED
ORCLCDB 3 PDB1 CREATE 22-JUN-14 PDB$SEED
SEEDDATA 4 PDB$SEED UNPLUG 24-MAY-13
ORCLCDB 4 PDB3 CLONE 22-JUN-14 PDB1
ORCLCDB 4 PDB1 CREATE 22-JUN-14 PDB$SEED
ORCLCDB 4 PDB$SEED PLUG 22-JUN-14 PDB$SEED

Thank You 
Ahmed Fathi

Ahmed Fathi - Senior Oracle Consultant P a g e | 31


Email: ahmedf.dba@gmail.com Blog: http://ahfathi.blogspot.com LinkedIn: http://linkedin.com/in/ahmedfathieg
Oracle Multitenant 12c

Resources
Oracle® Database Administrator's Guide 12c Release 1 (12.1) - E17636-21 - Oracle 12c Documentation
Oracle Database 12c: Managing Multitenant Architecture - D79128GC10 - Oracle Education
Pro Oracle Database 12c Administration, 2nd Edition – Darl Kuhm
Oracle Multitenant White Paper - Bryn Llewellyn

Ahmed Fathi - Senior Oracle Consultant P a g e | 32


Email: ahmedf.dba@gmail.com Blog: http://ahfathi.blogspot.com LinkedIn: http://linkedin.com/in/ahmedfathieg

You might also like