A partire dalla versione 12c Release 1, Oracle ha introdotto la option del Multitenant che rappresenta sicuramente uno dei più grandi cambiamenti di architettura nella storia del database Oracle.
Il Multitenant permette di gestire in modo più efficace ed efficiente i database in nostra gestione e anche le risorse hardware a nostra disposizione. Nell’architettura multitenant, il database come noi lo conosciamo sarà inglobato all’interno del container che rappresenterà il punto di ingresso per gestire i singoli pluggable database in termini di start/stop, tuning e backup; inoltre, questa opzione consente di semplificare la manutenzione dei database come se fosse uno solo quando sarà necessario aggiornare il software.
In termini di risorse hardware, ci sarà un importante risparmio sulle risorse utilizzate: in un'architettura standard ciascun database ha i propri processi di background e la propria memoria (SGA) oltre ai dati, mentre in architettura multitenant i processi di background e la SGA saranno del root container e i pluggable database avranno esclusivamente i dati.
Un altro importante vantaggio di questa architettura è la portabilità dei pluggable database, che possono essere spostati tra diversi container con poche operazioni di gestione ma con grandi vantaggi in termini di fermi applicativi.
Architettura Multitenant
Questa option si basa su due concetti fondamentali, il Container Database (CDB) e il Pluggable Database (PDB). Il CDB è molto simile a un database Oracle convenzionale, poiché contiene la maggior parte delle strutture di base di un database tradizionale cioè controlfile, datafile, undo, tempfile, redo log, etc. Ospita inoltre il dizionario dati per gli oggetti di proprietà del root container e quelli visibili a tutti i PDB. Un Pluggable Database (PDB) rappresenta un database utente isolato all'interno di un CDB. Ogni PDB ha i propri oggetti di schema, utenti, e dati, garantendo isolamento e indipendenza. Questo permette agli amministratori di gestire ogni PDB come se fosse un database separato.
Da Oracle 12.2 in poi, un PDB può e dovrebbe avere un suo undo tablespace proprietario.

L’architettura sopra può essere ulteriormente arricchita da un secondo livello che si frappone tra root container, il cdb$root e i vari pdb introducendo gli application container, ossia un raggruppamento logico di database che afferiscono alla stessa applicazione.
Non terremo conto, nel prosieguo di questo articolo, dell’application container in quanto non necessario per descrivere le peculiarità dell’architettura dei container.
Concetti base
Container Database (CDB)
Un Container Database (CDB) è il componente principale dell'architettura multitenant. Contiene uno o più Pluggable Databases (PDB) e include il “root container” (CDB$ROOT) e, opzionalmente, un “seed container” (PDB$SEED) per creare nuovi PDB.
Pluggable Database (PDB)
Un Pluggable Database (PDB) rappresenta un database utente isolato all'interno di un CDB. Ogni PDB ha i propri oggetti di schema, utenti e dati, garantendo isolamento e indipendenza. Questo permette agli amministratori di gestire ogni PDB come se fosse un database separato.
Root Container (CDB$ROOT)
Il root container è l'entità primaria del CDB, contenente metadati e informazioni comuni condivise tra tutti i PDB. Non contiene dati applicativi ma fornisce un ambiente per le operazioni amministrative comuni.
Seed Container (PDB$SEED)
Il seed container è un modello predefinito utilizzato per creare nuovi PDB. Questo consente una rapida implementazione di nuovi database senza dover configurare manualmente ogni PDB da zero.
Operazioni principali
Un CDB può essere creato utilizzando Oracle Database Configuration Assistant (DBCA) o tramite script SQL. Durante la creazione, viene configurato il seed container per facilitare l'aggiunta di nuovi PDB.

Creazione e gestione di PDB
Creazione di un PDB
Può essere effettuata clonando il PDB$SEED o un altro PDB esistente.
Il grafico sotto mostra le possibili modalità con cui può essere creato un PDB:

Entriamo nel dettaglio di alcune delle metodologie sopra elencate.
Creazione da Scratch (pdb$seed)

