Oracle Database 12c: Uma introdução aos conceitos de backup, recuperação e de recuperação a um ponto no tempo (PITR) de PDBs

Por Alex Zaballa , Yenugula Venkata RaviKumar (OCM) e Nassyam Basha (OCM)
Postado em Março 2015

Revisado por Marcelo Pivovar - Solution Architect

Estimados colegas de tecnologia Oracle sejam bem-vindos a este artigo, o qual servirá de base para os novos conceitos da versão 12c do banco de dados Oracle.
O Oracle Database 12c, no que diz respeito as versões anteriores, mudou radicalmente; ocorreram muitas melhorias no otimizador baseado em custos (CBO), na portabilidade dos bancos de dados, na flexibilidade ao realizar mudanças físicas e lógicas em sua arquitetura, tornando-o adequado a fazer frente ao novo mundo de “Cloud Computing“. A versão 12c introduziu principalmente dois novos conceitos:

  • Banco de Dados do tipo Container (CDB): É um banco de dados que tem a capacidade de armazenar logicamente diversos bancos de dados. Estes bancos de dados internos são chamados de “Pluggable Database (PDB)”.
  • Banco de Dados do tipo “Pluggable” (PDB): Um PDB é um conjunto de esquemas de bancos de dados que são apresentados aos usuários e aplicações como uma representação de um banco de dados separado e independente.

No banco de dados Oracle versão 12c, uma instância está associada a um CBD, isso significa que cada PDB não tem a sua própria instância, mas os "N" PDBs que existem dentro de um CBD compartilham a mesma instância.

Características gerais da versão 12c:

  • Nas versões anteriores ao 12c, todos os bancos de dados são do tipo “non-cdb”.
  • Iniciando na versão 12c, um banco de dados pode ser do tipo Container ou pode continuar sendo “non-cdb”.
  • O banco de dados Oracle 12c suporta a nova arquitetura “multitenant” que permite ter diversos sub bancos de dados dentro de um banco de dados mestre. O banco de dados mestre é do tipo CDB e os sub banco de dados são do tipo PDBs.
  • Um container chamado “ROOT” (CDB$ROOT) possue as “tablespaces” SYSTEM, SYSAUX, UNDO e TEMP e com isso, os controlfiles” e os arquivos de “redo log”.
  • Um container chamado “SEED” (PDB$SEED) possui as “tablespaces” SYSTEM, SYSAUX, TEMP e EXAMPLE, usados como base para criar novos PDBs.
  • Todo CDB sempre possui um SEED e um ROOT.
  • O SEED não pode ser aberto no modo “read-write”.

Características dos PDBs:

  • Os PDBs permitem que os DBAs consolidem um grande número de aplicações de banco de dados em uma única instalação de software.
  • Cada PDB pode manter seus próprios usuários.
  • Um PDB é uma espécie de container que mantém seus dados e o código das aplicações, mantém seus próprios metadados dentro das “tablespaces” SYSTEM, SYSAUX e opcionalmente a TEMP.
  • Cada PDB possui um identificador único dentro do CDB.
  • Um PDB pode ser criado bom base em um SEED.
  • Um PDB pode ser criado com base em um banco de dados non-cdb.
  • É possível criar diversas “tablespaces” dentro de um PDB, mas o PDB sempre usará os “controlfiles”, a “tablespace” de UNDO e os arquivos de “redo logs” do CDB.
  • Os PDBs podem ser removidos de um CDB e logo em seguida plugados em outro CDB.
  • Os dados de “Undo” e “Redo” dos PDBs serão agregados dentro dos arquivos de “redo logs” do CDB. O Oracle Golden Gate 12c foi modificado para que possa entender este tipo de arquivo de “redo log”.

Antes da versão 12c, se existisse um grande número de aplicações  dependentes do banco de dados, deveríamos levar em conta os seguintes fatores:

  • Muitos processos de “background” devido as numerosas instâncias de bancos de dados.
  • Grande quantidade de memória duplicada devido as SGAs de todas as instâncias de bandos de dados.
  • Diversas cópias dos metadados do Oracle (espaço para os diversos dicionários de dados nos diversos bancos de dados)
  • Atualização das versões dos diversos bancos de dados, aumentando o trabalho para os DBAs.
  • Os metadados das informações de negócio eram mesclados com os metadados do Oracle.
  • Multiplos backups e tarefas programadas para os diferentes bancos de dados. 

Vantagens de se usar CDBs e PDBs:

O Oracle 12c trouxe as seguintes vantagens sobre o antigo modo de administrar múltiplas instâncias, mantendo cada uma delas como um banco de dados diferente:

  • O Oracle 12c consolida a utilização de múltiplas instâncias de bancos de dados dentro de uma única, centralizada, evitando que os processos e estruturas de memória  sejam duplicados N vezes, onde N é o número de bancos de dados.
  • O tempo dos DBAs é otimizado para tarefas como atualização de versão e aplicação de patches.
  • Nenhuma alteração nas aplicações é necessária para poder utilizar um PDB, pois é apresentado ao usuário como um banco de dados independente.
  • O provisionamento de bancos de dados é rápido e fácil, por ter opções de “clone, plug e unplug“.
  • Proporciona isolamento, uma vez que os PDBs não compartilham informações entre si, a menos que se utilize um “Database Link“.
  • É totalmente compatível com o Oracle Real Application Clusters (RAC).
  • Em um servidor é preferível criar um maior número de PDBs do que instâncias de bancos de dados.

 

Requisitos para realizar backups e recuperações:

  1. Se estamos criando o banco de dados utilizando o DBCA, então é necessário informar o nome do PDB. Se estamos criando sem a opção "create as container database", é possível omitir a criação do PDB e depois criá-lo manualmente utilizando o seguiente comando:    
  2. SQL> create pluggable database orapdb using 'archivo XML'
    
  3. Quando criamos o banco de dados usando o DBCA, o modo “Archive log” virá desabilitado por default. Com isso, devemos habilitar o modo “Archive log” ou podemos fazer isso manualmente depois do banco criado:
  4. SQL> archive log list
    SQL> shutdown immediate;
    SQL> startup mount;
    SQL> alter database archivelog;
    SQL> alter database open;
    SQL> conn / as sysdba
    SQL> archive log list
    
  5. Habilitar o “Fast Recovery Area” setando um valor para os parâmetros “DB_RECOVERY_FILE_DEST” e “DB_RECOVERY_FILE_DEST_SIZE”.
  6. Os PDBs estarão em modo “mount” quando o CDB é iniciado e o “SEED” estará em modo “READ-ONLY”. É possível criar uma “trigger” para abrir automaticamente os PDBs quando o CDB é inicializado. O “SEED” não pode ser aberto no modo “read-write”. Ou pode-se fazer uso de um recurso presente na versão 12.1.0.2, “Preserving or Discarding the Open Mode of PDBs When the CDB Restarts”
