Clonación en Caliente de una Pluggable Database (PDB) en Ambiente Multi-Tenant con Oracle Database 12c R2.

Introducción:
Oracle Database 12c R2 ahora permite clonar en caliente las PDBs (HOT CLONE). Con esta funcionalidad una PDB puede ser clonada mientras esta online y ejecutando transacciones. Esto da una gran flexibilidad para generar ambientes de desarrollo desde la base de datos de producción mientras se mantiene la alta disponibilidad por la que Oracle es conocida. Esta funcionalidad puede ser usada para clonar una PDB que existe dentro del mismo CDB, en diferente CDB y desde una No-CDB local o remota, mientras todas las bases de datos sean Oracle Database 12c R2, estén en modo ARCHIVELOG y tengan LOCAL UNDO habilitado.
Configuración del Ambiente
Sistema Origen:

Operating System:           Oracle Enterprise Linux 6.8 (Santiago)
Database:                   Oracle Database 12c R2 (12.2.0.1.0)
Oracle Clusterware:         Oracle Clusterware 12c R2 (12.2.0.1.0)
Hostnames:                  tstldb101,tstldb102
IP addresses:               192.168.0.61, 192.168.0.62
Cluster Name:               TSTLDB01
Container Database (CDB):   PRODCDB
Pluggable Database (PDB):   PRODPDB

Sistema Destino:
Operating System:           Oracle Enterprise Linux 6.6 (Santiago)
Database:                   Oracle Database 12c R2 (12.2.0.1.0)
Oracle Clusterware:         Oracle Clusterware 12c R2 (12.2.0.1.0)
Hostname:                   tstldb201,tstldb202
IP addresses:               192.168.0.68, 192.168.0.69
Cluster Name:               TSTLDB02
Container Database (CDB):   DEVCDB
Pluggable Database (PDB):   DEVPDB (Esta PDB se crea en este artículo)

En este artículo vamos a crear la Pluggable Database DEVPDB en el Container Database DEVCDB del Cluster TSTLDB02 desde la Pluggable Database PROPDB que esta en el Container Database PRODCDB de otro Cluster TSTLDB01.
La ejecución del proceso del clonado de la PDB en caliente lo hacemos desde el Sistema Destino por eso para los propósitos de este artículo la designación local se refiere al cluster TSTLDB02 y la designación remoto refiere a TSTLDB01. Mientras lees este artículo recuerda entonces que remoto es el origen y local es el destino donde la nueva PDB será creada via el proceso de clonación.
Nos aseguramos que ambos CDB's estan en modo ARCHIVELOG con LOCAL_UNDO
Loguearse al Container Database origen (PRODCDB)
SQL> select name, log_mode from v$database;

NAME                 LOG_MODE
---------------     -------------------
PRODCDB              ARCHIVELOG

SQL> col property_value format a10
SQL> col property_name format a30
SQL> select property_name, PROPERTY_VALUE from database_properties 
where property_name = 'LOCAL_UNDO_ENABLED';

PROPERTY_NAME                      PROPERTY_V
------------------------------    --------------------
LOCAL_UNDO_ENABLED                 TRUE

Loguearse al Container Database destino (DEVCDB)
SQL> select name, log_mode from v$database;

NAME                 LOG_MODE
---------------     -------------------------
DEVCDB               ARCHIVELOG

SQL> col property_value format a10
SQL> col property_name format a30
SQL> select property_name, PROPERTY_VALUE from database_properties 
where property_name = 'LOCAL_UNDO_ENABLED';

PROPERTY_NAME                      PROPERTY_V
------------------------------    ---------------------
LOCAL_UNDO_ENABLED                 TRUE

Configurar las entradas en TNS
Vamos a requerir entradas en el TNS del Sistema Destino (en ambos nodos) el cual referencia a la PDB remota, PRODPDB. Estan sobreiluminadas las lineas relevantes.
[oracle@tstldb201 ~]$ cat /u01/app/oracle/product/12.2.0/dbhome_1/network/admin/tnsnames.ora
# tnsnames.ora Network Configuration File: /u01/app/oracle/product/12.2.0/dbhome_1/network/admin/tnsnames.ora
# Generated by Oracle configuration tools.

DEVCDB =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = tstldb02-scan)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = devcdb.world)
    )
  )

 PRODPDB =   (DESCRIPTION =     (ADDRESS = (PROTOCOL = TCP)(HOST = tstldb01-scan)(PORT = 1521))  
     (CONNECT_DATA =       (SERVER = DEDICATED)       (SERVICE_NAME = prodpdb.world)     )   ) 