CDB1 $ sqlplus sys@cdb1 sys AS sysdba SQL >
ALTER SYSTEM
SET db_create_file_dest = '/u01/app/oracle/oradata';
SQL >
CREATE PLUGGABLE DATABASE pdb1 ADMIN USER pdb1adm IDENTIFIED BY * * * * * * *;
OR
SQL >
CREATE PLUGGABLE DATABASE pdb1 ADMIN USER pdb1adm IDENTIFIED BY * * * * * * * 2 CREATE_FILE_DEST = '/u01/app/oracle/oradata';
OR
SQL >
CREATE PLUGGABLE DATABASE repotestpdb ADMIN USER pdbadm IDENTIFIED BY * * * * * * * FILE_NAME_CONVERT = (
'/u01/app/oracle/oradata/cdb1/pdbseed/'
,'/u01/app/oracle/oradata/cdb1/pdb2/'
);
OR
SQL >
ALTER SESSION
SET PDB_FILE_NAME_CONVERT = '/u01/app/oracle/oradata/cdb1/pdbseed/'
,'/u01/app/oracle/oradata/cdb1/pdb3/';
SQL >
CREATE PLUGGABLE DATABASE pdb3 ADMIN USER pdb_adm IDENTIFIED BY Password1 ROLES = (DBA);
CDB1 $ sqlplus sys@cdb1 sys AS sysdba SQL >
ALTER SYSTEM
SET db_create_file_dest = '/u01/app/oracle/oradata';
SQL >
CREATE PLUGGABLE DATABASE pdb1 ADMIN USER pdb1adm IDENTIFIED BY * * * * * * *;
OR
SQL >
CREATE PLUGGABLE DATABASE pdb1 ADMIN USER pdb1adm IDENTIFIED BY * * * * * * * 2 CREATE_FILE_DEST = '/u01/app/oracle/oradata';
OR
SQL >
CREATE PLUGGABLE DATABASE repotestpdb ADMIN USER pdbadm IDENTIFIED BY * * * * * * * FILE_NAME_CONVERT = (
'/u01/app/oracle/oradata/cdb1/pdbseed/'
,'/u01/app/oracle/oradata/cdb1/pdb2/'
);
OR
SQL >
ALTER SESSION
SET PDB_FILE_NAME_CONVERT = '/u01/app/oracle/oradata/cdb1/pdbseed/'
,'/u01/app/oracle/oradata/cdb1/pdb3/';
SQL >
CREATE PLUGGABLE DATABASE pdb3 ADMIN USER pdb_adm IDENTIFIED BY Password1 ROLES = (DBA);
2.
Clonazione da altro PDB locale

CDB1 $ sqlplus sys@cdb1 sys AS sysdba SQL >
ALTER PLUGGABLE DATABASE PDB1
CLOSE;
SQL >
ALTER PLUGGABLE DATABASE PDB1
OPEN READ ONLY;
SQL >
CREATE PLUGGABLE DATABASE PDB2
FROM PDB1 STORAGE UNLIMITED TEMPFILE REUSE FILE_NAME_CONVERT = (
'/u01/app/oracle/oradata/cdb1/pdb1/'
,'/u01/app/oracle/oradata/cdb1/pdb2'
);
PDB IN LOCAL UNDO MODE – CLONAZIONE A CALDO SQL >
CREATE PLUGGABLE DATABASE PDB3
FROM PDB1 STORAGE UNLIMITED TEMPFILE REUSE FILE_NAME_CONVERT = (
'/u01/app/oracle/oradata/cdb1/pdb1/'
,'/u01/app/oracle/oradata/cdb1/pdb3'
);
CDB1 $ sqlplus sys@cdb1 sys AS sysdba SQL >
ALTER PLUGGABLE DATABASE PDB1
CLOSE;
SQL >
ALTER PLUGGABLE DATABASE PDB1
OPEN READ ONLY;
SQL >
CREATE PLUGGABLE DATABASE PDB2
FROM PDB1 STORAGE UNLIMITED TEMPFILE REUSE FILE_NAME_CONVERT = (
'/u01/app/oracle/oradata/cdb1/pdb1/'
,'/u01/app/oracle/oradata/cdb1/pdb2'
);
PDB IN LOCAL UNDO MODE – CLONAZIONE A CALDO SQL >
CREATE PLUGGABLE DATABASE PDB3
FROM PDB1 STORAGE UNLIMITED TEMPFILE REUSE FILE_NAME_CONVERT = (
'/u01/app/oracle/oradata/cdb1/pdb1/'
,'/u01/app/oracle/oradata/cdb1/pdb3'
);
3.
Clonazione da PDB remoto

