terça-feira, 31 de maio de 2016

Duplicate de bases em RAC

Olá jovens... Espero que todos estejam bem...

Estou revisitando alguns posts, fazendo algumas melhorias e correções e acho que esse vale a pena.

Clonar bases em RAC é um processo bem tranquilo. Um pouco mais trabalhoso é verdade, mas bem tranquilo mesmo.

Nosso cenário:
Base: PROD
prod1 e prod1 ==> 11.2.0.4
CLONE
clone1 e clone2 ==> 11.2.0.4

Então, chega de papo. Vá até o seu local de backup e crie o arquivo "bkp.sh" com o seguinte conteúdo. Caso tenha o backup da noite (disco ou fita), melhor ainda.Utilize=o e ganhamos tempo.

export ORACLE_SID=prod1
rman target / <
run {
ALLOCATE CHANNEL d1 TYPE DISK MAXPIECESIZE 16G;
BACKUP AS COMPRESSED BACKUPSET FORMAT
            '/backup/prod/%d_%Y%M%D_%I_%s_%U.bkp' DATABASE
CURRENT CONTROLFILE FORMAT 
            '/backup/prod/ctrl_%d_%Y%M%D_%I_%s_%U.ctrl';
SQL 'ALTER SYSTEM CHECKPOINT';
SQL 'ALTER SYSTEM ARCHIVE LOG CURRENT';
BACKUP AS COMPRESSED BACKUPSET FORMAT 
            '/backup/prod/%d_%Y%M%D_%I_%s_%U.bkp' ARCHIVELOG ALL;
BACKUP CURRENT CONTROLFILE FORMAT 
            '/backup/prod/ctrl_%d_%Y%M%D_%I_%s_%U.ctrl';
RELEASE CHANNEL d1;
}
exit;
EOF

Faça um:
chmod +x bkp.sh
nohup ./bkp.sh &

E acompanhe pelo tail:
tail -f nohup.out

Enquanto rola o backup, podemos ir realizando outras tarefas. 

Se por ventura essa base que será clonada já existir no RAC, vamos limpar todos os arquivos antigos antes de continuar
srvctl stop database -d clone

Nunca é demais lembrar que se o clone for novo, precisamos criar toda a estrutura necessárias de diretórios, o password file, etc.

orapwd file=orapwclone1 entries=3 password=123456

mkdir -p $ORACLE_BASE/admin/CLONE/adump
mkdir -p $ORACLE_BASE/admin/CLONE/udump
mkdir -p $ORACLE_BASE/admin/CLONE/bdump
mkdir -p $ORACLE_BASE/admin/CLONE/cdump

Ou seja, toda a estrutura para uma base comum, nos dois nós do RAC.

Agora sim, vamos limpar os datafiles antigos via ASMCMD. Muito cuidado ao executar a limpeza.

su - grid
asmcmd -p
ls
cd +ASMGRP01
rm -rf clone
cd ..
cd +ASMGRP02
rm -rf clone

Após o término, não esqueça de voltar para o usuário ORACLE.

Vamos editar o init da base. Se a base for nova, vamos gerar um init a partir do spfile da produção. Além dos acertos normais, 
deve-se prestar muita atenção aos itens abaixo:
    
*.control_files                 = '+ASMGRP01','+ASMGRP02'
*.CLUSTER_DATABASE        = FALSE
*.DB_RECOVERY_FILE_DEST       = '+ASMGRP02'
*.DB_RECOVERY_FILE_DEST_SIZE   = 500G
*.DB_CREATE_FILE_DEST         = '+ASMGRP01'
*.db_create_online_log_dest_1 = '+ASMGRP01'
*.db_create_online_log_dest_2 = '+ASMGRP02'

## Configure o parâmetro para evitar um bug 
        ## durante o RESETLOGS do DUPLICATE:
_no_recovery_through_resetlogs=TRUE

Não se esqueça também que apesar da clonagem ser feita inicialmente como uma base single você está em um ambiente RAC. Por isso verifique também: 
    
    *.db_name='clone'
    clone1.instance_name='clone1'    
    clone2.instance_name='clone2'
    clone1.INSTANCE_NUMBER=1
    clone2.INSTANCE_NUMBER=2
    
   clone1.local_listener='(address=(protocol=tcp)(host=99.99.99.999)(port=1521))'
   clone2.local_listener='(address=(protocol=tcp)(host=99.99.99.999)(port=1521))'

    clone1.THREAD=1
    clone2.THREAD=2

    clone1.undo_tablespace='UNDOTBS01'
    clone2.undo_tablespace='UNDOTBS02'