[oracle@tstldb201 ~]$ ssh tstldb202 "cat /u01/app/oracle/product/12.2.0/dbhome_1/network/admin/tnsnames.ora "
# tnsnames.ora.tstldb202 

Network Configuration File: /u01/app/oracle/product/12.2.0/dbhome_1/network/admin/tnsnames.ora.tstldb202
# Generated by Oracle configuration tools.

DEVCDB =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = tstldb02-scan)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = devcdb.world)
    )
  )

 PRODPDB =   (DESCRIPTION =     (ADDRESS = (PROTOCOL = TCP)(HOST = tstldb01-scan)(PORT = 1521))   
    (CONNECT_DATA =       (SERVER = DEDICATED)       (SERVICE_NAME = prodpdb.world)     )   )   

Configurar un Common User
Ahora, necesitamos crear un Common User en el CDB remoto, PRODCDB. Lo hacemos desde el primer nodo en cluster TSTLDB01.
[oracle@tstldb101 database]$ . oraenv
ORACLE_SID = [oracle] ? prodcdb1
The Oracle base remains unchanged with value /u01/app/oracle

[oracle@tstldb101 database]$ sqlplus / as sysdba
SQL*Plus: Release 12.2.0.1.0 Production on Mon Mar 13 23:43:07 2017
Copyright (c) 1982, 2016, Oracle.  All rights reserved.
Connected to:
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production

SQL> create user c##pdb_hotcloner identified by "database_123" container=all;
User created.

SQL> grant dba to c##pdb_hotcloner container=all;
Grant succeeded.

Crear un Database Link
Creamos un Database Link Público en el contenedor CDB$ROOT de DEVCDB para conectarnos a la PDB, PROPDB. Luego validamos el DB_LINK consultando las vistas GV$DATABASE y GV$CONTAINERS, además verificamos que la PDB origen remota esta en modo READ WRITE.
[oracle@tstldb201 ~]$ . oraenv
ORACLE_SID = [oracle] ? devcdb1
The Oracle base remains unchanged with value /u01/app/oracle

[oracle@tstldb201 ~]$ sqlplus / as sysdba
SQL*Plus: Release 12.2.0.1.0 Production on Mon Mar 13 23:46:52 2017
Copyright (c) 1982, 2016, Oracle.  All rights reserved.
Connected to:
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production

SQL> create public database link SOURCE connect to c##pdb_hotcloner identified by "database_123" using 'PRODPDB';

Database link created.

SQL> select inst_id,name,open_mode from gv$database@source;

INST_ID       NAME              OPEN_MODE
----------  ---------------   --------------------
2             PRODCDB           READ WRITE
1             PRODCDB           READ WRITE

SQL> col name format a15
SQL> select inst_id,name,open_mode from gv$containers@source;

INST_ID       NAME              OPEN_MODE
----------  ---------------   ----------------------
1             PRODPDB           READ WRITE
2             PRODPDB           READ WRITE

Clonar en Caliente la PDB Remota
Antes de comenzar la clonación revisamos los containers disponibles en cada CDB para mostrar que no hay otra PDB que no sea PDB$SEED en el CDB, DEVCDB.
Nos logueamos en el Container Database - PRODCDB
SQL> select name from v$database;

NAME
---------------
PRODCDB

SQL> select name from v$containers;

NAME
-------------------
CDB$ROOT
PDB$SEED
PRODPDB

Nos logueamos en el Container Database - DEVCDB
SQL> select name from v$database;

NAME
---------------
DEVCDB

SQL> select name from v$containers;

NAME
---------------
CDB$ROOT
PDB$SEED

Ahora comenzamos la clonación desde el contenedor CDB$ROOT de DEVCDB y referenciando al DB_LINK SOURCE que nos conecta a PRODPDB de PRODCDB en el Cluster TSTLDB01.
SQL> create pluggable database devpdb from prodpdb@source;
Pluggable database created.

Analizar el Progreso del Proceso de Clonación
Analizamos el progreso de la Clonación en Caliente de la PDB Hot Clone consultando la v$session_longops en la PDB remota (origen).
SQL> select message from v$session_longops;

MESSAGE
-----------------------------------------------------
kpdbfCopyTaskCbk: +DATA/PRODCDB/4AA8F71F10B96DB0E0 : 
12800 out of 12800 Blocks done

kpdbfCopyTaskCbk: +DATA/PRODCDB/4AA8F71F10B96DB0E0 : 
44800 out of 44800 Blocks done

kpdbfCopyTaskCbk: +DATA/PRODCDB/4AA8F71F10B96DB0E0 : 
32000 out of 32000 Blocks done

Al finalizar vemos la PDB clonada, y las instancias 
quedan en estado MOUNTED.