CDB1 $ sqlplus sys@cdb1 sys AS sysdba SQL >
CREATE USER c##remote_clone_user IDENTIFIED BY remote_clone_user CONTAINER = ALL;
SQL >
GRANT CREATE SESSION
,CREATE PLUGGABLE DATABASE
TO c##remote_clone_user CONTAINER = ALL;
SQL >
SELECT property_name
,property_value
FROM database_properties
WHERE property_name = 'LOCAL_UNDO_ENABLED';
PROPERTY_NAME PROPERTY_VALUE
LOCAL_UNDO_ENABLED TRUE CDB2 $ sqlplus sys@cdb2 sys AS sysdba SQL >
CREATE DATABASE LINK clone_link CONNECT TO c##remote_clone_user IDENTIFIED BY remote_clone_user USING 'CDB1';
SQL >
CREATE PLUGGABLE DATABASE PDB1CLONE
FROM PDB1@clone_link;
SQL >
SELECT name
,open_mode
FROM v$pdbs
WHERE name = 'PDB1CLONE';
NAME OPEN_MODE
PDB1CLONE MOUNTED
CDB1 $ sqlplus sys@cdb1 sys AS sysdba SQL >
CREATE USER c##remote_clone_user IDENTIFIED BY remote_clone_user CONTAINER = ALL;
SQL >
GRANT CREATE SESSION
,CREATE PLUGGABLE DATABASE
TO c##remote_clone_user CONTAINER = ALL;
SQL >
SELECT property_name
,property_value
FROM database_properties
WHERE property_name = 'LOCAL_UNDO_ENABLED';
PROPERTY_NAME PROPERTY_VALUE
LOCAL_UNDO_ENABLED TRUE CDB2 $ sqlplus sys@cdb2 sys AS sysdba SQL >
CREATE DATABASE LINK clone_link CONNECT TO c##remote_clone_user IDENTIFIED BY remote_clone_user USING 'CDB1';
SQL >
CREATE PLUGGABLE DATABASE PDB1CLONE
FROM PDB1@clone_link;
SQL >
SELECT name
,open_mode
FROM v$pdbs
WHERE name = 'PDB1CLONE';
NAME OPEN_MODE
PDB1CLONE MOUNTED
4. Clonazione da Non-PDB remoto
DB19C NON - CDB $ sqlplus sys@db19c sys AS sysdba SQL >
CREATE USER c##remote_clone_user IDENTIFIED BY remote_clone_user;
SQL >
GRANT CREATE SESSION
,CREATE PLUGGABLE DATABASE
TO c##remote_clone_user;
SQL >
SELECT log_mode
FROM v$database;
LOG_MODE
ARCHIVELOG CDB1 $ sqlplus sys@cdb1 sys AS sysdba SQL >
CREATE DATABASE LINK clone_link CONNECT TO c##remote_clone_user IDENTIFIED BY remote_clone_user USING 'DB19C';
SQL >
CREATE PLUGGABLE DATABASE DB19CPDB
FROM NON$CDB@clone_link;
SQL >
SELECT name
,open_mode
FROM v$pdbs
WHERE name = 'DB19CPDB';
NAME OPEN_MODE
DB19CPDB MOUNTED
DB19C NON - CDB $ sqlplus sys@db19c sys AS sysdba SQL >
CREATE USER c##remote_clone_user IDENTIFIED BY remote_clone_user;
SQL >
GRANT CREATE SESSION
,CREATE PLUGGABLE DATABASE
TO c##remote_clone_user;
SQL >
SELECT log_mode
FROM v$database;
LOG_MODE
ARCHIVELOG CDB1 $ sqlplus sys@cdb1 sys AS sysdba SQL >
CREATE DATABASE LINK clone_link CONNECT TO c##remote_clone_user IDENTIFIED BY remote_clone_user USING 'DB19C';
SQL >
CREATE PLUGGABLE DATABASE DB19CPDB
FROM NON$CDB@clone_link;
SQL >
SELECT name
,open_mode
FROM v$pdbs
WHERE name = 'DB19CPDB';
NAME OPEN_MODE
DB19CPDB MOUNTED
Plug-in e unplug
I PDB possono essere spostati tra CDB diversi con operazioni di plug-in e unplug.

