Alterar DBname via controlfile

Boa Tarde.

Ontem postei um artigo sobre como alterar o dbname de uma instância com o NID, hoje vou escrever um artigo de como fazer este mesmo processo recriando seu controlfile.

Vantagens?
Sim muitas, pense que você perdeu seus controlfiles, você pode utilizar esta tecnica, ou você pode utilizar esta tecnica para duplicar sua base, mantendo sua base de produção intacta. As possibilidades são muitas.

Vamos ao que interessa.

Primeiro vamos gerar um backup de nosso controlfile.

-bash-3.1$ sqlplus

SQL*Plus: Release 11.2.0.2.0 Production on Thu Sep 29 14:38:47 2011

Copyright (c) 1982, 2010, Oracle.  All rights reserved.

Enter user-name: / as sysdba
Connected to an idle instance.

SQL> startup pfile=initlana1.ora
ORACLE instance started.

Total System Global Area  451964928 bytes
Fixed Size                  1344812 bytes
Variable Size             218106580 bytes
Database Buffers          226492416 bytes
Redo Buffers                6021120 bytes
Database mounted.
Database opened.
SQL> alter system switch logfile;

System altered.

SQL> alter database backup controlfile to trace as '/tmp/lana.ora'resetlogs;

Database altered.

Teremos de pegar este arquivo de trace que foi gerado e modificalo.
Observe que até as palavras “STARTUP NOMOUNT” todo o conteudo acima é comentário.

Devemos então apagar todo esse conteudo acima de “STARTUP NOMOUNT”
e também podemos apagar todo o conteudo abaixo que estiver comentado.

o resultado final de nosso arquivo deverá ser mais ou menos este.

bash-3.1$ vi /tmp/lana.ora
bash-3.1$ cat /tmp/lana.ora
STARTUP NOMOUNT
CREATE CONTROLFILE REUSE DATABASE "LANA1" RESETLOGS  ARCHIVELOG
    MAXLOGFILES 16
    MAXLOGMEMBERS 3
    MAXDATAFILES 400
    MAXINSTANCES 8
    MAXLOGHISTORY 292
LOGFILE
  GROUP 1 '/u01/app/oracle/oradata/lana/redo01.log'  SIZE 50M BLOCKSIZE 512,
  GROUP 2 '/u01/app/oracle/oradata/lana/redo02.log'  SIZE 50M BLOCKSIZE 512,
  GROUP 3 '/u01/app/oracle/oradata/lana/redo03.log'  SIZE 50M BLOCKSIZE 512
-- STANDBY LOGFILE
DATAFILE
  '/u01/app/oracle/oradata/lana/system01.dbf',
  '/u01/app/oracle/oradata/lana/sysaux01.dbf',
  '/u01/app/oracle/oradata/lana/undotbs01.dbf',
  '/u01/app/oracle/oradata/lana/users01.dbf',
  '/u01/app/oracle/oradata/lana/TEIKO.dbf',
  '/u01/app/oracle/oradata/lana/lana_LOB.DBF',
  '/u01/teste.dbf',
  '/u01/leolana1.dbf'
CHARACTER SET WE8MSWIN1252
;
RECOVER DATABASE USING BACKUP CONTROLFILE
ALTER DATABASE OPEN RESETLOGS;
ALTER TABLESPACE TEMP ADD TEMPFILE '/u01/app/oracle/oradata/lana/temp01.dbf'
     SIZE 1056964608  REUSE AUTOEXTEND ON NEXT 655360  MAXSIZE 32767M;
bash-3.1$

Vamos observar que neste arquivo existem listados todos os logfiles e todos os datafiles.
Caso desejarem alterar algum nome basta mover os datafiles para o desejado e alterar neste arquivo.

Agora pegaremos na segunda linha e alteraremos o banco lana1 para lana.
Também vamos trocar o REUSE para SET

bash-3.1$ vi /tmp/lana.ora
bash-3.1$ cat /tmp/lana.ora |grep CREATE
CREATE CONTROLFILE SET DATABASE "LANA" RESETLOGS  ARCHIVELOG
bash-3.1$

Observe no primeiro que o nome do database era “LANA1” e neste alteramos para “LANA” e também trocamos o reuse para set
Após isto, teremos de excluir os controlfiles antigos, mas por garantia vou apenas movelos.

SQL> select name from v$database;

NAME
---------
LANA1

SQL> set lines 160
SQL> col VALUE for a135
SQL> col NAME for a20
SQL> select NAME,VALUE from v$parameter where NAME ='control_files';

NAME                 VALUE
-------------------- -------------------------------------------------------------------------------------------------------------------------------------
control_files        /u01/app/oracle/oradata/lana/control01.ctl, /u01/app/oracle/oradata/lana/control02.ctl, /u01/app/oracle/oradata/lana/control03.ctl
SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.

