Renomear ou mover datafiles de forma online com Oracle Database 12C

Por Alex Zaballa,
Postado em Abril de 2014

Antes do Oracle Database 12c, renomear ou mover datafiles sempre foi uma tarefa offline. Existiam formas de minimizar o downtime, mas não era possível acabar com ele. Uma das possíveis soluções para renomear ou mover datafiles era:

  • Colocar a tablespace offline
  • Mover o(s) arquivo(s) utilizando comandos do sistema operacional ou ASM
  • Renomear o(s) arquivo(s) no control file
  • Colocar a tablespace online

Esta solução não podia ser utilizada para as tablespaces temporárias, SYSTEM e de UNDO ativas. Dependendo do tamanho dos arquivos e o tempo de downtime tolerado para a tablespace, era possível utilizar o RMAN para diminuir esse tempo.

Agora no Oracle Database 12c, é possível fazer tudo isso enquanto os usuários acessam o datafile, ou seja, de forma online e com um único comando. O comando “ALTER DATABASE MOVE DATAFILE” copia / renomeia o datafile para a nova localização, atualiza o control file e exclui o datafile antigo. Você também tem a opção de manter o arquivo antigo, utilizando a cláusula "KEEP", porém o arquivo retido não faz mais parte do banco de dados. A cláusula REUSE indica que um novo arquivo deve ser criado, mesmo que exista um arquivo com o mesmo nome no local de destino.

datafiles

Algumas tarefas comuns que agora podem ser feitas de forma online:

  • Mover datafiles de um tipo de storage para outro
  • Mover datafiles que não são acessados frequentemente para um storage de custo menor
  • Tornar a tablespace somente leitura e mover o datafiles para um write-once storage
  • Mover o database para dentro do Oracle Automatic Storage Management (Oracle ASM)

Quando o arquivo de origem é um arquivo OMF a opção KEEP não será respeitada. Se o arquivo de destino é um arquivo OMF, a cláusula TO pode ser omitida e o arquivo será criado com um nome OMF no local que aponta o parâmetro DB_CREATE_FILE_DEST.

O arquivo de origem pode ser especificado usando o número do arquivo ou nome.

Criando a tablespace e o datafile para exemplificar:




SQL> create tablespace tb_teste datafile '+DG01' size 10M;
Tablespace created.
SQL> create table tabela_teste (id number) tablespace tb_teste;
Table created.
SQL> insert into tabela_teste values (1);
1 row created.
SQL> commit;
Commit complete.
SQL> select name, status, file# from v$datafile;

NAME                                                STATUS   FILE#

--------------------------------------------------  -------  -----

+DG01/ORCL/DATAFILE/system.258.828439909             SYSTEM   1
+DG01/ORCL/DATAFILE/example.266.828440247            ONLINE   2
+DG01/ORCL/DATAFILE/sysaux.257.828439803             ONLINE   3
+DG01/ORCL/DATAFILE/undotbs1.260.828440039           ONLINE   4
+DG01/ORCL/DATAFILE/tb_teste.268.843508481           ONLINE   5
+DG01/ORCL/DATAFILE/users.259.828440035              ONLINE   6

Movendo o datafile do ASM para File System:



SQL> alter database move datafile '+DG01/ORCL/DATAFILE/tb_teste.268.843508481' 
  to '/u01/app/oracle/oradata/orcl/tb_teste.dbf';
  
Database altered.

SQL> select name, STATUS  from v$datafile where name like '%tb_teste%';

NAME                                                STATUS

--------------------------------------------------  -------

/u01/app/oracle/oradata/orcl/tb_teste.dbf            ONLINE

  O que é mostrado no alert.log:
Sat Mar 29 20:00:34 2014
Moving datafile +DG01/ORCL/DATAFILE/tb_teste.268.843508481 (5) 
  to /u01/app/oracle/oradata/orcl/tb_teste.dbf
Move operation committed for file /u01/app/oracle/oradata/orcl/tb_teste.dbf

Completed: alter database move datafile '+DG01/ORCL/DATAFILE/tb_teste.268.843508481' 
  to '/u01/app/oracle/oradata/orcl/tb_teste.dbf'

Renomeando o datafile:



SQL> alter database move datafile '/u01/app/oracle/oradata/orcl/tb_teste.dbf' 
  to '/u01/app/oracle/oradata/orcl/teste.dbf';