SQL> startup
ORACLE instance started.
Total System Global Area 1653518336 bytes
Fixed Size                  2289016 bytes
Variable Size            1056965256 bytes
Database Buffers          587202560 bytes
Redo Buffers                7061504 bytes
Database mounted.
Database opened.
SQL> select con_id,dbid,name,open_mode,total_size 
from v$pdbs;
CON_ID    DBID          NAME               OPEN_MODE   TOTAL_SIZE
-----------------------------------------------------------------
2         4077192876    PDB$SEED           READ ONLY    283115520
3         3864440897    ORAPDB             MOUNTED              0

SQL> alter session set container=orapdb;
Session altered.
SQL> select name,open_mode from v$database;
NAME      OPEN_MODE
--------------------
ORACDB    MOUNTED

Exemplo:

Criar uma “trigger” para iniciar os PDBs automaticamente.

SQL> CREATE or REPLACE trigger OPEN_PDB after startup on database
  2  begin
  3  execute immediate 'alter pluggable database all open';
  4  end;
  5  /
Trigger created.

Se você tem apenas um PDB, então você pode indicar o nome desse PDB.

SQL> select con_id,dbid,name,open_mode,total_size 
     from v$pdbs;
CON_ID       DBID    NAME                OPEN_MODE  TOTAL_SIZE
-------------------------------------------------------------------
2          4077192876 PDB$SEED            READ ONLY   283115520
3          3864440897 ORAPDB              MOUNTED             0
SQL> alter pluggable database orapdb open;
Pluggable database altered.

Ou você pode abrir todos os PDBs e especificar alguma(s) exeção (ões).

ALTER PLUGGABLE DATABASE ALL EXCEPT pdb1 OPEN;

Realizar um backup de um PDB com o RMAN:

Na versão 12c há um novo privilégio chamado SYSBACKUP que possui todos os privilégios necessários para execução de backups, entretanto, esses backups ainda podem ser realizados utilizando o SYSDBA.

O RMAN pode ser executado conectado ao ROOT ou a um PDB específico. Quando o RMAN se conecta a um PDB específico, todos os comandos estão relacionados com o PDB. Quando RMAN se conecta ao ROOT, todos os comandos serão aplicados a todo o CBD.

Utilizando o comando “REPORT SCHEMA” do  RMAN, é possível identificar os “datafiles” utilizados pelo CDB.

bash-3.2$ rman target sys/free2go@oracdb  RMAN> report schema;

 

Report_schema_cdb.PNG

 

Se você estiver executando o RMAN conectado a um PDB específico e executar o comando "REPORT SCHEMA", você só irá ver os “datafiles" correspondentes a este PDB.

bash-3.2$ rman target sys/free2go@orapdb
RMAN>reportschema;
using target database control file instead of recovery catalog
Report of database schema for database with db_unique_name ORACDB
List of PermanentDatafiles =========================== File Size(MB) Tablespace        RB segs Datafile Name ---- -------- ----------------- ----- -------------------- 8    260      SYSTEM            ***    /u01/app/oracle/oradata/ORACDB/pdb/datafile/system_pdb_01.dbf 9    610      SYSAUX            ***   /u01/app/oracle/oradata/ORACDB/pdb/datafile/sysaux_pdb_01.dbf 10   5        USERS             ***     /u01/app/oracle/oradata/ORACDB/pdb/datafile/users_pdb_01.dbf
List of Temporary Files ======================= File Size(MB) Tablespace Maxsize(MB) Tempfile Name ---- -------- --------- --------- ----------------------- 3    20       TEMP       32767       /u01/app/oracle/oradata/ORACDB/EDE01BFA46E34B11E0437801A8C0821E/ datafile/o1_mf_temp_9c5d7lon_.dbf

Backup de um banco de dados do tipo Container:

É o mesmo procedimento de um backup tradicional, porém na versão 12c, são inclusos todos os PDBs que estão dentro do CDB, incluindo ROOT e SEED. O backup por default ficará na “Fast Recovery Area”, de acordo com o parâmetro “DB_RECOVERY_FILE_DEST” e é necessário assegurar que existe espaço em disco disponível para o backup. Isto pode ser verificado através do parâmetro “DB_RECOVERY_FILE_DEST_SIZE” e com comandos do sistema operacional como o “df”.

RMAN> backup database plus archive log delete input;