É isso. Agora é só dar um startup nomount na criança.

export ORACLE_SID=clone1
SQL> startup nomount
    

Beleza meninão. Agora vamos preparar o script de clonagem. Eu gosto de usar o SET NEWNAME para setar os novos caminhos dos datafiles. Não tem erro. Outros preferem usar do convert, aqui fica a seu critério.

A brincadeira vai começar a ficar legal agora.. Até o momento, só preparamos a clonagem. Vamos agora a ação, propriamente dita...

Se conecte a produção e execute esse SELECT:

select 'set newname for datafile ' || FILE_ID || ' to new;' as tt 
   from dba_data_files order by FILE_ID;

select 'set newname for tempfile ' || FILE_ID || ' to new;' as tt 
   from dba_temp_files order by FILE_ID;

Você vai receber algo assim:
set newname for datafile 1 to new;
set newname for datafile 2 to new;

set newname for tempfile 1 to new;

Esse são os datafiles e temp que serão restaurados/criados durante o duplicate.

O "new" vai me trazer uma estrutura de pastas a partir do ASM dessa forma, por exemplo:
+ASMGRP01/clone/CLONE/datafile


Vamos agora montar o script. 

cd /backup/prod
vim clone.sh

export ORACLE_SID=CLONE
rman TARGET sys/123456@PRD_DUP1 NOCATALOG AUXILIARY / <
RUN 
{
ALLOCATE AUXILIARY CHANNEL aux1 DEVICE TYPE DISK 
           FORMAT '/backup/prod/%d_%Y%M%D_%I_%s_%U.bkp' ;
set until scn 19473867277;
set newname for datafile 1 to new;
        set newname for datafile 2 to new;
        set newname for datafile 3 to new;
        set newname for datafile 4 to new;
        set newname for datafile 5 to new;
        set newname for datafile 6 to new;
        set newname for datafile 7 to new;
        set newname for datafile 8 to new;
        set newname for datafile 9 to new;
        set newname for datafile 10 to new;
        set newname for datafile 11 to new;
        SET NEWNAME FOR TEMPFILE 1 TO new;
        DUPLICATE TARGET DATABASE TO "clone"
LOGFILE
GROUP 1 ('+ASMGRP01','+ASMGRP02') SIZE 300M REUSE,
GROUP 2 ('+ASMGRP01','+ASMGRP02') SIZE 300M REUSE,
GROUP 3 ('+ASMGRP01','+ASMGRP02') SIZE 300M REUSE;
}
EXIT
EOF

Alguns pontos importantes:
PRD_DUP1 => deve apontar para o nó 1 de produção e não para uma conexão do RAC

set until scn = número do ultimo SCN que consta em seu backup de archives. Digamos que o FULL terminou as 08:29:55 do dia 28. Nosso SCN seria "19473867277" pois ele é o último archive no backup após esse horário. Eu sempre pego o do nó 1. 

Identifique o seu último backup de archives, na coluna "LOW SCN":

BS Key  Size       Device Type Elapsed Time Completion Time
------- ---------- ----------- ------------ -------------------
15173   92.93M     DISK        00:00:18     30/05/2016 21:41:10
BP Key: 15173   Status: AVAILABLE  Compressed: YES  Tag: TAG20160530T214052
Piece Name: /backup/prod/backup_db_PROD_S_15201_P_1_T_913239652

 List of Archived Logs in backup set 15173
 Thrd Seq     Low SCN    Low Time            Next SCN   Next Time
 ---- ------- ---------- ------------------- ---------- ---------
 1    4739    19472084645 27/05/2016 21:41:53 19473855500 28/05/2016 06:01:01
 1    4740    19473855500 28/05/2016 06:01:01 19473867272 28/05/2016 08:30:07
 1    4741    19473867272 28/05/2016 08:30:07 19473867277 28/05/2016 08:30:11
 1    4742    19473867277 28/05/2016 08:30:11 19475563361 28/05/2016 13:31:56
 2    4774    19472083060 27/05/2016 21:41:52 19473867269 28/05/2016 08:30:06
 2    4775    19473867269 28/05/2016 08:30:06 19473867279 28/05/2016 08:30:12
 2    4776    19473867279 28/05/2016 08:30:12 19475563358 28/05/2016 13:31:53
 2    4777    19475563358 28/05/2016 13:31:53 19475563376 28/05/2016 13:32:04
 2    4778    19475563376 28/05/2016 13:32:04 19476477750 28/05/2016 21:41:56

REDO LOGFILE => Eu gosto de já setar um conjunto mínimo de redos na clonagem. Também fica a critério.