Database altered.

  Movendo o datafile para o ASM:
SQL> alter database move datafile '/u01/app/oracle/oradata/orcl/teste.dbf' to '+DG01';
Database altered.
SQL> select name, STATUS  from v$datafile where name like '%tb_teste%';

NAME                                                STATUS

--------------------------------------------------  -------

+DG01/ORCL/DATAFILE/tb_teste.268.843509069           ONLINE

Movendo o datafile no ASM para dentro de outro local no ASM:



SQL> alter database move datafile '+DG01/ORCL/DATAFILE/tb_teste.268.843509069' 
  to '+DG01/ORCL/DATAFILE/readonly/tb_teste.dbf';
Database altered.

  Movendo o datafile para o ASM e mantendo o arquivo antigo no local de origem:
  
SQL> alter database move datafile '/u01/app/oracle/oradata/orcl/tb_teste.dbf' to '+DG01' KEEP;
Database altered.
SQL> host ls -l /u01/app/oracle/oradata/orcl/tb_teste.dbf
-rw-r-----. 1 oracle dba 10493952 Mar 30 14:03 /u01/app/oracle/oradata/orcl/tb_teste.dbf

  Utilizando o REUSE:
SQL> ALTER DATABASE MOVE DATAFILE 5 To '/u01/app/oracle/oradata/orcl/tb_teste.dbf';
ALTER DATABASE MOVE DATAFILE 5 To '/u01/app/oracle/oradata/orcl/tb_teste.dbf'
*
ERROR at line 1:
ORA-01119: error in creating database file
'/u01/app/oracle/oradata/orcl/tb_teste.dbf'
ORA-27038: created file already exists
Additional information: 1
SQL> ALTER DATABASE MOVE DATAFILE 5 To '/u01/app/oracle/oradata/orcl/tb_teste.dbf' REUSE;
Database altered.

Utilizando o OMF, com isso eliminamos a necessidade de utilizar o TO:



SQL> show parameter db_create_file_dest

NAME                                    TYPE                 VALUE

------------------------------------ ----------- ------------------------------

db_create_file_dest                     string       +DG01
SQL> ALTER DATABASE MOVE DATAFILE 5;
Database altered.
SQL> select name, STATUS  from v$datafile where name like '%tb_teste%';

NAME                                                 STATUS

--------------------------------------------------  -------

+DG01/ORCL/DATAFILE/tb_teste.268.843574125           ONLINE

  Ao utilizar a cláusula KEEP em um OMF, podemos verificar que ela é ignorada:
ASMCMD> pwd
+dg01/orcl/datafile
ASMCMD> ls
EXAMPLE.266.828440247
SYSAUX.257.828439803
SYSTEM.258.828439909
TB_TESTE.268.843574125
UNDOTBS1.260.828440039
USERS.259.828440035
SQL> ALTER DATABASE MOVE DATAFILE 5 to '/u01/app/oracle/oradata/orcl/tb_teste.dbf' KEEP;
Database altered.
ASMCMD> ls
EXAMPLE.266.828440247
SYSAUX.257.828439803
SYSTEM.258.828439909
UNDOTBS1.260.828440039
USERS.259.828440035

  O ALTER DATABASE MOVE DATAFILE não funciona para temporary files:
SQL> select file#,name from v$tempfile;

FILE# NAME

---------- --------------------------------------------------

1 +DG01/ORCL/TEMPFILE/temp.265.828440161
SQL> ALTER DATABASE MOVE DATAFILE '+DG01/ORCL/TEMPFILE/temp.265.828440161' TO '/tmp/temp.dbf';
ALTER DATABASE MOVE DATAFILE '+DG01/ORCL/TEMPFILE/temp.265.828440161' TO '/tmp/temp.dbf'
*
ERROR at line 1:
ORA-01516: nonexistent log file, data file, or temporary file "+DG01/ORCL/TEMPFILE/temp.265.828440161"

Mesmo se você estiver usando um banco de dados standby, você pode executar esta operação de forma independente. Uma operação de flashback não muda o datafile movido de volta para sua posição anterior. Quando essa operação for realizada na plataforma Windows, o arquivo original será mantido, mesmo que você não tenha utilizado a opção KEEP. Após a operação ser concluída, você pode eliminar manualmente o datafile.

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á 14 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.