Starting backup at 19-DEC-13
current log archived
using channel ORA_DISK_1
channel ORA_DISK_1: starting archived log backup set
channel ORA_DISK_1: specifying archived log(s) in backup set
input archived log thread=1 sequence=6 RECID=1 STAMP=834602253
input archived log thread=1 sequence=7 RECID=2 STAMP=834602274
input archived log thread=1 sequence=8 RECID=3 STAMP=834604238
input archived log thread=1 sequence=9 RECID=4 STAMP=834604771
channel ORA_DISK_1: starting piece 1 at 19-DEC-13
channel ORA_DISK_1: finished piece 1 at 19-DEC-13
piece handle=/u01/app/oracle/fast_recovery_area/ORACDB/backupset/2013_12_19/
o1_mf_annnn_TAG20131219T183931_9c5w0cx5_.bkp 
tag=TAG20131219T183931 comment=NONE
channel ORA_DISK_1: backup set complete, elapsed time: 00:00:01
channel ORA_DISK_1: deleting archived log(s)
archived log file name=/u01/app/oracle/fast_recovery_area/ORACDB/archivelog/2013_12_19/
o1_mf_1_6_9c5sknwc_.arc 
RECID=1 STAMP=834602253
archived log file name=/u01/app/oracle/fast_recovery_area/ORACDB/archivelog/2013_12_19/
o1_mf_1_7_9c5slboc_.arc 
RECID=2 STAMP=834602274
archived log file name=/u01/app/oracle/fast_recovery_area/ORACDB/archivelog/2013_12_19/
o1_mf_1_8_9c5vhpcw_.arc 
RECID=3 STAMP=834604238
archived log file name=/u01/app/oracle/fast_recovery_area/ORACDB/archivelog/2013_12_19/
o1_mf_1_9_9c5w0cpm_.arc 
RECID=4 STAMP=834604771
Finished backup at 19-DEC-13 
Starting backup at 19-DEC-13 using channel ORA_DISK_1 channel ORA_DISK_1: starting full datafile backup set channel ORA_DISK_1: specifying datafile(s) in backup set inputdatafile file number=00001 name=/u01/app/oracle/oradata/ORACDB/datafile/ o1_mf_system_9c5czbgn_.dbf inputdatafile file number=00003 name=/u01/app/oracle/oradata/ORACDB/datafile/ o1_mf_sysaux_9c5cxm60_.dbf inputdatafile file number=00004 name=/u01/app/oracle/oradata/ORACDB/datafile/ o1_mf_undotbs1_9c5d0rvv_.dbf inputdatafile file number=00006 name=/u01/app/oracle/oradata/ORACDB/datafile/ o1_mf_users_9c5d0qoq_.dbf channel ORA_DISK_1: starting piece 1 at 19-DEC-13 channel ORA_DISK_1: finished piece 1 at 19-DEC-13 piece handle=/u01/app/oracle/fast_recovery_area/ORACDB/backupset/2013_12_19/ o1_mf_nnndf_TAG20131219T183933_9c5w0flg_.bkp tag=TAG20131219T183933 comment=NONE channel ORA_DISK_1: backup set complete, elapsed time: 00:00:45 channel ORA_DISK_1: starting full datafile backup set channel ORA_DISK_1: specifying datafile(s) in backup set inputdatafile file number=00009 name=/u01/app/oracle/oradata/ORACDB/pdb/datafile/sysaux_pdb_01.dbf inputdatafile file number=00008 name=/u01/app/oracle/oradata/ORACDB/pdb/datafile/system_pdb_01.dbf inputdatafile file number=00010 name=/u01/app/oracle/oradata/ORACDB/pdb/datafile/users_pdb_01.dbf channel ORA_DISK_1: starting piece 1 at 19-DEC-13 channel ORA_DISK_1: finished piece 1 at 19-DEC-13 piece handle=/u01/app/oracle/fast_recovery_area/ORACDB/EDE01BFA46E34B11E0437801A8C0821E/backupset/2013_12_19/ o1_mf_nnndf_TAG20131219T183933_9c5w1tqp_.bkp tag=TAG20131219T183933 comment=NONE channel ORA_DISK_1: backup set complete, elapsed time: 00:00:25 channel ORA_DISK_1: starting full datafile backup set channel ORA_DISK_1: specifying datafile(s) in backup set inputdatafile file number=00007 name=/u01/app/oracle/oradata/ORACDB/datafile/o1_mf_sysaux_9c5d1gjo_.dbf inputdatafile file number=00005 name=/u01/app/oracle/oradata/ORACDB/datafile/o1_mf_system_9c5d1gkh_.dbf channel ORA_DISK_1: starting piece 1 at 19-DEC-13 channel ORA_DISK_1: finished piece 1 at 19-DEC-13 piece handle=/u01/app/oracle/fast_recovery_area/ORACDB/EDE01310DB1248ADE0437801A8C065D6/backupset/2013_12_19/ o1_mf_nnndf_TAG20131219T183933_9c5w2mz4_.bkp tag=TAG20131219T183933 comment=NONE channel ORA_DISK_1: backup set complete, elapsed time: 00:00:26 Finished backup at 19-DEC-13
Starting backup at 19-DEC-13 current log archived using channel ORA_DISK_1 channel ORA_DISK_1: starting archived log backup set channel ORA_DISK_1: specifying archived log(s) in backup set input archived log thread=1 sequence=10 RECID=5 STAMP=834604869 channel ORA_DISK_1: starting piece 1 at 19-DEC-13 channel ORA_DISK_1: finished piece 1 at 19-DEC-13 piece handle=/u01/app/oracle/fast_recovery_area/ORACDB/backupset/2013_12_19/o1_mf_annnn_TAG20131219T184109_9c5w3fct_.bkp tag=TAG20131219T184109 comment=NONE channel ORA_DISK_1: backup set complete, elapsed time: 00:00:01 channel ORA_DISK_1: deleting archived log(s) archived log file name=/u01/app/oracle/fast_recovery_area/ORACDB/archivelog/2013_12_19/o1_mf_1_10_9c5w3f6z_.arc RECID=5 STAMP=834604869 Finished backup at 19-DEC-13
Starting Control File and SPFILE Autobackup at 19-DEC-13
piece handle=/u01/app/oracle/fast_recovery_area/ORACDB/autobackup/2013_12_19/o1_mf_s_834604870_9c5w3hjt_.bkp comment=NONE Finished Control File and SPFILE Autobackup at 19-DEC-13

Você pode verificar se o backup foi concluído com sucesso utilizando o comando "list backup" no RMAN.

List_backup.PNG

Até agora, foi realizado um backup completo que inclui o CBD e seus PDBs, no entanto, é possível fazer um backup de um PDB específico
 
Backup de um banco de dados do tipo PDB:

Para fazer o backup de um PDB, você pode se conectar com o RMAN a este PDB específico e executar o comando “backup database”. Se a conexão for feita ao PDB e você executar o seguinte comando "backup pluggable database orapdb" irá obter o seguinte erro:
RMAN> backup pluggable database orapdb tag 'PDB_Backup';
Starting backup at 19-DEC-13
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=1 device type=DISK RMAN-00571: =========================================================== RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS =============== RMAN-00571: =========================================================== RMAN-03002: failure of backup command at 12/19/2013 18:56:55 RMAN-07538: Pluggable Database qualifier not allowed when connected to a Pluggable Database

Porém conectado ao CDB:

RMAN> backup pluggable database orapdb tag 'PDB_Backup';
Starting backup at 19-DEC-13 allocated channel: ORA_DISK_1 channel ORA_DISK_1: SID=49 device type=DISK channel ORA_DISK_1: starting full datafile backup set channel ORA_DISK_1: specifying datafile(s) in backup set inputdatafile file number=00009 name=/u01/app/oracle/oradata/ORACDB/pdb/datafile/sysaux_pdb_01.dbf inputdatafile file number=00008 name=/u01/app/oracle/oradata/ORACDB/pdb/datafile/system_pdb_01.dbf inputdatafile file number=00010 name=/u01/app/oracle/oradata/ORACDB/pdb/datafile/users_pdb_01.dbf channel ORA_DISK_1: starting piece 1 at 19-DEC-13 channel ORA_DISK_1: finished piece 1 at 19-DEC-13 piece handle=/u01/app/oracle/fast_recovery_area/ORACDB/EDE01BFA46E34B11E0437801A8C0821E/backupset/2013_12_19/ o1_mf_nnndf_PDB_BACKUP_9c5x3rsf_.bkp tag=PDB_BACKUP comment=NONE channel ORA_DISK_1: backup set complete, elapsed time: 00:00:15 Finished backup at 19-DEC-13 Starting Control File and SPFILE Autobackup at 19-DEC-13 piece handle=/u01/app/oracle/fast_recovery_area/ORACDB/autobackup/2013_12_19/o1_mf_s_834605919_9c5x47y6_.bkp comment=NONE Finished Control File and SPFILE Autobackup at 19-DEC-13
RMAN> list backup tag='PDB_Backup';
List of Backup Sets =================== BS Key  Type LV Size       Device Type Elapsed Time Completion Time ------- ---- -- ---------- ----------- ------------ --------------- 8       Full    681.70M    DISK        00:00:10     19-DEC-13 BP Key: 8   Status: AVAILABLE  Compressed: NO  Tag: PDB_BACKUP Piece Name: /u01/app/oracle/fast_recovery_area/ORACDB/EDE01BFA46E34B11E0437801A8C0821E/backupset/2013_12_19/ o1_mf_nnndf_PDB_BACKUP_9c5x3rsf_.bkp List of Datafiles in backup set 8 Container ID: 3, PDB Name: ORAPDB File LV Type Ckp SCN   CkpTime  Name ---- -- ---- --------- --------- ---- 8     Full 1752950   19-DEC-13 /u01/app/oracle/oradata/ORACDB/pdb/datafile/system_pdb_01.dbf 9     Full 1752950   19-DEC-13 /u01/app/oracle/oradata/ORACDB/pdb/datafile/sysaux_pdb_01.dbf 10    Full 1752950   19-DEC-13 /u01/app/oracle/oradata/ORACDB/pdb/datafile/users_pdb_01.dbf RMAN>

Na saída acima, você pode ver o identificador e também o nome do PDB. A "TAG" é opcional.

Como se pode observar, o  GUID é mostrado no caminho do backup:

"/u01/app/oracle/fast_recovery_area/ORACDB/EDE01BFA46E34B11E0437801A8C0821E/backupset/2013_12_19/o1_mf_nnndf_PDB_BACKUP_9c5x3rsf_.bkp".

O GUID também pode ser obtido consultando a view v$pdbs:

SQL> select con_id,dbid,guid,name from v$pdbs;
CON_ID  DBID       GUID                              NAME
------- ----------  --------------------------------  ---------         
2       4077192876  EDE01310DB1248ADE0437801A8C065D6  PDB$SEED
3      3864440897  EDE01BFA46E34B11E0437801A8C0821E  ORAPDB

Toda esta informação está relacionada com backups completos do PDB.

Você também pode executar backups parciais de um PDB, por exemplo, de um “datafile” ou de um “tablespace”. Para realizar um backup de um “datafile”, não há nenhuma mudança na versão 12c, mas para fazer o backup de um “tablespace”, é necessário adiconar o nome do PDB, como mostrado nos exemplos a seguir:

RMAN> backup datafile 2,10; 
RMAN> backup tablespaceorapdb:users tag='PDB_users_TBS';
 Starting backup at 19-DEC-13
 using target database control file instead of recovery catalog
 allocated channel: ORA_DISK_1
 channel ORA_DISK_1: SID=1 device type=DISK
 channel ORA_DISK_1: starting full datafile backup set
 channel ORA_DISK_1: specifying datafile(s) in backup set
 inputdatafile file number=00010 
name=/u01/app/oracle/oradata/ORACDB/pdb/datafile/users_pdb_01.dbf
 channel ORA_DISK_1: starting piece 1 at 19-DEC-13
 channel ORA_DISK_1: finished piece 1 at 19-DEC-13
 piece handle=/u01/app/oracle/fast_recovery_area/ORACDB/EDE01BFA46E34B11E0437801A8C0821E/
backupset/2013_12_19/o1_mf_nnndf_PDB_USERS_TBS_9c5y6dxb_.bkp tag=PDB_USERS_TBS comment=NONE
 channel ORA_DISK_1: backup set complete, elapsed time: 00:00:01
 Finished backup at 19-DEC-13
Starting Control File and SPFILE Autobackup at 19-DEC-13 piece handle=/u01/app/oracle/fast_recovery_area/ORACDB/autobackup/2013_12_19/o1_mf_s_834607014_9c5y6g2x_.bkp comment=NONE Finished Control File and SPFILE Autobackup at 19-DEC-13

Recuperação de um PDB com o RMAN:

Se houver algum “tablespace” ou “datafile” com problemas que pertença a um PDB, o CDB não será afetado, unicamente o PDB com problemas não estará disponível para ser acessado. Um cenário relacionado com a recuperação de PDB será exibido, mas lembre-se que antes de realizar uma recuperação, você deve garantir que existe um backup.

Simulação da perda de um “datafile” em um PDB:

O cenário abaixo demonstra como restaurar e recuperar um “datafile“.
SQL> alter session set container=orapdb;
Session altered.
SQL> col name for a100
SQL>select file#,name from v$datafile;
FILE#   NAME
--------- -----------------------------------------------------
4       /u01/app/oracle/oradata/ORACDB/datafile/o1_mf_undotbs1_9c5d0rvv_.dbf
8       /u01/app/oracle/oradata/ORACDB/pdb/datafile/system_pdb_01.dbf
9       /u01/app/oracle/oradata/ORACDB/pdb/datafile/sysaux_pdb_01.dbf
10       /u01/app/oracle/oradata/ORACDB/pdb/datafile/users_pdb_01.dbf
SQL> !rm /u01/app/oracle/oradata/ORACDB/pdb/datafile/system_pdb_01.dbf
SQL> !ls -ltr /u01/app/oracle/oradata/ORACDB/pdb/datafile/system_pdb_01.dbf
 ls: /u01/app/oracle/oradata/ORACDB/pdb/datafile/system_pdb_01.dbf: 