Agora vamos movelos

-bash-3.1$ mv /u01/app/oracle/oradata/lana/control01.ctl /u01/app/oracle/oradata/lana/control01.ctl_old
-bash-3.1$ mv /u01/app/oracle/oradata/lana/control02.ctl /u01/app/oracle/oradata/lana/control02.ctl_old
-bash-3.1$ mv /u01/app/oracle/oradata/lana/control03.ctl /u01/app/oracle/oradata/lana/control03.ctl_old

Agora vamos ao que interessa, subir a base com novo nome.

SQL> @/tmp/lana.ora
ORACLE instance started.

Total System Global Area  451964928 bytes
Fixed Size                  1344812 bytes
Variable Size             218106580 bytes
Database Buffers          226492416 bytes
Redo Buffers                6021120 bytes

Control file created.

Até aqui é a parte mais importante.
Você tem de receber a mensagem de que os controlfiles foram criados.

Com esta mensagem já sabemos que é possível pelo menos montar o banco.

Após isto teremos de partir para a recuperação do banco.

SQL> alter database open read only;
alter database open read only
*
ERROR at line 1:
ORA-16008: indeterminate control file checkpoint

SQL> alter database recover USING BACKUP CONTROLFILE until cancel;
alter database recover USING BACKUP CONTROLFILE until cancel
*
ERROR at line 1:
ORA-00279: change 3045708 generated at 09/29/2011 15:10:19 needed for thread 1
ORA-00289: suggestion :
/u01/app/oracle/product/11.2.0/dbhome_1/dbs/arch1_3_762990194.dbf
ORA-00280: change 3045708 for thread 1 is in sequence #3

Se tentarmos efetuar o recover pelo archive que ele esta sugerindo não conseguiremos encontralo.

SQL> !ls -lrt /u01/app/oracle/product/11.2.0/dbhome_1/dbs/arch1_3_762990194.dbf
ls: /u01/app/oracle/product/11.2.0/dbhome_1/dbs/arch1_3_762990194.dbf: Arquivo ou diretório não encontrado

O que temos de fazer nesta situação é fazer um recover com o logfile que ainda não foi gerado archive.

SQL> select member
  2  from v$logfile
  3  where GROUP# = 3;

MEMBER
--------------------------------------------------------------------------------
/u01/app/oracle/oradata/lana/redo03.log

Conforme a mensagem de recover “ORA-00280: change 3045708 for thread 1 is in sequence #3”.
Então já sabemos que era o grupo de redo 3.


SQL> alter database recover cancel;

Database altered.

SQL> recover database;
ORA-00283: recovery session canceled due to errors
ORA-01610: recovery using the BACKUP CONTROLFILE option must be done

SQL> recover database USING BACKUP CONTROLFILE;
ORA-00279: change 3045708 generated at 09/29/2011 15:10:19 needed for thread 1
ORA-00289: suggestion :
/u01/app/oracle/product/11.2.0/dbhome_1/dbs/arch1_3_762990194.dbf
ORA-00280: change 3045708 for thread 1 is in sequence #3

Specify log: {=suggested | filename | AUTO | CANCEL}
/u01/app/oracle/oradata/lana/redo03.log
Log applied.
Media recovery complete.
SQL> ALTER DATABASE OPEN RESETLOGS;

Database altered.

Banco no ar.
Mas nosso trabalho ainda não terminou.
Neste processo se você for fazer algum select com ordenação que custem mais do que o banco tem de memória reservada você receberá erros no select (infelizmente não tenho o erro aqui.)

SQL> ALTER TABLESPACE TEMP ADD TEMPFILE '/u01/app/oracle/oradata/lana/temp01.dbf' SIZE 1056964608
REUSE AUTOEXTEND ON NEXT 655360  MAXSIZE 32767M;

Tablespace altered.

Neste caso acima eu utilizei o mesmo arquivo de temp e por isso utilizei a clausula reuse no comando.

SQL> select name from v$database;

NAME
---------
LANA

Pronto.

%name Alterar DBname via controlfile

Autor: Leandro Lana

Trabalho com banco de dados Oracle desde 2006, já trabalhei com as plataformas 9i, 10G, 11G, 12C, 18C, 19C e 21(ainda em testes).

Trabalhando atualmente como consultor Oracle na MigraTI Soluções em TI como administrador de banco de dados Oracle, SQL-Server, MySQL e Postgresql.

Contato: leandro.lana@migrati.com.br

Fone: (47) 9191-6052 / (47) 3328 0996

Certificações:

OCA 10G.

OCP 10G.

OCE Linux.

OCE RAC/Cluster.

MCP SQL-Server 2008.

MCITP SQL-Server 2008.

DB2 Fundamentals.