SQL> select inst_id, name, open_mode from gv$containers 
where name = 'DEVPDB';

INST_ID       NAME                OPEN_MODE
----------  ---------------     --------------------
1             DEVPDB              MOUNTED
2             DEVPDB              MOUNTED

Nos logueamos al Container Database - DEVCDB
[oracle@tstldb201 ~]$ . oraenv
ORACLE_SID = [oracle] ? devcdb1
The Oracle base remains unchanged with value /u01/app/oracle

[oracle@tstldb201 ~]$ sqlplus / as sysdba
SQL*Plus: Release 12.2.0.1.0 Production on Tue Mar 14 00:09:19 2017
Copyright (c) 1982, 2016, Oracle.  All rights reserved.
Connected to:
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production

SQL> alter pluggable database DEVPDB open read write instances=ALL;
Pluggable database altered.

SQL> col name format a15
SQL> select inst_id, name, open_mode from gv$containers where name = 'DEVPDB';

INST_ID       NAME                OPEN_MODE
----------  ---------------     --------------------
1             DEVPDB              READ WRITE
2             DEVPDB              READ WRITE

Verificar la ubicación de los Datafiles en ambas PDBs.
Origen (PRODPDB de PRODCDB)
[oracle@tstldb101 trace]$ . oraenv
ORACLE_SID = [prodcdb1] ? prodcdb1
The Oracle base remains unchanged with value /u01/app/oracle

[oracle@tstldb101 trace]$ sqlplus / as sysdba
SQL*Plus: Release 12.2.0.1.0 Production on Tue Mar 14 
00:05:43 2017

Copyright (c) 1982, 2016, Oracle.  All rights reserved.
Connected to:

Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 
- 64bit Production

SQL> alter session set container = PRODPDB;
Session altered.

SQL> col name format a100
SQL> select name from v$datafile;

NAME
---------------------------------------------------------
+DATA/PRODCDB/4AA8F71F10B96DB0E0533D00A8C0638A/DATAFILE/
system.274.938559389

+DATA/PRODCDB/4AA8F71F10B96DB0E0533D00A8C0638A/DATAFILE/
sysaux.275.938559389

+DATA/PRODCDB/4AA8F71F10B96DB0E0533D00A8C0638A/DATAFILE/
undotbs1.273.938559389

+DATA/PRODCDB/4AA8F71F10B96DB0E0533D00A8C0638A/DATAFILE/
undo_2.277.938559471

+DATA/PRODCDB/4AA8F71F10B96DB0E0533D00A8C0638A/DATAFILE/
users.278.938559493


Destino (DEVPDB de DEVCDB)
[oracle@tstldb201 ~]$ . oraenv
ORACLE_SID = [oracle] ? devcdb1
The Oracle base remains unchanged with value /u01/app/
oracle

[oracle@tstldb201 ~]$ sqlplus / as sysdba
SQL*Plus: Release 12.2.0.1.0 Production on Mon Mar 13 
23:46:52 2017
Copyright (c) 1982, 2016, Oracle.  All rights reserved.
Connected to:
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 
- 64bit Production

SQL> alter session set container = DEVPDB;
Session altered.

SQL> col name format a100
NAME
----------------------------------------------------------
+DATA/DEVCDB/4AA9B457CD025F7BE0534400A8C0C831/DATAFILE/
system.289.938563067

+DATA/DEVCDB/4AA9B457CD025F7BE0534400A8C0C831/DATAFILE/
sysaux.288.938563067

+DATA/DEVCDB/4AA9B457CD025F7BE0534400A8C0C831/DATAFILE/
undotbs1.296.938563067

+DATA/DEVCDB/4AA9B457CD025F7BE0534400A8C0C831/DATAFILE/
undo_2.290.938563067

+DATA/DEVCDB/4AA9B457CD025F7BE0534400A8C0C831/DATAFILE/
users.295.938563067


Conclusión
En la version de Oracle Database 12c R2, las pluggable databases son más útiles ya que ahora cuentan con la capacidad de crear PDBs clonadas desde una PDB que esta abierta y en modo READ WRITE. Esto permite que la Base de Datos origen continúe dando servicio, ayuda a que los ambientes de Bases de Datos Oracle sean más ágiles y conduce a desarrollos más ágiles haciendo fácil la clonación de datos de producción para propósitos de pruebas.

Comentarios

Entradas populares de este blog

Installing Oracle GoldenGate for Oracle 12c

Replicación de datos con múltiples procesos "Extract" y "Replicat" con el modo de captura integrada utilizando Oracle GoldenGate 12c

How To Rename ASM Diskgroup With RAC Database