No such file or directory
SQL> select file#,error,recover from v$datafile_header;
FILE#  ERROR                REC
-------- -------------------- -----
4                           NO
8    CANNOT OPEN FILE
9                          NO
10                          NO

Quando existem "datafiles" perdidos em um PDB, você pode se conectar ao CBD e executar os comandos necessários para restaurar e recuperar estes arquivos. Note que quando os "datafiles" não estão disponíveis, não é possível fechar o PDB.

RMAN> restore datafile 8;
 Starting restore at 20-DEC-13
 using target database control file instead of recovery catalog
 allocated channel: ORA_DISK_1
 channel ORA_DISK_1: SID=21 device type=DISK
 channel ORA_DISK_1: starting datafile backup set restore
 channel ORA_DISK_1: specifying datafile(s) to restore from backup set
 channel ORA_DISK_1: restoring datafile 00008 to /u01/app/oracle/oradata/ORACDB/pdb/datafile/system_pdb_01.dbf
 channel ORA_DISK_1: reading from backup piece /u01/app/oracle/
 fast_recovery_area/ORACDB/EDE01BFA46E34B11E0437801A8C0821E/backupset/2013_12_20/
o1_mf_nnndf_TAG20131220T110232_9c7oow6q_.bkp
 channel ORA_DISK_1: piece handle=/u01/app/oracle/fast_recovery_area/ORACDB/
EDE01BFA46E34B11E0437801A8C0821E/backupset/2013_12_20/o1_mf_nnndf_TAG20131220T110232_9c7oow6q_.bkp 
 tag=TAG20131220T110232
 channel ORA_DISK_1: restored backup piece 1
 channel ORA_DISK_1: restore complete, elapsed time: 00:00:15
 Finishedrestore at 20-DEC-13

Após concluído o procedimento de restauro do "datafile" corretamente, então você pode executar o comando “recover datafile”.

RMAN> recover datafile 8;
 Starting recover at 20-DEC-13
 using channel ORA_DISK_1
 starting media recovery
 archived log for thread 1 with sequence 20 is already on disk as file 
/u01/app/oracle/fast_recovery_area/ORACDB/archivelog/2013_12_20/o1_mf_1_20_9c7orfgl_.arc
 archived log for thread 1 with sequence 21 is already on disk as file 
/u01/app/oracle/fast_recovery_area/ORACDB/archivelog/2013_12_20/o1_mf_1_21_9c7ph7wj_.arc
 archived log for thread 1 with sequence 22 is already on disk as file 
/u01/app/oracle/fast_recovery_area/ORACDB/archivelog/2013_12_20/o1_mf_1_22_9c7py3bm_.arc
 archived log for thread 1 with sequence 23 is already on disk as file 
/u01/app/oracle/fast_recovery_area/ORACDB/archivelog/2013_12_20/o1_mf_1_23_9c7q9rqr_.arc
 archived log for thread 1 with sequence 24 is already on disk as file 
/u01/app/oracle/fast_recovery_area/ORACDB/archivelog/2013_12_20/o1_mf_1_24_9c7qd7on_.arc
 archived log for thread 1 with sequence 25 is already on disk as file 
/u01/app/oracle/fast_recovery_area/ORACDB/archivelog/2013_12_20/o1_mf_1_25_9c7qyomg_.arc
 archived log for thread 1 with sequence 26 is already on disk as file 
/u01/app/oracle/fast_recovery_area/ORACDB/archivelog/2013_12_20/o1_mf_1_26_9c7rblbd_.arc
 archived log for thread 1 with sequence 27 is already on disk as file 
/u01/app/oracle/fast_recovery_area/ORACDB/archivelog/2013_12_20/o1_mf_1_27_9c7sjr14_.arc
 archived log for thread 1 with sequence 28 is already on disk as file 
/u01/app/oracle/fast_recovery_area/ORACDB/archivelog/2013_12_20/o1_mf_1_28_9c86jnck_.arc
 archived log for thread 1 with sequence 29 is already on disk as file 
/u01/app/oracle/fast_recovery_area/ORACDB/archivelog/2013_12_20/o1_mf_1_29_9c86lowv_.arc
 archived log file name=/u01/app/oracle/fast_recovery_area/ORACDB/archivelog/2013_12_20/
o1_mf_1_20_9c7orfgl_.arc 
thread=1 sequence=20
 archived log file name=/u01/app/oracle/fast_recovery_area/ORACDB/archivelog/2013_12_20/
o1_mf_1_21_9c7ph7wj_.arc 
thread=1 sequence=21
 archived log file name=/u01/app/oracle/fast_recovery_area/ORACDB/archivelog/2013_12_20/
o1_mf_1_22_9c7py3bm_.arc 
thread=1 sequence=22
 archived log file name=/u01/app/oracle/fast_recovery_area/ORACDB/archivelog/2013_12_20/
o1_mf_1_23_9c7q9rqr_.arc 
thread=1 sequence=23
 archived log file name=/u01/app/oracle/fast_recovery_area/ORACDB/archivelog/2013_12_20/
o1_mf_1_24_9c7qd7on_.arc 
thread=1 sequence=24
 archived log file name=/u01/app/oracle/fast_recovery_area/ORACDB/archivelog/2013_12_20/
o1_mf_1_25_9c7qyomg_.arc 
thread=1 sequence=25
 archived log file name=/u01/app/oracle/fast_recovery_area/ORACDB/archivelog/2013_12_20/
o1_mf_1_26_9c7rblbd_.arc 
thread=1 sequence=26
 archived log file name=/u01/app/oracle/fast_recovery_area/ORACDB/archivelog/2013_12_20/
o1_mf_1_27_9c7sjr14_.arc 
thread=1 sequence=27
 media recovery complete, elapsed time: 00:00:02
 Finishedrecover at 20-DEC-13

No exemplo acima, foi realizada a recuperação de um “datafile“ da “tablespace“ SYSTEM. No caso de um "datafile" perdido e que não seja da “tablespace“ SYSTEM, você pode executar os passos abaixo:

RMAN> alter database datafile 10 offline;
 RMAN> restore datafile 10;
 RMAN> recover datafile 10;
 RMAN> alter database datafile 10 online;

Perda de uma “tablespace” em um PDB:

Se você tem vários “datafiles” perdidos para uma "tablespace" é possível restaurar toda a "tablespace" e realizar uma recuperação. No exemplo a seguir uma "tablespace" será criada com o nome de EXAMPLE e em seguida, iremos restaurar e recuperar. A técnica de restauro e recuperação de uma "tablespace" é a mesma se a "tablespace" contém um único ou diversos "datafiles".

SQL> alter session set container=orapdb;
 Session altered.
SQL> create tablespace example
 datafile '/u01/app/oracle/oradata/ORACDB/pdb/example01.dbf'
 size 50m;
 Tablespace created.
SQL> alter tablespace example 
 adddatafile '/u01/app/oracle/oradata/ORACDB/pdb/example02.dbf' size 50m;
 Tablespace altered.
SQL> select file_id,file_name
 fromcdb_data_files
 where tablespace_name = 'EXAMPLE';
FILE_ID   FILE_NAME
-------- -----------------------------------------------        
17        /u01/app/oracle/oradata/ORACDB/pdb/example01.dbf
18        /u01/app/oracle/oradata/ORACDB/pdb/example02.dbf
SQL>!rm /u01/app/oracle/oradata/ORACDB/pdb/example01.dbf
 SQL>!rm /u01/app/oracle/oradata/ORACDB/pdb/example02.dbf
SQL>!ls -ltr /u01/app/oracle/oradata/ORACDB/pdb/example*
 ls: /u01/app/oracle/oradata/ORACDB/pdb/example*: No such file or directory

Uma vez eliminados todos os "datafiles" da “tablespace” EXAMPLE, é realizada uma recuperação da referida "tablespace". Para realizar a recuperação da ”tablespace“, é necessário que ela esteja OFFLINE. O comando “alter tablespace example offline” só funciona quando ainda existem datafiles funcionais. Neste exemplo, vamos eliminar todos os "datafiles", então você precisa usar a cláusula "IMMEDIATE" para colocar a “tablespace” em estado “offline.”

RMAN> alter tablespace example offline immediate;
 Statement processed
RMAN> restore tablespace example;
 Starting restore at 20-DEC-13
 using channel ORA_DISK_1
 creatingdatafile file number=17 name=/u01/app/oracle/oradata/ORACDB/pdb/example01.dbf
 creatingdatafile file number=18 name=/u01/app/oracle/oradata/ORACDB/pdb/example02.dbf
 restore not done; all files read only, offline, or already restored
 Finished restore at 20-DEC-13
 RMAN> recover tablespace example;
 Starting recover at 20-DEC-13
 using channel ORA_DISK_1
 starting media recovery
 archived log for thread 1 with sequence 6 is already on disk as file 
/u01/app/oracle/fast_recovery_area/ORACDB/archivelog/2013_12_20/o1_mf_1_6_9c8htxj2_.arc
 archived log for thread 1 with sequence 7 is already on disk as file 
/u01/app/oracle/fast_recovery_area/ORACDB/archivelog/2013_12_20/o1_mf_1_7_9c8htxvk_.arc
 archived log for thread 1 with sequence 8 is already on disk as file 
/u01/app/oracle/fast_recovery_area/ORACDB/archivelog/2013_12_20/o1_mf_1_8_9c8hv0xq_.arc
 archived log for thread 1 with sequence 9 is already on disk as file 
/u01/app/oracle/fast_recovery_area/ORACDB/archivelog/2013_12_20/o1_mf_1_9_9c8hv0xh_.arc
 archived log file name=/u01/app/oracle/fast_recovery_area/ORACDB/archivelog/2013_12_20/
o1_mf_1_6_9c8htxj2_.arc 
thread=1 sequence=6
 archived log file name=/u01/app/oracle/fast_recovery_area/ORACDB/archivelog/2013_12_20/
o1_mf_1_7_9c8htxvk_.arc 
thread=1 sequence=7
 media recovery complete, elapsed time: 00:00:00
 Finished recover at 20-DEC-13
 RMAN> alter tablespace example online;
 Statement processed
 RMAN> 

Agora, a “tablespace“ EXAMPLE está completamente recuperada e, com isso, encontra-se em estado ONLINE.

Perda completa de um PDB:

Nesta seção, vamos ver como restaurar e recuperar um PDB de um backup. Se você possui múltiplos PDBs, você pode restaurá-lo sem afetar os outros PDBs. Para realizar o restauro e recuperação, é possível se conectar ao container ROOT e utilizar o  seguinte comando "RESTORE PLUGGABLE DATABASE", ou também, é possível conectar ao PDB específico e executar o comando "RESTORE DATABASE".

Para realizar o restauro e recuperação do PDB, é recomendado realizar o “fechamento” do mesmo.
SQL>alter pluggable database orapdb close;
Pluggable database altered.
RMAN> restore pluggable database orapdb;
 Starting restore at 21-DEC-13
 using target database control file instead of recovery catalog
 allocated channel: ORA_DISK_1
 channel ORA_DISK_1: SID=55 device type=DISK
 channel ORA_DISK_1: starting datafile backup set restore
 channel ORA_DISK_1: specifying datafile(s) to restore from backup set
 channel ORA_DISK_1: restoring datafile 00019 to 
/u01/app/oracle/oradata/ORACDB/pdb/datafile/orapdb_o1_mf_system_9cbghmrb_.dbf
 channel ORA_DISK_1: restoring datafile 00020 to 
/u01/app/oracle/oradata/ORACDB/pdb/datafile/orapdb_o1_mf_sysaux_9cbghmpl_.dbf
 channel ORA_DISK_1: restoring datafile 00021 to 
/u01/app/oracle/oradata/ORACDB/pdb/datafile/orapdb_users01.dbf
 channel ORA_DISK_1: reading from backup piece 
/u01/app/oracle/fast_recovery_area/ORACDB/EE07145D1EAF1865E0437801A8C01BCF/backupset/2013_12_21/
o1_mf_nnndf_TAG20131221T124059_9cbhstcp_.bkp
 channel ORA_DISK_1: piece handle=/u01/app/oracle/fast_recovery_area/
ORACDB/EE07145D1EAF1865E0437801A8C01BCF/
backupset/2013_12_21/o1_mf_nnndf_TAG20131221T124059_9cbhstcp_.bkp tag=TAG20131221T124059
 channel ORA_DISK_1: restored backup piece 1
 channel ORA_DISK_1: restore complete, elapsed time: 00:00:25
 Finished restore at 21-DEC-13
