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 {
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
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:
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
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
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