UNPLUG SQL > CONNECT SYS@CDB1 AS SYSDBA SQL >
ALTER PLUGGABLE DATABASE pdb1
CLOSE;
SQL >
ALTER PLUGGABLE DATABASE pdb1 UNPLUG
INTO '/u01/app/oracle/oradata/cdb1/pdb1/pdb1.xml';
OR
SQL >
ALTER PLUGGABLE DATABASE pdb1 UNPLUG
INTO '/u01/app/oracle/oradata/cdb1/pdb1/pdb1.pdb';
PLUG - IN SQL > CONNECT SYS@CDB2 AS sysdba SQL >
CREATE PLUGGABLE DATABASE pdb2 USING '/u01/app/oracle/oradata/cdb2/pdb2/pdb1.xml' FILE_NAME_CONVERT = (
'/u01/app/oracle/oradata/cdb1/pdb1/'
,'/u01/app/oracle/oradata/cdb2/pdb2/'
);
OR
SQL >
CREATE PLUGGABLE DATABASE pdb2 USING '/u01/app/oracle/oradata/cdb2/pdb2/pdb1.pdb' FILE_NAME_CONVERT = (
'/u01/app/oracle/oradata/cdb1/pdb1/'
,'/u01/app/oracle/oradata/cdb2/pdb2/'
);
SQL >
ALTER PLUGGABLE DATABASE pdb2
OPEN READ WRITE;
UNPLUG SQL > CONNECT SYS@CDB1 AS SYSDBA SQL >
ALTER PLUGGABLE DATABASE pdb1
CLOSE;
SQL >
ALTER PLUGGABLE DATABASE pdb1 UNPLUG
INTO '/u01/app/oracle/oradata/cdb1/pdb1/pdb1.xml';
OR
SQL >
ALTER PLUGGABLE DATABASE pdb1 UNPLUG
INTO '/u01/app/oracle/oradata/cdb1/pdb1/pdb1.pdb';
PLUG - IN SQL > CONNECT SYS@CDB2 AS sysdba SQL >
CREATE PLUGGABLE DATABASE pdb2 USING '/u01/app/oracle/oradata/cdb2/pdb2/pdb1.xml' FILE_NAME_CONVERT = (
'/u01/app/oracle/oradata/cdb1/pdb1/'
,'/u01/app/oracle/oradata/cdb2/pdb2/'
);
OR
SQL >
CREATE PLUGGABLE DATABASE pdb2 USING '/u01/app/oracle/oradata/cdb2/pdb2/pdb1.pdb' FILE_NAME_CONVERT = (
'/u01/app/oracle/oradata/cdb1/pdb1/'
,'/u01/app/oracle/oradata/cdb2/pdb2/'
);
SQL >
ALTER PLUGGABLE DATABASE pdb2
OPEN READ WRITE;
Rimuovere un PDB

SQL > CONNECT sys@CDB1 AS SYSDBA SQL >
ALTER PLUGGABLE DATABASE pdb1
CLOSE;
SQL >
DROP PLUGGABLE DATABASE PDB1 INCLUDING DATAFILES;
OR
SQL >
DROP PLUGGABLE DATABASE PDB1 KEEP DATAFILES;
SQL > CONNECT sys@CDB1 AS SYSDBA SQL >
ALTER PLUGGABLE DATABASE pdb1
CLOSE;
SQL >
DROP PLUGGABLE DATABASE PDB1 INCLUDING DATAFILES;
OR
SQL >
DROP PLUGGABLE DATABASE PDB1 KEEP DATAFILES;
Backup e ripristino
Possono essere eseguiti separatamente per ogni PDB, garantendo flessibilità.
Backup CDB
RMAN > CONNECT TARGET SYS@CDB1 RMAN >
BACKUP DATABASE PLUS ARCHIVELOG;
Backup Pluggable Database
RMAN > CONNECT TARGET SYS@CDB1 RMAN >
BACKUP PLUGGABLE DATABASE pdb1;
RMAN >
BACKUP PLUGGABLE DATABASE pdb1
,pdb2
,pdb3;
Point in Time Recovery
RMAN >
ALTER PLUGGABLE DATABASE pdb5
CLOSE;
RMAN > run {
SET UNTIL SCN 1066;
RESTORE PLUGGABLE DATABASE pdb5;
RECOVER PLUGGABLE DATABASE pdb5;
} RMAN >
ALTER PLUGGABLE DATABASE pdb5
OPEN RESETLOGS;
Backup CDB
RMAN > CONNECT TARGET SYS@CDB1 RMAN >
BACKUP DATABASE PLUS ARCHIVELOG;
Backup Pluggable Database
RMAN > CONNECT TARGET SYS@CDB1 RMAN >
BACKUP PLUGGABLE DATABASE pdb1;
RMAN >
BACKUP PLUGGABLE DATABASE pdb1
,pdb2
,pdb3;
Point in Time Recovery
RMAN >
ALTER PLUGGABLE DATABASE pdb5
CLOSE;
RMAN > run {
SET UNTIL SCN 1066;
RESTORE PLUGGABLE DATABASE pdb5;
RECOVER PLUGGABLE DATABASE pdb5;
} RMAN >
ALTER PLUGGABLE DATABASE pdb5
OPEN RESETLOGS;
Dopo questa panoramica sull'architettura e le operazioni principali, nel prossimo articolo vedremo come gestire aggiornamenti e patch e come si amministra un ambiente multitenant.
di Anna Bruno, pubblicato il 7 novembre 2025