RMAN> recover pluggable database orapdb;
 Starting recover at 21-DEC-13
 using channel ORA_DISK_1
 starting media recovery
 media recovery complete, elapsed time: 00:00:00
 Finished recover at 21-DEC-13
RMAN>alter pluggable database orapdb open;
 Statement processed

Recuperação a um ponto do tempo de um PDB (DBPITR):

O conceito de recuperação para um ponto no tempo é chamdo de "DBPITR". É possível que venhamos a enfrentar problemas como uma tabela que foi dropada, registros que foram removidos ou uma tabela que foi truncada. Em tais casos, uma recuperação a um ponto no tempo pode ser realizada.

Seria possível utilizar um recurso novo presente no 12c, chamado “RMAN Table Point In Time Recovery“, mas isso será tratado em um futuro artigo.

Nota: Para realizar o DBPITR será utilizado o RMAN.

Requisitos para utilizar um DBPITR em um PDB:

  • O banco de dados precisa estar em modo “Archive log”.
  • Você precisa de um backup completo do CBD, se o alvo é o SCN 10.000 por exemplo, então o backup deve começar abaixo deste SCN, como por exemplo, 8.000, 9.000 ou menos.
  • É necessário ter todos os “archived logs” posteriores ao backup completo.

Verifique o status do modo "archive log" e se existe um backup antes de fazer as modificações, deleções ou qualquer outra operação.

SQL> select name,open_mode from v$pdbs;
NAME                           OPEN_MODE
------------------------------ ----------
PDB$SEED                       READ ONLY
ORAPDB                         READ WRITE
SQL> archive log list
 Database log mode             Archive Mode
 Automatic archival             Enabled
 Archive destination           USE_DB_RECOVERY_FILE_DEST
 Oldest online log sequence    3
 Next log sequence to archive  5
 Current log sequence           5

 

Foi realizado um backup completo, mas recomendamos que este backup seja verificado após sua conclusão:

RMAN> list backup tag='BEFORE_DBPITR';
List of Backup Sets
===================
BS Key  Size       Device Type Elapsed Time Completion Time
------- ---------- ----------- ------------ ---------------
68      13.21M     DISK        00:00:02     21-DEC-13

BP Key: 68   Status: AVAILABLE  Compressed: YES 
Tag: BEFORE_DBPITR
Piece Name: /u01/app/oracle/fast_recovery_area/ORACDB/backupset/2013_12_21/
o1_mf_annnn_BEFORE_DBPITR_9cbpl5l2_.bkp
List of Archived Logs in backup set 68

Thrd Seq     Low SCN   Low Time  Next SCN   Next Time
---- ------- ---------- --------- ---------- ---------
1    1       2273638    21-DEC-13 2281354    21-DEC-13
1    2       2281354    21-DEC-13 2281403    21-DEC-13
1    3       2281403    21-DEC-13 2284137    21-DEC-13
1    4       2284137    21-DEC-13 2284199    21-DEC-13
1    5       2284199    21-DEC-13 2289882    21-DEC-13
BS Key  Size       Device Type Elapsed Time Completion Time
------- ---------- ----------- ------------ ---------------
72      12.50K     DISK        00:00:00     21-DEC-13

BP Key: 72   Status: AVAILABLE  Compressed: YES 
Tag: BEFORE_DBPITR
Piece Name: /u01/app/oracle/fast_recovery_area/ORACDB/backupset/2013_12_21/
o1_mf_annnn_BEFORE_DBPITR_9cbpp6ob_.bkp
List of Archived Logs in backup set 72

Thrd Seq     Low SCN    Low Time  Next SCN   Next Time
---- ------- ---------- --------- ---------- ---------
1    6       2289882    21-DEC-13 2289956    21-DEC-13


Agora você tem o banco de dados no modo "Archive log" e também foi realizado um backup completo bem-sucedido do banco de dados, ao qual atribuímos a tag "BEFORE_DBPITR".

SQL>  alter session set container=orapdb;
Session altered.
SQL> select name,open_mode from v$pdbs;
NAME                           OPEN_MODE
------------------------------ ----------
ORAPDB                         READ WRITE
SQL> create tablespacedbpitr
datafile '/u01/app/oracle/oradata/ORACDB/pdb/datafile/dbpitr_01.dbf'
size 100m;
Tablespace created.
SQL> create user pdbuser identified by manager 
defaulttablespacedbpitr;
User created.
SQL> connect pdbuser/manager@orapdb;
Connected.
SQL> create table pdbtable(
emp_namevarchar2(10),
salary number(5));
Table created.
SQL> insert into pdbtable values ('emp_one',60000);
1 row created.
SQL> insert into pdbtable values ('emp_two',70000);
1 row created.
SQL> insert into pdbtable values ('emp_three',80000);
1 row created.
SQL> commit;
Commit complete.
SQL> select timestamp_to_scn(sysdate) from dual;
TIMESTAMP_TO_SCN(SYSDATE)
-------------------------
2291250
SQL> select * from pdbtable;
EMP_NAME       SALARY
---------- ---------
emp_one         60000
emp_two         70000
emp_three       80000


Três registros foram inseridos na tabela "pdbtable" e foi realizado o "commit". Para realizar o "DBPITR" é necessário saber o momento em que precisamos recuperar o banco de dados. Portanto, você deve ter o SCN a ser alcançado ou a data em que você precisa recuperar. Você também pode usar funções para obter esses dados, como por exemplo:

  • timestamp_to_scn
  • scn_to_timestamp

 SQL> select timestamp_to_scn(sysdate) from dual;

TIMESTAMP_TO_SCN(SYSDATE)
--------------------------
2291262

SQL> select scn_to_timestamp(2291262) from dual;
SCN_TO_TIMESTAMP(2291262)
----------------------------------------------------------------
21-DEC-13 03.17.30.000000000 PM


Depois de reunir os detalhes do SCN ou a data desejada de recuperação, a tabela inteira foi truncada (simulando um erro do usuário), com isso, todos os registros na tabela "pdbtable" foram perdidos.

SQL> truncate table pdbtable;
 Table truncated.
SQL> select * from pdbtable;
 no rows selected


Agora obteremos o SCN e a data referente a este SCN:

SQL> select timestamp_to_scn(sysdate) from dual;
TIMESTAMP_TO_SCN(SYSDATE)
-------------------------
2291764
SQL> select scn_to_timestamp(2291764) from dual;
SCN_TO_TIMESTAMP(2291764)
----------------------------------------------------------------
21-DEC-13 03.27.18.000000000 PM