Agora vamos executar a clonagem.
chmod +x clone.sh
nohup ./clone.sh & 

E acompanhar:
tail -f nohup.out

Se você chegou até aqui, parabéns man... Sua base já está sendo clonada. 

Se deu algo errado, volta e faz de novo.. Não desite agora... 

Continuando... Se correu tudo bem, devemos ter sucesso na clonagem.

Agora vamos fazer umas validações antes de colocar a base no RAC:

- Verificar o nome do controlfile gerado:
select value from v$parameter where name = 'control_files';
VALUE
-------------------------------------------------------
'+ASMGRP1/clone/controlfile/current.309.772155755', 
'+ASMGRP2/clone/controlfile/current.276.772155755'

Vamos baixar a base clonada e acertar o init com o nome dos controlfiles e o cluster_database

shutdown immediate

vim $ORACLE_HOME/dba/inisclone1.ora
*.control_files = '+ASMGRP1/clone/controlfile/current.309.772155755', 
                  '+ASMGRP2/clone/controlfile/current.276.772155755'
*.CLUSTER_DATABASE = TRUE

startup


Bacana, subiu? Tudo certinho? Estamos quase lá... 

Agora vamos criar redos para a thread 2 se for necessário. Mas como eu vou saber? Acredite, a informação está lá :)
    
Vamos primeiro verificar o tamanho dos Redos para criar todos iguais

select * from v$log;         
select GROUP#, THREAD#, SEQUENCE#, BYTES* from v$log;        

    GROUP#    THREAD#  SEQUENCE#      BYTES
---------- ---------- ---------- ----------
         1          1          1  134217728 
         2          1          0  134217728
         3          1          0  134217728
         

Viu ali que só temos redos para a thread 1? E a thread 2, como fica? Vamos criar, ora pois :)
        

select  GROUP#, TYPE, MEMBER from v$logfile;

GROUP# TYPE    MEMBER
------ ------- ---------------------------------------
     1 ONLINE  +ASMGRP01/clone/CLONE/onlinelog/group_1.413.766579093
       +ASMGRP01/clone/CLONE/onlinelog/group_1.413.766579094
  
     2 ONLINE  +ASMGRP01/clone/CLONE/onlinelog/group_2.412.766579093
         +ASMGRP01/clone/CLONE/onlinelog/group_2.412.766579094
  
     3 ONLINE  +ASMGRP01/clone/CLONE/onlinelog/group_3.411.766579093
       +ASMGRP01/clone/CLONE/onlinelog/group_3.411.766579094
        
Executar uma vez para cada grupo (no nosso exem-):    
alter database add logfile thread 2 ('+ASMGRP01','+ASMGRP02') 
   size 300M;
alter system switch logfile;
    
Habilitar a thread 2, se necessário
       alter database enable thread 2;

Ai sim, criar um spfile, e copiar o init, orapw, spfile para o nó 2:


 scp initclone1.ora oracle@clone-02:/oracle/app/oracle/product/10.2.0/db_1/dbs/initclone2.ora
 scp orapwclone1 oracle@clone-02:/oracle/app/oracle/product/10.2.0/db_1/dbs/orapwclone2
 scp spfileclone1.ora oracle@clone-02:/oracle/app/oracle/product/10.2.0/db_1/dbs/spfileclone2.ora

E por fim, o momento mais legal de todos: Iniciar a base no cluster

Se for nova, registrar a base primeiro nos OCR's do RAC
        srvctl add database -d clone -o /oracle/app/oracle/product/10.2.0/db_1
srvctl add instance -d clone -i clone1 -n clone-01
srvctl add instance -d clone -i clone2 -n clone-02

Start da base pelo cluster 
       srvctl start database -d clone
    
AHAHAH, bacana.. Chegamos até aqui? Ai sim, então chegamos até o final.

Espero que tenha ajudado. E que seja um guia fácil de acompanhar.

Isso eu não posso mudar nunca, e fica como no original:

Ahh, já ia esquecendo de oferecer esse post para quatro caras que me ajudaram muito na minha transição para a consultoria: 

Fabio Telles
Everton Evaristo
Breno "Sabonetão" Rodrigues
Hélio Higa. 

Obrigado pela ajuda.

E lembrem-se que "friends will be friends right to the end - Queen".


Abraço
Mario

Nenhum comentário:

Postar um comentário

Isso te ajudou? Comente...

Postagem em destaque

[ORACLE] Increasing the number of cores in a virtualized Oracle Database Appliance.

Hello everyone. How are you going? Today, I'll show you the process to increase the number of cores in a virtualized ODA HA X7-2. Import...