Antes de executar a recuperação do banco de dados, é necessário que este seja fechado. É necessário fechar apenas o PDB em que ocorreu o problema.

bash-3.2$ rman 
 RMAN> connect target "sys as sysbackup" 
 target database Password: 
 connected to target database: ORACDB (DBID=2508982653) 
RMAN>alter pluggable database orapdb close; 
 using target database control file instead of recovery catalog 
 Statement processed 


O PDB “ORAPDB“ foi fechado, agora é possível realizar a recuperação a um ponto do tempo anterior ao momento em que a tabela foi truncada. Antes de realizar o "DBPITR" existe a necessidade de criar um destino auxiliar, com espaço suficiente para armazenar cópias dos "datafiles".

bash-3.2$ rman target /
RMAN> run
 2> {
 3> set until scn 2291262;
 4> restore pluggable database orapdb;
 5> recover pluggable database orapdb auxiliary destination='/home/oracle/working/aux_pdb';
 6>alter pluggable database orapdb open resetlogs;
 7> }
executing command: SET until clause
Starting restore at 21-DEC-13
 using target database control file instead of recovery catalog
 allocated channel: ORA_DISK_1
 channel ORA_DISK_1: SID=57 device type=DISK
creatingdatafile file number=22 name=/u01/app/oracle/oradata/ORACDB/pdb/datafile/dbpitr_01.dbf
 channel ORA_DISK_1: starting datafile backup set restore
 channel ORA_DISK_1: specifying datafile(s) to restore from backup set
 channel ORA_DISK_1: restoring datafile 00019 to 
/u01/app/oracle/oradata/ORACDB/pdb/datafile/orapdb_o1_mf_system_9cbghmrb_.dbf
 channel ORA_DISK_1: restoring datafile 00020 to 
/u01/app/oracle/oradata/ORACDB/pdb/datafile/orapdb_o1_mf_sysaux_9cbghmpl_.dbf
 channel ORA_DISK_1: restoring datafile 00021 to 
/u01/app/oracle/oradata/ORACDB/pdb/datafile/orapdb_users01.dbf
 channel ORA_DISK_1: reading from backup piece 
/u01/app/oracle/fast_recovery_area/ORACDB/EE07145D1EAF1865E0437801A8C01BCF/backupset/2013_12_21/
o1_mf_nnndf_TAG20131221T143720_9cbpn00l_.bkp
 channel ORA_DISK_1: piece 
handle=/u01/app/oracle/fast_recovery_area/ORACDB/EE07145D1EAF1865E0437801A8C01BCF/backupset/2013_12_21/
o1_mf_nnndf_TAG20131221T143720_9cbpn00l_.bkp tag=TAG20131221T143720
 channel ORA_DISK_1: restored backup piece 1
 channel ORA_DISK_1: restore complete, elapsed time: 00:00:35
 Finished restore at 21-DEC-13
.....................................
Oracle instance shut down
Removing automatic instance
 Automatic instance removed
 auxiliary instance file /home/oracle/working/aux_pdb/ORACDB/datafile/o1_mf_sysaux_9cbt6k0m_.dbf deleted
 auxiliary instance file /home/oracle/working/aux_pdb/ORACDB/controlfile/o1_mf_9cbt6c34_.ctl deleted
 Finished recover at 21-DEC-13
Statement processed
Pluggable Database Point-In-Time recovery successfully completed without any errors. 


Foi incluído o comando "alter pluggable database orapdb  open resetlogs", para que o PDB estivesse disponível para leituras e escritas logo após a conclusão da recuperação. Agora é hora de verificar os dados, para ver se o RMAN foi capaz de recuperar os registros que foram excluídos ao truncar a tabela.

bash-3.2$ sqlpluspdbuser/manager@orapdb

SQL> select * from pdbtable;

EMP_NAME       SALARY
---------- ---------
emp_one         60000
emp_two         70000
emp_three       80000


Todos os dados apagados pela operação de truncate estam novamente disponíveis na tabela. Quando é realizada a recuperação de um único PDB, nenhum outro PDB do container será afetado.

SQL> select db_incarnation#,pdb_incarnation#,
status,incarnation_time
from v$pdb_incarnation
where status='CURRENT'; 

DB_INCARNATION# PDB_INCARNATION# STATUS  INCARNATION_TIME 
--------------- ---------------- ------- -------------------- 
5                1        CURRENT 21-DEC-2013 03:17:42 


Recomenda-se verificar a data da reencarnação e o SCN antes do truncar a tabela para verificar se a recuperação foi realizada com sucesso.

 


Alex Zaballa, formado em Análise de Sistemas, é especialista em Banco de Dados Oracle com sólidos conhecimentos em Servidores de Aplicação e Sistemas Operacionais; trabalha com Oracle há 15 anos, é ORACLE ACE, certificado OCM Database 11G e conta com mais de 100 outras certificações em produtos da Oracle. Desde 2007 é funcionário da empresa Júpiter em Angola, alocado em um projeto no Ministério das Finanças. Alex também é fundador do Grupo de Usuários Oracle de Angola (GUOA) e membro do time OraWorld.

Yenugula Venkata Ravikumar é um DBA com mais de 15 anos de experiencia com Oracle e em ambientes de alta disponibilidade (RAC, Data Guard, dentre outros), tuning e desempenho, migrações, backup e recover, Oracle Exadata X2 e X3, é Expert em sistemasoperacionais tais como  como AIX, HP-UX e Linux. Já participou como conferencista de Oracle pela India, ode mora atualmente. Obteve o titulo de "Oracle Certified Master (OCM 10g)" em 2009.

Nassyam Basha é um DBA, OCM 11g, com experiência em tecnologias como Oracle Data Guard, RMAN, RAC. Ele já fez mais de 90 configurações do Data Guard em diferentes plataformas, de não-RAC RAC e vice-versa. Ele fez migrações bem-sucedidas com "switchovers" e "failovers" a vários bancos de dados de produção crítica. Ele participa ativamente de fóruns Oracle utilizando o usuário "CKPT" e ganhou mais de 10.000 pontos (nível guru). Publica regularmente artigos em seu blog www.oracle-ckpt.com e é co-autor do livro "Guia de Administração do Oracle Data Guard 11gR2".

Este artigo foi revisto pela equipe de produtos Oracle e está em conformidade com as normas e práticas para o uso de produtos Oracle.