Pular para o conteúdo

ORACLE E MAA (Maximum Availability Architecture)

ORACLE E MAA (Maximum Availability Architecture)

Este artigo é o primeiro de uma série sobre Maximum Availability Architecture (MAA), com os passos, dicas e afins para configurar e manter um ambiente deste porte. No final da série teremos um ambiente com Oracle RAC tanto no primary quanto no standby.  Ambos sincronizados com Data Guard(DG) rodando em alta disponibilidade.

Não é a intenção aqui mostrar com configurar um ambiente RAC, já partirei de um ambiente com o RAC instalado e um banco rodando. Utilizarei o Oracle 11GR2 versão 11.2.0.3, já que a intenção também é mostrar como atualizar um ambiente em DG. Além disso, tentarei cobrir alguns pontos como “real-time apply” e criação do banco standby usando Media Management Layer (MML).

Tentarei ser o mais didático e claro possível e caso tenha alguma dúvida, pergunte. Todos os comandos que executei estarão no artigo. Infelizmente este primeiro artigo será extenso (muito) e cheio de detalhes técnicos, não tem como montar um ambiente assim de forma rápida e sem os diversos detalhes envolvidos. Infelizmente não existe um guia rápido de 10 passos para MAA com RAC, isso não existe. Você verá aqui um guia detalhado do início ao fim sobre como configurar MAA com RAC em ambos os lados.

Provavelmente alguns passos utilizados aqui para a configuração do ambiente podem ser mais simples na prática. Espero no final cobrir boa parte de um ambiente DG e MAA: switchover, failover, reisntate, broker, observer e afins.

Uma configuração como esta seria a aplicada em um ambiente Exadata que necessita de alta disponibilidade. Você teria que configurar MAA com DG entre dois Exadatas, como é RAC seria um DG sobre RAC.

PRIMEIRO ARTIGO

Neste primeiro artigo iremos configurar um ambiente DG em dois sites, somente o banco será replicado. Neste artigo não iremos ver a configuração do Broker nem failover, switchover e reinstate; isso ficará para próximos artigos.

AMBIENTE

A primeira coisa a ser feita em qualquer ambiente MAA é entender o ambiente que estamos trabalhando. Aqui, já partimos deum ambiente que chamamos inicialmente de primary com Oracle RAC 11.2.0.3 sobre 2 nós. No ASM temos dois diskgroups DATA e FRA para hospedar o banco de dados. Também temos um banco de dados chamado “maa”. Como dito acima, a intenção aqui não é mostrar a instalação de um RAC, existem ótimos artigos na internet sobre como fazer isso.

No servidor você pode descobrir isso através do comando “crsctlstat res –t”

O segundo ambiente chamarei de standby onde temos um RAC instalado, mas sem nenhum banco de dados criado, somente o Grid Infrastricture está instalado e uma instância ASM está criada. O banco de dados será criado aqui através da configuração do DG.

Aqui temos uma mudança interessante, no ambiente standby não temos o diskgroup DATA e sim o DG01. Essa é uma mudança intencional, deixei assim para que fosse possível explicar alguns detalhes na configuração do DG. Preferencialmente tenha os mesmos diskgroups em ambos os lados, primary e standby. Isso não será um problema, vamos ver a frente como contornar.

ARCHIVES, FLASHBACK E LOGMODE

De forma bem resumida DG utiliza archivelogs para sincronizar o primary com o standby, enviando todo e qualquer archive gerado no primarypara o standby.Para isso, precisamos que a base esteja em modo ARCHIVELOG. Basta verificar e configurar caso não esteja. Observe nos passos abaixo:

SQL> SELECT instance_name FROM gv$instance;

INSTANCE_NAME
 ----------------
 maa1
 maa2 

SQL> SELECT log_mode, flashback_on FROM v$database;

 LOG_MODE     FLASHBACK_ON

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

 NOARCHIVELOG NO

 SQL> ARCHIVE LOG LIST;

 Database log mode              No Archive Mode

 Automatic archival             Disabled

 Archive destination            USE_DB_RECOVERY_FILE_DEST

 Oldest online log sequence     13

 Current log sequence           14

 SQL>

Como visto acima a base não está em modo archivelog e nem está com o flashback habilitado. Habilitar flashback é fundamental, ele permite recuperar o banco de dados (fazer o reinstate) do primary em caso de failover de maneira muito (mas muito) mais rápida. Isso será tópico de um próximo artigo, mas no failover a troca entre os papeis entre primary e standby é feita de maneira abrupta. Se você tiver habilitado flashback as suas noites serão mais tranquilas e as horas extras menores.

Para configurar tudo corretamente, verifique o parâmetro de destino dos archives e o tamanho que ele pode usar. Dependendo da sua base de dados e da carga sobre ela, recomendo aumentar um pouco o limite da db_recovery_file_dest_size. Você até pode configurar outro caminho para o destino dosarchives, mas recomendo deixar tudo gerenciado pelo mesmo parâmetro e apontando para o db_recovery_file_dest. Caso queira ajustar algo, utilize:

ALTER SYSTEM SET db_recovery_file_dest='+FRA' SCOPE=SPFILE SID='*';

ALTER SYSTEM SET db_recovery_file_dest_size=4096M  SCOPE=SPFILE SID='*';

Com tudo configurado, basta fazer um restart do banco e habilitar flashback e archivelog. Como estamos em um RAC, acostume-se com seus comandos:

[oracle@rac11pri01 ~]
srvctl stop database -d maa -o immediate 
[oracle@rac11pri01 ~]
[oracle@rac11pri01 ~]
srvctl start instance -d maa -i maa1 -o mount
[oracle@rac11pri01 ~]

sqlplus / as sysdba SQL*Plus: Release 11.2.0.3.0 Production on Sat Mar 29 12:15:01 2014 Copyright (c) 1982, 2011, Oracle.  All rights reserved. Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production With the Partitioning, Real Application Clusters and Automatic Storage Management options 
SQL> ALTER DATABASE ARCHIVELOG; Database altered. 
SQL> ALTER DATABASE FLASHBACK ON; Database altered. 
SQL> ALTER DATABASE OPEN; Database altered. 
SQL> exit 

Disconnected from Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production With the Partitioning, Real Application Clusters and Automatic Storage Management options [oracle@rac11pri01 ~]$ [oracle@rac11pri01 ~] 
srvctl start instance -d maa -i maa2 [oracle@rac11pri01 ~]
srvctl status database -d maa Instance maa1 is running on node rac11pri01 Instance maa2 is running on node rac11pri02 [oracle@rac11pri01 ~]$

Como disse, o pilar básico do DG são os archiveslogs, mas infelizmente muitas vezes temos tabelas em modo NOLOGGING. Acredito que você já percebeu que isso pode não ser ideal em um DG, mas temos uma forma de corrigir isso com o “FORCE LOGGING”. Habilitando o “FORCE LOGGING” fará o banco de dados a gerar semprearchivelogs mesmo que a sua tabela esteja em NOLOGGING.

Dependendo o modo como você configura o seu DG existe a possibilidade de não usar o “FORCE LOGGING”. Basicamente uma informação sobre a transação é escrita no redo mesmo a operação sendo NOLOGGING, somente o seu archive não é gerado. Não uso assim e não recomendo deixar sem force logging. Configurar o FORCE LOGGING não custa nada e você irá agradecer no futuro.

A configuração é simples, observe abaixo:

SQL> SELECT log_mode, flashback_on, force_logging FROM v$database;

LOG_MODE     FLASHBACK_ON       FOR

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

ARCHIVELOG   YES                NO

SQL> ALTER DATABASE FORCE LOGGING;

Database altered.

SQL> SELECT log_mode, flashback_on, force_logging FROM v$database;

LOG_MODE     FLASHBACK_ON       FOR
------------ ------------------ ---
ARCHIVELOG   YES                YES

SQL>

Preparando pfile e spfile

Agora vamos começar a configurar o primary para o DG, deixando todos os parâmetros corretamente definidos (até para passos e artigos futuros). Como vamos trabalhar com os parâmetros eu recomendo começar com o um backup do spfile, nunca se sabe não é.

SQL> CREATE PFILE = '/tmp/pfile-primary-bkp.ora' FROM spfile;

File created.

SQL>

DB_NAME e DB_UNIQUE_NAME

Estes dois parâmetros são fundamentais em um ambiente DG. São eles que vão definir o nome da base de dados e das instâncias standby. O primeiro parâmetro é o db_name, responsável por dar nome ao banco de dados. O valor definido aqui será o mesmo utilizando tanto no primary quanto no standby.

SQL> SHOW PARAMETER db_name

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------

db_name                              string      maa

SQL>

O próximo parâmetro db_unique_name é utilizado para identificar qual o banco que você está, primary ou standby. O valor deste parâmetro ficará diferente entre o primary e o standy (ao contrário do db_name).  No primary nós não modificamos o seu valor, deixamos ele no valor default.

Além disso, a sua definição é utilizadaem outros parâmetros e configurações do DG, como por exemplo no redotransportation. Em alguns casos (como no 10G) era possível ter o mesmo valor em ambos os lados, com a versão 11 se isso estiver ocorrendo primary e standby não se comunicam. Essas informações você pode ver neste documento (Oracle Data Guard Concepts and Administration).

Um detalhe importante, o valor do db_unique_name quando não está configurado (fixo no spfile) deriva do db_name. Assim, é fundamental garantir que ele esteja definido no spfile da primary. Vejaabaixo:

SQL> SHOW PARAMETER db_unique_name

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
db_unique_name                       string      maa

SQL>

SQL>  ALTER SYSTEM SET db_unique_name='maa' SCOPE = spfile SID = '*';

System altered.

SQL>

LOG ARCHIVE CONFIGS

Este parâmetro é utilizado para definir quem participa do DG, quais as bases que irão trocar os archives. Se você tiver mais de um standby você definirá todos eles aqui, se você adicionar mais um standby no futuro terá que modificar este parâmetro.

A configuração deste parâmetro é simples, basta definir como no exemplo abaixo onde temos os dois bancos. Os valores aceitos para este parâmetro são os definidos no parâmetro db_unique_name. Desta forma, observe que já definimos como ficará para o nome para o standby (maastb):

SQL> SHOW PARAMETER log_archive_config

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
log_archive_config                   string

SQL>

SQL> ALTER SYSTEM SET log_archive_config='DG_CONFIG=(maa,maastb)' SCOPE = spfile SID = '*';

System altered.

SQL>

LOG_ARCHIVE_DEST_XX

Antes de alterarmos estes parâmetros precisamos entender algumas informações importantes do DG. Com as definições que podem ser especificadas nestes parâmetros definimos como o DG irá sincronizar os archives logs, quem será responsável por fazer isso e quando fazer isso.

A primeira definição importante a ser entendida é como os archives são sincronizados, a forma como redo é transportado (o que chamamos de redotransportation):

-SYNC: No modo síncrono o redotransporation entre o primary e o standy acontece de forma síncrona, isso quer dizer que uma transação no primary somente retorna ao usuário se o standbyrecebeu ela. Consequentemente isso pode trazer alguns “problemas” se a sua rede não tiver o throughput necessário para conseguir transportar as informações. Imagine que a latência de sua rede será somada ao tempo de qualquer commit do usuário.

-ASYNC: Neste modo o redo do primary não é transportado com sincronia, isso quer dizer que o commit do usuário não depende do envio da sua transação ao standby. Fica mais rápido, mas menos seguro.

Além da forma síncrona ou não do envio do redo também é necessário especificar uma “garantia” de recebimento por parte do standby. Assim temos duas opções:

-AFFIRM: garante que o standby recebeu e escreveu o redo no seu grupo de redo (standbyredo log – explicarei mais a frente).

-NOAFFIRM: o primary não espera o ACK do standby sobre a escrita completa do redo enviado. Assim o standby responde o ACK antes de garantir a escrita em seu grupo de redo.

Depois de escolher a sincronia entre as bases é necessário delimitar para o que o log_archive_dest será válido. Esta definição é feita através do atributo VALID_FOR que é dividido em duas partes:

REDO_LOG_TYPE:

-ONLINE_LOGFILE: com este parâmetro definido no VALID_FOR o LOG_ARCHIVE_DEST somente será utilizado quando estiver arquivando os redologonlines.

-STANDBY_LOGFILE: o destino somente será válido para standbyredologs (explicarei eles mais a frente).

-ALL_LOGFILES: o destino será utilizado independente do tipo de onlinelog. Como disse anteriormente, se utilizar um único local pode ficar mais simples a gerência.

DATABASE_ROLE:

-PRIMARY_ROLE: o destino somente será utilizando quando o banco estiver atuando como primary.

-STANDBY_ROLE: ativo somente quando estiver atuando como standby.

-ALL_ROLES: para ambos os casos acima.

Com estas definições podemos montar o log_archive_dest corretamente, vou tomar como base o exemplo abaixo:

SQL> SHOW PARAMETER log_archive_dest_1

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
log_archive_dest_1                   string

...

...

SQL> ALTER SYSTEM SET log_archive_dest_1='LOCATION=USE_DB_RECOVERY_FILE_DEST VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=maa' SCOPE=spfile SID='*';

System altered.

SQL>

Vamos analisar em partes o que foi definido acima para deixar tudo claro:

-LOCATION: definido que o destino dos archives será o que estiver definido no parâmetro DB_RECOVER_FILE_DEST.

-ALL_LOGFILES: isso quer dizer que este destino será utilizado independente do tipo de onlinelog gerado.

-ALL_ROLES: integrado com o parâmetro acima, o destino será utilizado independente da role do banco.

Com as definições acima temos que o LOG_ARCHIVE_DEST_1 será utilizado quando qualquer archive for gerado neste banco de dados, independe da role (primary ou standby) e do tipo de onlinelog (redo ou standby). Basicamente defini o armazenamento local. Claro que você pode definir configurações mais específicas, por exemplo, ter um local especifico para standby logs e redo logs. Você pode querer fazer isso para aliviar a carga sobre os discos por exemplo. Da forma como definido acima, tudo estará armazenando na flash_recovery_area.

Como você deve ter percebido, não foi definido nenhum local ou banco remoto para enviar os archives, somente definimos o que fazer localmente. Para especificar o que e como enviar para o standbyadicionamos mais um destino, observe o exemplo abaixo:

SQL> ALTER SYSTEM SET log_archive_dest_2='SERVICE=maastb SYNC AFFIRM LGWR VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=maastb' SCOPE=spfile SID='*';

System altered.

SQL>

Novamente verificamos os detalhes:

-SERVICE: define que o destino será um serviço TNS, o que estiver definido aqui tem que ser igual ao que está no tnsnames.ora. Como estamos em RAC, o TNS deve ser o mesmo para ambas as instâncias.

-SYNC: aqui, o logwriter somente retornará a transação ao usuário se o standby a receber;

-AFFIRM: além do logwriter esperar o standby receber, ele irá esperar até que o standby informar que escrever com sucesso em seu standby logs

-LGWR: este parâmetro era utilizado para diferenciar quem era responsável por enviar os dados ao standby. Deixo aqui para uma garantia que será o logwriter.

-ONLINE_LOGFILES: este destino será utilizado somente quando estiver arquivando os redolog, você não e não tem motivo para enviar os standby logs.

-PRIMARY_ROLE: novamente, o destino somente será utilizado quando estiver atuando como primary.

Com a definição acima garantimos o envio síncrono dos dados entre o primary e o standby. Também garantido o recebimento e aplicação dos mesmos pelo standby.

Antes de prosseguirmos, eu acredito que seja importante desligar temporariamente (será ligado só no fim do processo) o log_archive_dest que aponta para o standby. Caso você tenha alguma instância reiniciada você não verá erro por erro de envio ao destino acima definido.

SQL> ALTER SYSTEM SET log_archive_dest_state_2=DEFER SCOPE=spfile SID='*';

System altered.

SQL>

Se você quiser, defina um acrônimo para seus archives, quando usamos OFA, o seu nome pode ficar confuso para quem ainda não tem domínio:

SQL> ALTER SYSTEM SET log_archive_format='arch_%t_%s_%r.arc' SCOPE=spfile SID='*';

System altered.

SQL>

DB_FILE_NAME_CONVERT,  LOG_FILE_NAME_CONVERT e STANDBY_FILE_MANAGEMENT

Os dois primeiros parâmetros são importantes em ambientes primary e standby que diferem em sua estrutura de diretórios para datafiles/logfiles. Alguns passos acima você observou que intencionalmente o standby tem uma estrutura de diskgroups diferentes do primary. Esta diferença será corrigida aqui.

Ambos os parâmetros recebem conjunto (pares) de informações, basicamente você informa o caminho de origem e qual o caminho que o substituirá. Isso é importante, pois ao criarmos um novo datafile no primary ele será criado corretamente no standby. Na documentação da Oracle, existe a informação de que ele é considerado/avaliado em pares, o primeiro é substituído pelo segundo e assim sucessivamente (eles até comentam em expressões regulares para análise). Veja as definições abaixo:

SQL> ALTER SYSTEM SET db_file_name_convert='+DG01/maastb','+DATA/maa','+FRA/maastb','+FRA/maa' SCOPE=SPFILE SID='*';

System altered.

SQL>

Observe que aqui, caso o banco receba alguma informação quanto a criação de um datafile o caminho será substituído de ‘+DG01/maastb’ para ‘+DATA/maa’. Note que estamos definindo isso para a base atual que será a primary, mas já estamos preparando ela para caso ela vire standby os parâmetros já estejam corretos.

Fazemos a mesma coisa para os logfiles:

SQL> ALTER SYSTEM SET log_file_name_convert='+DG01/maastb','+DATA/maa','+FRA/maastb','+FRA/maa' SCOPE=spfile SID='*';

System altered.

SQL>

O parâmetro standby_file_management garante uma segurança maior no gerenciamento dos dados. Definido ele como AUTO garantimos que todo e qualquer arquivo criado ou deletado no primary será automaticamente replicado no standby. O detalhe é que ele vem desabilitado por padrão.

SQL> SHOW PARAMETER standby_file_management;

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
standby_file_management              string      MANUAL

SQL> ALTER SYSTEM SET standby_file_management=AUTO SCOPE=SPFILE SID='*';

System altered.

SQL>

FAL_SERVER

Este parâmetro define onde que a instância irá buscar os archives caso ocorra algum gap de recebimento. Pense no seguinte caso, você precisa fazer uma manutenção no seu ambiente RAC standby e desliga ele por dois dias, na volta ele terá que buscar os archives em algum lugar (geralmente a primary), esse é o parâmetro que define isso. O valor deste parâmetro deve ser igual ao que está no TNS, em RAC garanta que exista no TNS de ambas as instâncias:

SQL> ALTER SYSTEM SET fal_server=maastb SCOPE=spfile SID='*';

System altered.

SQL>

Com isso, terminamos a preparação do spfile da primary, agora vamos preparar o spfile da base standby.

TNSNAMES

Antes de continuarmos temos que editar o TNSNAMES de todas as instâncias do RAC para criar entradas para o standby. Lembre de todos os parâmetros que definimos previamente e que apontam para o TNS, ele deve casar com os valores que definimos nos parâmetros anteriores. O TNS atual (de uma instância do primary):

[oracle@rac11pri01 ~]

cat /u01/app/oracle/product/11.2.0.3/db_1/network/admin/tnsnames.ora 

# tnsnames.ora Network Configuration File: /u01/app/oracle/product/11.2.0.3/db_1/network/admin/tnsnames.ora 
# Generated by Oracle configuration tools. MAA =   (DESCRIPTION =     (ADDRESS = (PROTOCOL = TCP)(HOST = rac11pri-scan.tjsc.jus.br)(PORT = 1521))     (CONNECT_DATA =       (SERVER = DEDICATED)       (SERVICE_NAME = maa)     )   ) 

[oracle@rac11pri01 ~]$

Vamos editar ele e adicionar a entrada para o standby (observe que foi adicionado o MAASTB):

[oracle@rac11pri01 ~]

vi /u01/app/oracle/product/11.2.0.3/db_1/network/admin/tnsnames.ora 
[oracle@rac11pri01 ~]$ 
[oracle@rac11pri01 ~]$ 
[oracle@rac11pri01 ~] cat /u01/app/oracle/product/11.2.0.3/db_1/network/admin/tnsnames.ora 
# tnsnames.ora Network Configuration File: /u01/app/oracle/product/11.2.0.3/db_1/network/admin/tnsnames.ora 
# Generated by Oracle configuration tools. MAA =   (DESCRIPTION =     (ADDRESS = (PROTOCOL = TCP)(HOST = rac11pri-scan.tjsc.jus.br)(PORT = 1521))     (CONNECT_DATA =       (SERVER = DEDICATED)       (SERVICE_NAME = maa)     )   ) MAASTB =   (DESCRIPTION =     (ADDRESS = (PROTOCOL = TCP)(HOST = rac11stb-scan.tjsc.jus.br)(PORT = 1521))     (CONNECT_DATA =       (SERVER = DEDICATED)       (SERVICE_NAME = maastb)     )   ) 
[oracle@rac11pri01 ~]$ 
[oracle@rac11pri01 ~]
tnspingmaastb TNS Ping Utility for Linux: Version 11.2.0.3.0 - Production on 30-MAR-2014 10:05:36 Copyright (c) 1997, 2011, Oracle.  
All rights reserved. Used parameter files: Used TNSNAMES adapter to resolve the alias Attempting to contact (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = rac11stb-scan.tjsc.jus.br)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = maastb))) OK (10 msec) 
[oracle@rac11pri01 ~]$

Como TNS foi editado em único nó para economizar tempo você copia ele (através do scp mesmo) entre todos os nós do primary e para todos os nós do standby:

[oracle@rac11pri01~] scp /u01/app/oracle/product/11.2.0.3/db_1/network/admin/tnsnames.ora rac11pri02:/u01/app/oracle/product/11.2.0.3/db_1/network/admin/tnsnames.ora tnsnames.ora                                                                                                                                                                                               100%  534     0.5KB/s   00:00 
[oracle@rac11pri01 ~] scp /u01/app/oracle/product/11.2.0.3/db_1/network/admin/tnsnames.ora rac11stb01:/u01/app/oracle/product/11.2.0.3/db_1/network/admin/tnsnames.ora oracle@rac11stb01's 
password: tnsnames.ora                                                                                                                                                                                               100%  534     0.5KB/s   00:00 
[oracle@rac11pri01 ~] scp /u01/app/oracle/product/11.2.0.3/db_1/network/admin/tnsnames.ora rac11stb02:/u01/app/oracle/product/11.2.0.3/db_1/network/admin/tnsnames.ora oracle@rac11stb02's password: tnsnames.ora                                                                                                                                                                                               100%  534     0.5KB/s   00:00 [oracle@rac11pri01 ~]$

PREPARANDO STANDBY, SPFILE e DIRETÓRIOS

Depois do SPFILE da primary e do TNS configurado podemos começar os ajustes dospfile da stanby. Tomamos como base o spfile da primaryfazendo uma cópia e enviando ela para o RAC standby:

SQL> CREATE PFILE = '/tmp/pfile-primary.ora' FROM spfile;

File created.

SQL> exit

Disconnected from Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production

With the Partitioning, Real Application Clusters and Automatic Storage Management options

[oracle@rac11pri01 ~]$

[oracle@rac11pri01 ~] scp /tmp/pfile-primary.ora oracle@rac11stb01:/tmp/pfile-primary-standby.ora oracle@rac11stb01's password: pfile-primary.ora                                                                                                                                                                                          100% 1854     1.8KB/s   00:00 
[oracle@rac11pri01 ~]$

Depois de copiado vamos editar os parâmetros abaixo no spfile que foi copiado para o standby:

-audit_file_dest: local novo, precisamos ajustar para o nome correto.

-control_files: mesmo motivo do acima. Observe que foi alterado para +DG01 ao invés de +DATA

-db_create_file_dest: voltamos ao mesmo ponto, a estrutura de diskgroups é diferente do primary.

-db_file_name_convert: aqui invertemos as duplas definidas, lembre-se que estamos no standby

-db_unique_name: lembre da definição de tópicos anteriores, no standby este parâmetro recebe um valor distinto do primary.

-fal_server: o standby recorre ao primary.

-log_archive_dest_1: uma simples mudança, o que estava “MAA” vira “MAASTB”

-log_archive_dest_2: o contrário do anterior, o que era “MAASTB” vira “MAA”

-log_file_name_convert: mesmo caso do db_file_name_convert, invertemos os valores.

-remote_listener: ele deve apontar para o servidor que hospeda o standby.

-maaX.*: todos os parâmetros que referenciavam instâncias específicas do primary foram substituídas para as equivalentes do standby (seguindo o definido pelo db_unique_name).

Observe como ficou o pfile editado:

[oracle@rac11stb01 ~] vi /tmp/pfile-primary-standby.ora [oracle@rac11stb01 ~]
[oracle@rac11stb01 ~] cat /tmp/pfile-primary-standby.ora *.audit_file_dest='/u01/app/oracle/admin/maastb/adump' *.audit_trail='db' *.cluster_database=true *.compatible='11.2.0.0.0' *.control_files='+DG01/maastb/controlfile/current.273.843488553','+FRA/maastb/controlfile/current.256.843488553' *.db_block_size=8192 *.db_create_file_dest='+DG01' *.db_domain='' *.db_file_name_convert='+DATA/maa','+DG01/maastb','+FRA/maa','+FRA/maastb' *.db_name='maa' *.db_recovery_file_dest='+FRA' *.db_recovery_file_dest_size=10737418240 *.db_unique_name='maastb' *.diagnostic_dest='/u01/app/oracle' *.fal_server='MAA' maastb1.instance_number=1 maastb2.instance_number=2 *.log_archive_config='DG_CONFIG=(maa,maastb)' *.log_archive_dest_1='LOCATION=USE_DB_RECOVERY_FILE_DEST VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=maastb' *.log_archive_dest_2='SERVICE=maa SYNC AFFIRM LGWR VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=maa' *.log_archive_dest_state_2='DEFER' *.log_archive_format='arch_%t_%s_%r.arc' *.log_file_name_convert='+DATA/maa','+DG01/maastb','+FRA/maa','+FRA/maastb' *.open_cursors=300 *.pga_aggregate_target=268435456 *.processes=150 *.remote_listener='rac11stb-scan.tjsc.jus.br:1521' *.remote_login_passwordfile='exclusive' *.sga_target=1073741824 *.standby_file_management='AUTO' maastb2.thread=2 maastb1.thread=1 maastb1.undo_tablespace='UNDOTBS1' maastb2.undo_tablespace='UNDOTBS2' [oracle@rac11stb01 ~]$

Para terminar a configuração do standby precisamos ajustar dois detalhes: adump e pasword file. São dois passos simples, no primeiro são criados os diretórios no standby e no segundo o arquivo de senhas do primary é copiado para o standby (precisa ser o mesmo em todos os nós):

No standby

[oracle@rac11stb01 ~] mkdir -p /u01/app/oracle/admin/maastb/adump [oracle@rac11stb01 ~]$

No primary

[oracle@rac11pri01 ~] cd $ORACLE_HOME/dbs 
[oracle@rac11pri01 dbs]
scp /u01/app/oracle/product/11.2.0.3/db_1/dbs/orapwmaa1 oracle@rac11stb01:/u01/app/oracle/product/11.2.0.3/db_1/dbs/orapwmaastb1 oracle@rac11stb01's password: orapwmaa1                                                                                                                                                                                                  100% 1536     1.5KB/s   00:00 
[oracle@rac11pri01 dbs] scp /u01/app/oracle/product/11.2.0.3/db_1/dbs/orapwmaa1 oracle@rac11stb02:/u01/app/oracle/product/11.2.0.3/db_1/dbs/orapwmaastb2 oracle@rac11stb02's password: orapwmaa1                                                                                                                                                                                                  100% 1536     1.5KB/s   00:00 [oracle@rac11pri01 dbs]$

BACKUP, RESTORE E CLONE

Aqui vamos entrar em um ponto que necessita atenção e pode variar de caso a caso. Neste artigo tentarei cobrir 3 métodos de clone. O primeiro é através de backup e restore do banco de dados utilizando backup copiado (backupsets) do primary para o standby. O segundo modo é através de clone com ACTIVE DATABASE. O terceiro é um exemplo resumido de um clone com MML.

Clone com backup local

O primeiro exemplo de clone é criando ostandby utilizando um backup do primary. Este backup é copiado ao standby para que seja possível acessá-lo localmente a partir do standby. Isso as vezes fica complicado devido aotamanho da base de dados, uma base de 2TB necessita que você tenha este espaço disponível no filesystem do sistema operacional dostandby. A título de exemplo, vamos seguir com este exemplo.

O primeiro passo é ir naprimary e realizar um backup full da base de dados. Repare que não será feito backup do controlfile. O backup do controlfiletem uma função (e comandos específicos e eu prefiro fazer ele separado).

Observe abaixo os comandos executados (a saída foi reduzida para ficar menor e caber no artigo)

Comando executado:

    RUN {

        BACKUP FULL FORMAT '/tmp/bkpf-data-D-%d-DBID-%I-T-%T-NB-%s.bkp' DATABASE TAG 'BKP-FULL';

        SQL 'ALTER SYSTEM ARCHIVE LOG CURRENT';

        BACKUP FORMAT '/tmp/bkpf-arch-D-%d-DBID-%I-T-%T-NB-%s.bkp' ARCHIVELOG ALL TAG 'BKP-FULL-ARCH';

        BACKUP FORMAT '/tmp/bkp-spf-D-%d-DBID-%I-T-%T-NB-%s.bkp' SPFILE TAG 'BKP-FULL-SPFILE';

    }

[oracle@rac11pri01 ~] rman target / Recovery Manager: Release 11.2.0.3.0 - Production on Sun Mar 30 13:09:17 2014 Copyright (c) 1982, 2011, Oracle and/or its affiliates.  All rights reserved. connected to target database: MAA (DBID=722024964) RMAN>  RUN { 2>     BACKUP FULL FORMAT '/tmp/bkpf-data-D-%d-DBID-%I-T-%T-NB-%s.bkp' DATABASE TAG 'BKP-FULL'; 3>     SQL 'ALTER SYSTEM ARCHIVE LOG CURRENT'; 4>     BACKUP FORMAT '/tmp/bkpf-arch-D-%d-DBID-%I-T-%T-NB-%s.bkp' ARCHIVELOG ALL TAG 'BKP-FULL-ARCH'; 5>     BACKUP FORMAT '/tmp/bkp-spf-D-%d-DBID-%I-T-%T-NB-%s.bkp' SPFILE TAG 'BKP-FULL-SPFILE'; 6> } Starting backup at 30-MAR-14 using target database control file instead of recovery catalog allocated channel: ORA_DISK_1 channel ORA_DISK_1: SID=32 instance=maa1 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=00001 name=+DATA/maa/datafile/system.270.843488557 inputdatafile file number=00002 name=+DATA/maa/datafile/sysaux.269.843488563 ... ... ... channel ORA_DISK_1: starting piece 1 at 30-MAR-14 channel ORA_DISK_1: finished piece 1 at 30-MAR-14 piece handle=/tmp/bkp-spf-D-MAA-DBID-722024964-T-20140330-NB-4.bkp tag=BKP-FULL-SPFILE comment=NONE channel ORA_DISK_1: backup set complete, elapsed time: 00:00:01 Finished backup at 30-MAR-14 RMAN>

Como disse e observado acima não temos backup do controlfile e ele é fundamental para a criação do standby. Observe que ele é específico para criar o standby, FOR STANDBY.

Eu prefiro fazer ele separado e para disco local. Se você estivesse usando MML, você poderia enviar seu backup para a fita e o controlfile ficaria local. É uma preferência minha, se você quiser enviar tudo para a MML ou executar tudo no passo anterior, sem problema.

RUN {

    BACKUP FORMAT '/tmp/bkp-ctf-D-%d-DBID-%I-T-%T-NB-%s.bkp' CURRENT CONTROLFILE FOR STANDBY TAG 'BKP-FULL-CONTROL';

}

RMAN> RUN {

    BACKUP FORMAT '/tmp/bkp-ctf-D-%d-DBID-%I-T-%T-NB-%s.bkp' CURRENT CONTROLFILE FOR STANDBY TAG 'BKP-FULL-CONTROL';

}2> 3>

Starting backup at 30/03/2014 13:14:12

using channel ORA_DISK_1

channel ORA_DISK_1: starting full datafile backup set

channel ORA_DISK_1: specifying datafile(s) in backup set

including standby control file in backup set

channel ORA_DISK_1: starting piece 1 at 30/03/2014 13:14:13

channel ORA_DISK_1: finished piece 1 at 30/03/2014 13:14:14

piece handle=/tmp/bkp-ctf-D-MAA-DBID-722024964-T-20140330-NB-6.bkp tag=BKP-FULL-CONTROL comment=NONE

channel ORA_DISK_1: backup set complete, elapsed time: 00:00:01

Finished backup at 30/03/2014 13:14:14

RMAN>

Com os backups em mão, vamos copiar eles para o standby.

[oracle@rac11pri01 ~] scp /tmp/bkp* oracle@rac11stb01:/tmp/ oracle@rac11stb01's password: bkp-ctf-D-MAA-DBID-722024964-T-20140330-NB-6.bkp                                                                                                                                                           100%   18MB   8.8MB/s   00:02 bkpf-arch-D-MAA-DBID-722024964-T-20140330-NB-3.bkp                                                                                                                                                         100%  144MB  12.0MB/s   00:12 bkpf-data-D-MAA-DBID-722024964-T-20140330-NB-1.bkp                                                                                                                                                         100%  299MB  11.5MB/s   00:26 bkpf-data-D-MAA-DBID-722024964-T-20140330-NB-2.bkp                                                                                                                                                         100%   18MB   8.9MB/s   00:02 bkp-spf-D-MAA-DBID-722024964-T-20140330-NB-4.bkp                                                                                                                                                           100%   96KB  96.0KB/s   00:00 [oracle@rac11pri01 ~]$

Com o backup copiado para o standby é possível iniciar o banco. Iniciamos o standby em modo nomountcom o pfile que editamos previamente e iniciamos o clone.Subindo o banco em NOMOUNT com o pfile editado:

SQL> STARTUP PFILE='/tmp/pfile-primary-standby.ora' NOMOUNT;

ORACLE instance started.

Total System Global Area 1068937216 bytes

Fixed Size                  2235208 bytes

Variable Size             339739832 bytes

Database Buffers          721420288 bytes

Redo Buffers                5541888 bytes

SQL>

Como é a primeira vez que estamos iniciando a instância do standby é interessante observar o alertlog para ver se todos os parâmetros foram aceitos corretamente. Verifique os parâmetros que modificamos previamente neste PFILE:

[oracle@rac11stb01 ~] tail -1000f /u01/app/oracle/diag/rdbms/maastb/maastb1/trace/alert_maastb1.log Sun Mar 30 13:19:03 2014 Starting ORACLE instance (normal) ... ...         Using parameter settings in client-side pfile /tmp/pfile-primary-standby.ora on machine rac11stb01.tjsc.jus.br System parameters with non-default values:   processes                = 150   sga_target               = 1G   control_files            = "+DG01/maastb/controlfile/current.273.843488553"   control_files            = "+FRA/maastb/controlfile/current.256.843488553"   db_file_name_convert     = "+DATA/maa"   db_file_name_convert     = "+DG01/maastb"   db_file_name_convert     = "+FRA/maa"   db_file_name_convert     = "+FRA/maastb"   log_file_name_convert    = "+DATA/maa"   log_file_name_convert    = "+DG01/maastb"   log_file_name_convert    = "+FRA/maa"   log_file_name_convert    = "+FRA/maastb"   db_block_size            = 8192   compatible               = "11.2.0.0.0"   log_archive_dest_1       = "LOCATION=USE_DB_RECOVERY_FILE_DEST VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=maastb"   log_archive_dest_2       = "SERVICE=maa SYNC AFFIRM LGWR VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=maa"   log_archive_dest_state_2 = "DEFER"   fal_server               = "MAA"   log_archive_config       = "DG_CONFIG=(maa,maastb)"   log_archive_format       = "arch_%t_%s_%r.arc"   cluster_database         = TRUE   db_create_file_dest      = "+DG01"   db_recovery_file_dest    = "+FRA"   db_recovery_file_dest_size= 10G   standby_file_management  = "AUTO"   thread                   = 1   undo_tablespace          = "UNDOTBS1"   instance_number          = 1   remote_login_passwordfile= "EXCLUSIVE"   db_domain                = ""   remote_listener          = "rac11stb-scan.tjsc.jus.br:1521"   audit_file_dest          = "/u01/app/oracle/admin/maastb/adump"   audit_trail              = "DB"   db_name                  = "maa"   db_unique_name           = "maastb"   open_cursors             = 300   pga_aggregate_target     = 256M   diagnostic_dest          = "/u01/app/oracle" Cluster communication is configured to use the following interface(s) for this instance   169.254.172.112 cluster interconnect IPC version:Oracle UDP/IP (generic) ... ... List of instances:  1 (myinst: 1)  Global Resource Directory frozen * allocate domain 0, invalid = TRUE  Communication channels reestablished ... ...

Como tudo “subiu” com sucesso, vamos clonar o banco. Observe a forma de conexão ao RMAN e que os arquivos estão locais no nó desta instância.

Quanto a conexão um detalhe importante no RAC.Se você especificar no “auxiliary”, por exemplo “sys@maastb”, poderia ter um problema com o listener. O problema reside no fato de que não tem como especificar em que nó a conexão será feita, se tiver sorte será no mesmo nó que você está. Assim, você pode deixar vazio que a conexão será no nó local.

Após a conexão feita é possível clonar o banco para o standby a partir do backup que está armazenado localmente.

oracle@rac11stb01 tmp] rman target sys@maa auxiliary sys Recovery Manager: Release 11.2.0.3.0 - Production on Sun Mar 30 13:39:01 2014 Copyright (c) 1982, 2011, Oracle and/or its affiliates.  All rights reserved. target database Password: connected to target database: MAA (DBID=722024964) auxiliary database Password: connected to auxiliary database: MAA (not mounted) RMAN> RUN {     ALLOCATE AUXILIARY CHANNEL d1 DEVICE TYPE DISK FORMAT = '/tmp/bkp-ctf-D-%d-DBID-%I-T-%T-NB-%s.bkp';     DUPLICATE TARGET DATABASE FOR STANDBY NOFILENAMECHECK; }2> 3> 4> using target database control file instead of recovery catalog allocated channel: d1 channel d1: SID=18 instance=maastb1 device type=DISK Starting Duplicate Db at 30-MAR-14 contents of Memory Script: {    restore clone standby controlfile; } executing Memory Script Starting restore at 30-MAR-14 channel d1: starting datafile backup set restore channel d1: restoring control file channel d1: reading from backup piece /tmp/bkp-ctf-D-MAA-DBID-722024964-T-20140330-NB-6.bkp channel d1: piece handle=/tmp/bkp-ctf-D-MAA-DBID-722024964-T-20140330-NB-6.bkp tag=BKP-FULL-CONTROL channel d1: restored backup piece 1 channel d1: restore complete, elapsed time: 00:00:06 output file name=+DG01/maastb/controlfile/current.265.843594121 output file name=+FRA/maastb/controlfile/current.260.843594123 Finished restore at 30-MAR-14 contents of Memory Script: {    sql clone 'alter database mount standby database'; } executing Memory Script sql statement: alter database mount standby database RMAN-05529: WARNING: DB_FILE_NAME_CONVERT resulted in invalid ASM names; names changed to disk group only. contents of Memory Script: {    setnewname for tempfile  1 to  "+dg01";    switch clone tempfile all;    setnewname for datafile  1 to  "+dg01";    setnewname for datafile  2 to  "+dg01";    setnewname for datafile  3 to  "+dg01";    setnewname for datafile  4 to  "+dg01";    setnewname for datafile  5 to  "+dg01";    restore    clone database    ; } executing Memory Script executing command: SET NEWNAME renamedtempfile 1 to +dg01 in control file executing command: SET NEWNAME executing command: SET NEWNAME executing command: SET NEWNAME executing command: SET NEWNAME executing command: SET NEWNAME Starting restore at 30-MAR-14 channel d1: starting datafile backup set restore channel d1: specifying datafile(s) to restore from backup set channel d1: restoring datafile 00001 to +dg01 channel d1: restoring datafile 00002 to +dg01 channel d1: restoring datafile 00003 to +dg01 channel d1: restoring datafile 00004 to +dg01 channel d1: restoring datafile 00005 to +dg01 channel d1: reading from backup piece /tmp/bkpf-data-D-MAA-DBID-722024964-T-20140330-NB-1.bkp channel d1: piece handle=/tmp/bkpf-data-D-MAA-DBID-722024964-T-20140330-NB-1.bkp tag=BKP-FULL channel d1: restored backup piece 1 channel d1: restore complete, elapsed time: 00:01:25 Finished restore at 30-MAR-14 contents of Memory Script: {    switch clone datafile all; } executing Memory Script datafile 1 switched to datafile copy inputdatafile copy RECID=6 STAMP=843572620 file name=+DG01/maastb/datafile/system.257.843594135 datafile 2 switched to datafile copy inputdatafile copy RECID=7 STAMP=843572620 file name=+DG01/maastb/datafile/sysaux.256.843594135 datafile 3 switched to datafile copy inputdatafile copy RECID=8 STAMP=843572620 file name=+DG01/maastb/datafile/undotbs1.262.843594137 datafile 4 switched to datafile copy inputdatafile copy RECID=9 STAMP=843572620 file name=+DG01/maastb/datafile/undotbs2.263.843594137 datafile 5 switched to datafile copy inputdatafile copy RECID=10 STAMP=843572620 file name=+DG01/maastb/datafile/users.264.843594137 Finished Duplicate Db at 30-MAR-14 releasedchannel: d1 RMAN>

Acredito que a saída acima seja auto explicativa mas fazendo uma análise detalhada obervamos que os arquivos foram convertidos corretamente em seus destinos. +DATA do primary virou +DG01 no standby (ignore o warning que ele deu, o parâmetro está correto).

Se você for ao ASM do standby verá que tudo está no seu devido lugar:

[oracle@rac11stb01 tmp]$ export ORACLE_SID=+ASM1

[oracle@rac11stb01 tmp]$ export ORACLE_HOME=/u01/app/grid/11.2.0.3

[oracle@rac11stb01 tmp] asmcmd ASMCMD> ls DG01/ FRA/ SYS01/ ASMCMD> ls DG01 MAASTB/ ASMCMD> ls FRA MAASTB/ ASMCMD> ls DG01/MAASTB/ CONTROLFILE/ DATAFILE/ ONLINELOG/ ASMCMD> ls FRA/MAASTB/ CONTROLFILE/ ONLINELOG/ ASMCMD> ASMCMD> exit [oracle@rac11stb01 ~]$

Clone com ACTIVE DATABASE

No clone realizado através do ACTIVE DATABASE você vai clonar o banco primary para o standby sem realizar qualquer backup. Você se conecta no banco primary e “manda” ele clonar um standby. Explicarei mais detalhes no decorrer dos próximos passos, o clone utilizando este método é mais complicado do que o anterior.

Diferentemente do método anterior, você precisa conectar no banco auxiliar utilizando tnsnames. Caso contrário, você verá o erro abaixo ao tentar clonar o banco:

[oracle@rac11stb01 ~] rman target sys@maa auxiliary sys 

Recovery Manager: Release 11.2.0.3.0 - Production on Sun Mar 30 14:47:40 2014 Copyright (c) 1982, 2011, Oracle and/or its affiliates.  All rights reserved. target database Password: connected to target database: MAA (DBID=722024964) auxiliary database Password: connected to auxiliary database: MAA (not mounted) RMAN> DUPLICATE TARGET DATABASE FOR STANDBY FROM ACTIVE DATABASE DORECOVER NOFILENAMECHECK; Starting Duplicate Db at 30/03/2014 14:48:15 RMAN-00571: =========================================================== RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS =============== RMAN-00571: =========================================================== RMAN-03002: failure of Duplicate Db command at 03/30/2014 14:48:16 RMAN-05501: aborting duplication of target database RMAN-06217: not connected to auxiliary database with a net service name RMAN>

Assim, o primeiro passo é criar um método de conectar diretamente na instância. Como estamos em umambiente RAC fica um pouco mais complicado, você pode ter problemas de conexão caso seja redirecionada para o nó errado. Basicamente registramos manualmente a instância.

Particularmente eu prefiro criar manualmente um listener em um único nó e direcionar as conexões do standby para ele. Este pode não ser o melhor método, mas me sinto confortável com ele.

Para isso temos que criar um listener específico no standbypara o clone em uma outra porta(observe o numero da porta, o hostname, GLOBAL_DBNAME e SID_NAME):

[oracle@rac11stb01 ~] vi /u01/app/grid/11.2.0.3/network/admin/listener.ora 
[oracle@rac11stb01 ~] cat /u01/app/grid/11.2.0.3/network/admin/listener.ora                            LISTENER_CLONE =        (DESCRIPTION_LIST =           (DESCRIPTION =              (ADDRESS_LIST =                 (ADDRESS = (PROTOCOL = TCP)(HOST = rac11stb01-vip)(PORT = 1522)                    (IP = FIRST)                 )              )              (ADDRESS_LIST =                 (ADDRESS = (PROTOCOL = TCP)(HOST = rac11stb01)(PORT = 1522)                    (IP = FIRST)                 )              )              (ADDRESS_LIST =                 (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC))              )           )         )     SID_LIST_LISTENER_CLONE =      (SID_LIST =        (SID_DESC =          (GLOBAL_DBNAME = maastb)          (ORACLE_HOME = /u01/app/oracle/product/11.2.0.3/db_1)          (SID_NAME = maastb1)        )     )

Além disso, vamos ajustar o TNS do nó standbyem estamos conectados para apontar para o hostname e porta correta do listener. Neste caso, mudamos de 1521 para 1522 e para o rac11stb01.

[oracle@rac11stb01 ~] vi /u01/app/oracle/product/11.2.0.3/db_1/network/admin/tnsnames.ora 
[oracle@rac11stb01 ~] cat /u01/app/oracle/product/11.2.0.3/db_1/network/admin/tnsnames.ora MAA =   (DESCRIPTION =     (ADDRESS = (PROTOCOL = TCP)(HOST = rac11pri-scan.tjsc.jus.br)(PORT = 1521))     (CONNECT_DATA =       (SERVER = DEDICATED)       (SERVICE_NAME = maa)     )   ) MAASTB =   (DESCRIPTION =     (ADDRESS = (PROTOCOL = TCP)(HOST = rac11stb01.tjsc.jus.br)(PORT = 1522))     (CONNECT_DATA =       (SERVER = DEDICATED)       (SERVICE_NAME = maastb)     )   ) [oracle@rac11stb01 ~]$

Depois de disso, podemos subir o novo listener e testar o tns (observe que a instância já fica registrada no listener – é isso que queremos):

[oracle@rac11stb01 ~]$ export ORACLE_HOME=/u01/app/grid/11.2.0.3

[oracle@rac11stb01 ~]$ /u01/app/grid/11.2.0.3/bin/lsnrctl start LISTENER_CLONE

LSNRCTL for Linux: Version 11.2.0.3.0 - Production on 30-MAR-2014 16:24:46

Copyright (c) 1991, 2011, Oracle.  All rights reserved.

Starting /u01/app/grid/11.2.0.3/bin/tnslsnr: please wait...

TNSLSNR for Linux: Version 11.2.0.3.0 - Production

System parameter file is /u01/app/grid/11.2.0.3/network/admin/listener.ora

Log messages written to /u01/app/oracle/diag/tnslsnr/rac11stb01/listener_clone/alert/log.xml

Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=10.17.42.52)(PORT=1522)))

Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=10.17.42.48)(PORT=1522)))

Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC)))

Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=rac11stb01-vip)(PORT=1522)(IP=FIRST)))

STATUS of the LISTENER

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

Alias                     LISTENER_CLONE

Version                   TNSLSNR for Linux: Version 11.2.0.3.0 - Production

Start Date                30-MAR-2014 16:24:46

Uptime                    0 days 0 hr. 0 min. 0 sec

Trace Level               off

Security                  ON: Local OS Authentication

SNMP                      OFF

Listener Parameter File   /u01/app/grid/11.2.0.3/network/admin/listener.ora

Listener Log File         /u01/app/oracle/diag/tnslsnr/rac11stb01/listener_clone/alert/log.xml

Listening Endpoints Summary...

  (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=10.17.42.52)(PORT=1522)))

  (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=10.17.42.48)(PORT=1522)))

  (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC)))

Services Summary...

Service "tjdgstb" has 1 instance(s).

  Instance "maastb1", status UNKNOWN, has 1 handler(s) for this service...

The command completed successfully

[oracle@rac11stb01 ~]$

[oracle@rac11stb01 ~]$ export ORACLE_HOME=/u01/app/oracle/product/11.2.0.3/db_1

[oracle@rac11stb01 ~] tnspingmaastb 

TNS Ping Utility for Linux: Version 11.2.0.3.0 - Production on 30-MAR-2014 16:27:09 Copyright (c) 1997, 2011, Oracle.  All rights reserved. Used parameter files: Used TNSNAMES adapter to resolve the alias Attempting to contact (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = rac11stb01.tjsc.jus.br)(PORT = 1522)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = maastb))) OK (0msec) [oracle@rac11stb01 ~]$

Como mudamos o listener e sua porta temporariamente precisamos que isso esteja refletido no pfile que iremos usar para subir a instância. Basta editar o pfile para apontar o parâmetro “remote_lister”para o endereço correto (observe como era e como ficou o parâmetro):

[oracle@rac11stb01 ~] cat /tmp/pfile-primary-standby.ora |grepremote_listener *.remote_listener='rac11stb-scan.tjsc.jus.br:1521' [oracle@rac11stb01 ~]
[oracle@rac11stb01 ~] vi /tmp/pfile-primary-standby.ora 
[oracle@rac11stb01 ~]
[oracle@rac11stb01 ~] cat /tmp/pfile-primary-standby.ora |grepremote_listener *.remote_listener='rac11stb01.tjsc.jus.br:1522' [oracle@rac11stb01 ~]$

Devido a forma como o clone é feito, a origem dos dados (mesmo que você inicie o procedimento da standby) será do primary para o standby. Desta forma, o TNS do primary deve apontar para os endereços configurados nos passos acima para o standby. Faça isso somente em uma instância da primary (na que você vai chamar o RMAN), modifique a porta da entrada para a 1522.

Depois desta configuração inicial, basta iniciar a instância o standby em modo nomount para iniciar o clone. Além disso, podemos testar o PFILE criado e modificado previamente quanto a falhas.

SQL> STARTUP PFILE='/tmp/pfile-primary-standby.ora' NOMOUNT;

ORACLE instance started.

Total System Global Area 1068937216 bytes

Fixed Size                  2235208 bytes

Variable Size             343934136 bytes

Database Buffers          717225984 bytes

Redo Buffers                5541888 bytes

SQL> exit

Disconnected from Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production

With the Partitioning, Real Application Clusters and Real Application Testing options

[oracle@rac11stb01 ~]$

Depois disso podemos conectar através do RMAN e realizar o clone do banco de dados. Observe na saída do comando que basicamente ele realiza um backup e um restore do banco de dados. Obviamente que isso tem uma carga considerável e pode demorar também.

Se você comparar com o método anterior a carga é a mesma, mas aqui (caso o seu banco seja grande) poderá acabar concorrendo com a sua carga de trabalho do dia a dia (você faz backup no meio do horário de pico?). Outro detalhe, a origem da conexão é da primary e não é especificada no comando do rman (observe a opçãotarget).

[oracle@rac11pri01 ~] rman target sys auxiliary sys@maastb Recovery Manager: Release 11.2.0.3.0 - Production on Sun Mar 30 17:17:00 2014 Copyright (c) 1982, 2011, Oracle and/or its affiliates.  All rights reserved. target database Password: connected to target database: MAA (DBID=722024964) auxiliary database Password: connected to auxiliary database: MAA (not mounted) RMAN> DUPLICATE TARGET DATABASE FOR STANDBY FROM ACTIVE DATABASE DORECOVER NOFILENAMECHECK; Starting Duplicate Db at 30/03/2014 17:17:10 Using target database control file instead of recovery catalog allocated channel: ORA_AUX_DISK_1 channel ORA_AUX_DISK_1: SID=19 instance=maastb1 device type=DISK contents of Memory Script: {    backup as copy reuse    targetfile  '/u01/app/oracle/product/11.2.0.3/db_1/dbs/orapwmaa1' auxiliary format  '/u01/app/oracle/product/11.2.0.3/db_1/dbs/orapwmaastb1'   ; } executing Memory Script Starting backup at 30/03/2014 17:17:11 allocated channel: ORA_DISK_1 channel ORA_DISK_1: SID=157 instance=maa1 device type=DISK Finished backup at 30/03/2014 17:17:12 contents of Memory Script: {    backup as copy current controlfile for standby auxiliary format  '+DG01/maastb/controlfile/current.265.843606857';    restore clone controlfile to  '+FRA/maastb/controlfile/current.260.843606857' from  '+DG01/maastb/controlfile/current.265.843606857';    sql clone "create spfile from memory";    shutdown clone immediate;    startup clone nomount;    sql clone "alter system set  control_files =   ''+DG01/maastb/controlfile/current.265.843606857'', ''+FRA/maastb/controlfile/current.260.843606857'' comment=  ''Set by RMAN'' scope=spfile";    shutdown clone immediate;    startup clone nomount; } executing Memory Script Starting backup at 30/03/2014 17:17:14 using channel ORA_DISK_1 channel ORA_DISK_1: starting datafile copy copying standby control file output file name=/u01/app/oracle/product/11.2.0.3/db_1/dbs/snapcf_maa1.f tag=TAG20140330T171714 RECID=1 STAMP=843585435 channel ORA_DISK_1: datafile copy complete, elapsed time: 00:00:07 Finished backup at 30/03/2014 17:17:21 Starting restore at 30/03/2014 17:17:22 using channel ORA_AUX_DISK_1 channel ORA_AUX_DISK_1: copied control file copy Finished restore at 30/03/2014 17:17:26 sql statement: create spfile from memory Oracle instance shut down connected to auxiliary database (not started) Oracle instance started Total System Global Area    1068937216 bytes Fixed Size                     2235208 bytes Variable Size                348128440 bytes Database Buffers             713031680 bytes Redo Buffers                   5541888 bytes sql statement: alter system set  control_files =   ''+DG01/maastb/controlfile/current.265.843606857'', ''+FRA/maastb/controlfile/current.260.843606857'' comment= ''Set by RMAN'' scope=spfile Oracle instance shut down connected to auxiliary database (not started) Oracle instance started Total System Global Area    1068937216 bytes Fixed Size                     2235208 bytes Variable Size                348128440 bytes Database Buffers             713031680 bytes Redo Buffers                   5541888 bytes contents of Memory Script: {    sql clone 'alter database mount standby database'; } executing Memory Script sql statement: alter database mount standby database RMAN-05529: WARNING: DB_FILE_NAME_CONVERT resulted in invalid ASM names; names changed to disk group only. contents of Memory Script: {    setnewname for tempfile  1 to  "+dg01";    switch clone tempfile all;    setnewname for datafile  1 to  "+dg01";    setnewname for datafile  2 to  "+dg01";    setnewname for datafile  3 to  "+dg01";    setnewname for datafile  4 to  "+dg01";    setnewname for datafile  5 to  "+dg01";    backup as copy reuse    datafile  1 auxiliary format  "+dg01"   datafile  2 auxiliary format  "+dg01"   datafile  3 auxiliary format  "+dg01"   datafile  4 auxiliary format  "+dg01"   datafile  5 auxiliary format  "+dg01"   ;    sql 'alter system archive log current'; } executing Memory Script executing command: SET NEWNAME renamedtempfile 1 to +dg01 in control file executing command: SET NEWNAME executing command: SET NEWNAME executing command: SET NEWNAME executing command: SET NEWNAME executing command: SET NEWNAME Starting backup at 30/03/2014 17:18:11 using channel ORA_DISK_1 channel ORA_DISK_1: starting datafile copy inputdatafile file number=00001 name=+DATA/maa/datafile/system.270.843488557 output file name=+DG01/maastb/datafile/system.264.843606915 tag=TAG20140330T171811 channel ORA_DISK_1: datafile copy complete, elapsed time: 00:01:05 channel ORA_DISK_1: starting datafile copy inputdatafile file number=00002 name=+DATA/maa/datafile/sysaux.269.843488563 output file name=+DG01/maastb/datafile/sysaux.263.843606981 tag=TAG20140330T171811 channel ORA_DISK_1: datafile copy complete, elapsed time: 00:00:55 channel ORA_DISK_1: starting datafile copy inputdatafile file number=00003 name=+DATA/maa/datafile/undotbs1.268.843488567 output file name=+DG01/maastb/datafile/undotbs1.262.843607035 tag=TAG20140330T171811 channel ORA_DISK_1: datafile copy complete, elapsed time: 00:00:25 channel ORA_DISK_1: starting datafile copy inputdatafile file number=00004 name=+DATA/maa/datafile/undotbs2.265.843488579 output file name=+DG01/maastb/datafile/undotbs2.256.843607061 tag=TAG20140330T171811 channel ORA_DISK_1: datafile copy complete, elapsed time: 00:00:25 channel ORA_DISK_1: starting datafile copy inputdatafile file number=00005 name=+DATA/maa/datafile/users.258.843488581 output file name=+DG01/maastb/datafile/users.257.843607085 tag=TAG20140330T171811 channel ORA_DISK_1: datafile copy complete, elapsed time: 00:00:03 Finished backup at 30/03/2014 17:21:05 sql statement: alter system archive log current contents of Memory Script: {    backup as copy reuse    archivelog like  "+FRA/maa/archivelog/2014_03_30/thread_2_seq_4.292.843592197" auxiliary format "+FRA"   archiveloglike  "+FRA/maa/archivelog/2014_03_30/thread_1_seq_18.537.843607269" auxiliary format "+FRA"   archiveloglike  "+FRA/maa/archivelog/2014_03_30/thread_2_seq_5.508.843607269" auxiliary format "+FRA"   ;    catalog clone start with  "+FRA";    switch clone datafileall; } executingMemory Script Starting backup at 30/03/2014 17:21:11 usingchannel ORA_DISK_1 channel ORA_DISK_1: starting archived log copy input archived log thread=2 sequence=4 RECID=8 STAMP=843592197 output file name=+FRA/maastb/archivelog/2014_03_30/thread_2_seq_4.571.843607095 RECID=0 STAMP=0 channel ORA_DISK_1: archived log copy complete, elapsed time: 00:00:01 channel ORA_DISK_1: starting archived log copy input archived log thread=1 sequence=18 RECID=9 STAMP=843607269 output file name=+FRA/maastb/archivelog/2014_03_30/thread_1_seq_18.574.843607095 RECID=0 STAMP=0 channel ORA_DISK_1: archived log copy complete, elapsed time: 00:00:03 channel ORA_DISK_1: starting archived log copy input archived log thread=2 sequence=5 RECID=10 STAMP=843607270 output file name=+FRA/maastb/archivelog/2014_03_30/thread_2_seq_5.257.843607099 RECID=0 STAMP=0 channel ORA_DISK_1: archived log copy complete, elapsed time: 00:00:03 Finished backup at 30/03/2014 17:21:18 searching for all files that match the pattern +FRA List of Files Unknown to the Database ===================================== File Name: +fra/MAASTB/ARCHIVELOG/2014_03_30/thread_2_seq_4.571.843607095 File Name: +fra/MAASTB/ARCHIVELOG/2014_03_30/thread_1_seq_18.574.843607095 File Name: +fra/MAASTB/ARCHIVELOG/2014_03_30/thread_2_seq_5.257.843607099 cataloging files... cataloging done List of Cataloged Files ======================= File Name: +fra/MAASTB/ARCHIVELOG/2014_03_30/thread_2_seq_4.571.843607095 File Name: +fra/MAASTB/ARCHIVELOG/2014_03_30/thread_1_seq_18.574.843607095 File Name: +fra/MAASTB/ARCHIVELOG/2014_03_30/thread_2_seq_5.257.843607099 datafile 1 switched to datafile copy inputdatafile copy RECID=1 STAMP=843585503 file name=+DG01/maastb/datafile/system.264.843606915 datafile 2 switched to datafile copy inputdatafile copy RECID=2 STAMP=843585503 file name=+DG01/maastb/datafile/sysaux.263.843606981 datafile 3 switched to datafile copy inputdatafile copy RECID=3 STAMP=843585503 file name=+DG01/maastb/datafile/undotbs1.262.843607035 datafile 4 switched to datafile copy inputdatafile copy RECID=4 STAMP=843585503 file name=+DG01/maastb/datafile/undotbs2.256.843607061 datafile 5 switched to datafile copy inputdatafile copy RECID=5 STAMP=843585503 file name=+DG01/maastb/datafile/users.257.843607085 contents of Memory Script: {    set until scn  435603;    recover    standby    clone database     deletearchivelog    ; } executing Memory Script executing command: SET until clause Starting recover at 30/03/2014 17:21:21 allocated channel: ORA_AUX_DISK_1 channel ORA_AUX_DISK_1: SID=145 instance=maastb1 device type=DISK starting media recovery archived log for thread 1 with sequence 18 is already on disk as file +FRA/maastb/archivelog/2014_03_30/thread_1_seq_18.574.843607095 archived log for thread 2 with sequence 5 is already on disk as file +FRA/maastb/archivelog/2014_03_30/thread_2_seq_5.257.843607099 archived log file name=+FRA/maastb/archivelog/2014_03_30/thread_1_seq_18.574.843607095 thread=1 sequence=18 archived log file name=+FRA/maastb/archivelog/2014_03_30/thread_2_seq_5.257.843607099 thread=2 sequence=5 media recovery complete, elapsed time: 00:00:01 Finishedrecoverat 30/03/2014 17:21:25 FinishedDuplicateDbat 30/03/2014 17:21:48 RMAN>

Vamos analisar a saída dos comandos acima, ele começa com um backup do password file do primary para o standby. Depois temos um script executado na standby com:

-Backup do controlfile da primary (backup para standby).

-Clone do spfile da standby.

-Restart da instância (por isso o clone anterior).

-Correção dos controlfiles na standby;

-Novo restart da standby.

-Por fim, clone da primary para a standby;

Durante o backup e restore o input é +DATA e o destino é +DG01. Isso quer dizer que ele seguiu como base o que foi definido no pfile que fez o startup da standby (você também pode verificar isso no alert da standby).

Observe a quantidade de vezes que ocorreu shutdown e startup na standby, para que isso ocorra com sucesso você precisa de um registro direto no listener. Está ai o motivo para criarmos o listener e registrarmos manualmente a instância nele.

Depois do clone concluir com sucesso é hora de colocar ordem na casa, corrigir os tnsnames e remover listener criado. No lado do primary (em ambos os nós) corrija os tns para apontar para o endereço correto (observe a definição “MAASTB”):

[oracle@rac11pri01 ~] cat /u01/app/oracle/product/11.2.0.3/db_1/network/admin/tnsnames.ora # tnsnames.ora Network Configuration File: /u01/app/oracle/product/11.2.0.3/db_1/network/admin/tnsnames.ora # Generated by Oracle configuration tools. MAA =   (DESCRIPTION =     (ADDRESS = (PROTOCOL = TCP)(HOST = rac11pri-scan.tjsc.jus.br)(PORT = 1521))     (CONNECT_DATA =       (SERVER = DEDICATED)       (SERVICE_NAME = maa)     )   ) MAASTB =   (DESCRIPTION =     (ADDRESS = (PROTOCOL = TCP)(HOST = rac11stb01.tjsc.jus.br)(PORT = 1522))     (CONNECT_DATA =       (SERVER = DEDICATED)       (SERVICE_NAME = maastb)     )   ) 
[oracle@rac11pri01 ~] vi /u01/app/oracle/product/11.2.0.3/db_1/network/admin/tnsnames.ora 
[oracle@rac11pri01 ~] cat /u01/app/oracle/product/11.2.0.3/db_1/network/admin/tnsnames.ora # tnsnames.ora Network Configuration File: /u01/app/oracle/product/11.2.0.3/db_1/network/admin/tnsnames.ora # Generated by Oracle configuration tools. MAA =   (DESCRIPTION =     (ADDRESS = (PROTOCOL = TCP)(HOST = rac11pri-scan.tjsc.jus.br)(PORT = 1521))     (CONNECT_DATA =       (SERVER = DEDICATED)       (SERVICE_NAME = maa)     )   ) MAASTB =   (DESCRIPTION =     (ADDRESS = (PROTOCOL = TCP)(HOST = rac11stb-scan.tjsc.jus.br)(PORT = 1521))     (CONNECT_DATA =       (SERVER = DEDICATED)       (SERVICE_NAME = maastb)     )   ) 
[oracle@rac11pri01 ~]$

Arrume o parâmetro remote_listener do pfile da standby:

[oracle@rac11stb01 ~] cat /tmp/pfile-primary-standby.ora |grepremote_listener *.remote_listener='rac11stb01.tjsc.jus.br:1522' [oracle@rac11stb01 ~] vi /tmp/pfile-primary-standby.ora 
[oracle@rac11stb01 ~] cat /tmp/pfile-primary-standby.ora |grepremote_listener *.remote_listener='rac11stb-scan.tjsc.jus.br:1521' [oracle@rac11stb01 ~]$

Removendo o listener utilizado no clone da standby:

[oracle@rac11stb01 ~]$ export ORACLE_HOME=/u01/app/grid/11.2.0.3

[oracle@rac11stb01 ~] lsnrctl stop 

LISTENER_CLONE LSNRCTL for Linux: Version 11.2.0.3.0 - Production on 30-MAR-2014 18:32:26 Copyright (c) 1991, 2011, Oracle.  All rights reserved. Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=rac11stb01-vip)(PORT=1522)(IP=FIRST))) The command completed successfully [oracle@rac11stb01 ~]$ [oracle@rac11stb01 ~]$ 
[oracle@rac11stb01 ~] cat /u01/app/grid/11.2.0.3/network/admin/listener.ora LISTENER=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=IPC)(KEY=LISTENER))))            # line added by Agent LISTENER_SCAN3=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=IPC)(KEY=LISTENER_SCAN3))))                # line added by Agent LISTENER_SCAN2=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=IPC)(KEY=LISTENER_SCAN2))))                # line added by Agent LISTENER_SCAN1=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=IPC)(KEY=LISTENER_SCAN1))))                # line added by Agent ENABLE_GLOBAL_DYNAMIC_ENDPOINT_LISTENER_SCAN1=ON                # line added by Agent ENABLE_GLOBAL_DYNAMIC_ENDPOINT_LISTENER_SCAN2=ON                # line added by Agent ENABLE_GLOBAL_DYNAMIC_ENDPOINT_LISTENER_SCAN3=ON                # line added by Agent ENABLE_GLOBAL_DYNAMIC_ENDPOINT_LISTENER=ON              # line added by Agent LISTENER_CLONE =    (DESCRIPTION_LIST =       (DESCRIPTION =          (ADDRESS_LIST =             (ADDRESS = (PROTOCOL = TCP)(HOST = rac11stb01-vip)(PORT = 1522)                (IP = FIRST)             )          )          (ADDRESS_LIST =             (ADDRESS = (PROTOCOL = TCP)(HOST = rac11stb01)(PORT = 1522)                (IP = FIRST)             )          )          (ADDRESS_LIST =             (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC))          )       )     ) SID_LIST_LISTENER_CLONE =  (SID_LIST =    (SID_DESC =      (GLOBAL_DBNAME = maastb)      (ORACLE_HOME = /u01/app/oracle/product/11.2.0.3/db_1)      (SID_NAME = maastb1)    ) ) 
[oracle@rac11stb01 ~] vi /u01/app/grid/11.2.0.3/network/admin/listener.ora 
[oracle@rac11stb01 ~] cat /u01/app/grid/11.2.0.3/network/admin/listener.ora 

LISTENER=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=IPC)(KEY=LISTENER))))            # line added by Agent LISTENER_SCAN3=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=IPC)(KEY=LISTENER_SCAN3))))                # line added by Agent LISTENER_SCAN2=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=IPC)(KEY=LISTENER_SCAN2))))                # line added by Agent LISTENER_SCAN1=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=IPC)(KEY=LISTENER_SCAN1))))                # line added by Agent ENABLE_GLOBAL_DYNAMIC_ENDPOINT_LISTENER_SCAN1=ON                # line added by Agent ENABLE_GLOBAL_DYNAMIC_ENDPOINT_LISTENER_SCAN2=ON                # line added by Agent ENABLE_GLOBAL_DYNAMIC_ENDPOINT_LISTENER_SCAN3=ON                # line added by Agent ENABLE_GLOBAL_DYNAMIC_ENDPOINT_LISTENER=ON              # line added by Agent [oracle@rac11stb01 ~]$

E corrigindo o tns da standby

[oracle@rac11stb01 ~] cat /u01/app/oracle/product/11.2.0.3/db_1/network/admin/tnsnames.ora 
MAA =   (DESCRIPTION =     (ADDRESS = (PROTOCOL = TCP)(HOST = rac11pri-scan.tjsc.jus.br)(PORT = 1521))     (CONNECT_DATA =       (SERVER = DEDICATED)       (SERVICE_NAME = maa)     )   ) MAASTB =   (DESCRIPTION =     (ADDRESS = (PROTOCOL = TCP)(HOST = rac11stb01.tjsc.jus.br)(PORT = 1522))     (CONNECT_DATA =       (SERVER = DEDICATED)       (SERVICE_NAME = maastb)     )   ) 
[oracle@rac11stb01 ~] vi /u01/app/oracle/product/11.2.0.3/db_1/network/admin/tnsnames.ora 
[oracle@rac11stb01 ~] cat /u01/app/oracle/product/11.2.0.3/db_1/network/admin/tnsnames.ora 
MAA =   (DESCRIPTION =     (ADDRESS = (PROTOCOL = TCP)(HOST = rac11pri-scan.tjsc.jus.br)(PORT = 1521))     (CONNECT_DATA =       (SERVER = DEDICATED)       (SERVICE_NAME = maa)     )   ) MAASTB =   (DESCRIPTION =     (ADDRESS = (PROTOCOL = TCP)(HOST = rac11stb-scan.tjsc.jus.br)(PORT = 1521))     (CONNECT_DATA =       (SERVER = DEDICATED)       (SERVICE_NAME = maastb)     )   ) 
[oracle@rac11stb01 ~]$

Pronto, depois destes passos você tem um standby criado através de um activedatabase. O restart da instância fica para depois (já que ainda não terminamos o processo).

Clone através de MML

O procedimento é o mesmo do duplicate(sem activedatabase), mas aqui especificando os canais para a fita. O detalhe é que você tem que ter habilitado o standby na sua MML. Peço que observe como os canais foram configurados, temos um canal que aponta para a fita e um segundo canal para disco específico para o controlfile.

Comando a ser executado:

    rmantargetsys/XXXXXXXX@oselocpdauxiliarysys/XXXXXX@oselo

    run {

    ALLOCATE AUXILIARY CHANNEL t1 DEVICE TYPE 'SBT_TAPE' PARMS 'ENV=(NSR_SERVER=mml-server,NSR_CLIENT=selodigital-st,NSR_DPRINTF=TRUE, NSR_DEBUG_FILE=/tmp/t1.log,NSR_DEBUG_LEVEL=2)';

    ALLOCATE AUXILIARY CHANNEL d1 DEVICE TYPE DISK FORMAT = '/tmp/bkp-ctf-D-%d-DBID-%I-T-%T-NB-%s.bkp';

    DUPLICATE TARGET DATABASE FOR STANDBY NOFILENAMECHECK;

    }    

-bash-3.00

rman target sys/XXXXXXX@oselocpd auxiliary sys/XXXXXXX@oselo Recovery Manager: Release 10.2.0.5.0 - Production on Wed Aug 7 17:10:32 2013 Copyright (c) 1982, 2007, Oracle.  All rights reserved. connected to target database: OSELO (DBID=2831035320) connected to auxiliary database: OSELO (not mounted) RMAN> run { ALLOCATE AUXILIARY CHANNEL t1 DEVICE TYPE 'SBT_TAPE' PARMS 'ENV=(NSR_SERVER=mml-server,NSR_CLIENT=selodigital-st,NSR_DPRINTF=TRUE, NSR_DEBUG_FILE=/tmp/t1.log,NSR_DEBUG_LEVEL=2)'; 2> 3> ALLOCATE AUXILIARY CHANNEL d1 DEVICE TYPE DISK FORMAT = '/tmp/bkp-ctf-D-%d-DBID-%I-T-%T-NB-%s.bkp'; DUPLICATE TARGET DATABASE FOR STANDBY NOFILENAMECHECK; 4> 5> } using target database control file instead of recovery catalog allocated channel: t1 channel t1: sid=155 devtype=SBT_TAPE channel t1: NMO v5.0.0.0 allocated channel: d1 channel d1: sid=154 devtype=DISK Starting Duplicate Db at 07-AUG-13 contents of Memory Script: {    restore clone standby controlfile;    sql clone 'alter database mount standby database'; } executing Memory Script Starting restore at 07-AUG-13 channel d1: starting datafilebackupset restore channel d1: restoring control file channel d1: reading from backup piece /tmp/bkp-ctf-D-OSELO-DBID-2831035320-T-20130807-NB-6297.bkp channel d1: restored backup piece 1 piece handle=/tmp/bkp-ctf-D-OSELO-DBID-2831035320-T-20130807-NB-6297.bkp tag=BKP-FULL-CONTROL-STB channel d1: restore complete, elapsed time: 00:00:11 outputfilename=+DATA/oselo/controlfile/current.280.822849075 outputfilename=+DATA/oselo/controlfile/current.279.822849075 Finished restore at 07-AUG-13 sql statement: alter database mount standby database WARNING: DB_FILE_NAME_CONVERT resulted in invalid ASM names; names changed to diskgroup only. contents of Memory Script: {    setnewname for tempfile  1 to  "+data";    switch clone tempfile all;    setnewname for datafile  1 to  "+data";    setnewname for datafile  2 to  "+data";    setnewname for datafile  3 to  "+data";    setnewname for datafile  4 to  "+data";    setnewname for datafile  5 to  "+data";    setnewname for datafile  6 to  "+data";    setnewname for datafile  7 to  "+data";    setnewname for datafile  8 to  "+data";    setnewname for datafile  9 to  "+data";    restore    checkreadonly    clone database    ; } executing Memory Script executing command: SET NEWNAME renamed temporary file 1 to +data in control file executing command: SET NEWNAME executing command: SET NEWNAME executing command: SET NEWNAME executing command: SET NEWNAME executing command: SET NEWNAME executing command: SET NEWNAME executing command: SET NEWNAME executing command: SET NEWNAME executing command: SET NEWNAME Starting restore at 07-AUG-13 channel t1: starting datafilebackupset restore channel t1: specifying datafile(s) to restore from backup set restoringdatafile 00007 to +DATA restoringdatafile 00008 to +DATA channel t1: reading from backup piece bkpi0-data-D-OSELO-DBID-2831035320-T-20130806-NB-6288.bkp channel t1: restored backup piece 1 piece handle=bkpi0-data-D-OSELO-DBID-2831035320-T-20130806-NB-6288.bkp tag=BKP-INCR0-DB channel t1: restore complete, elapsed time: 01:09:16 channel t1: starting datafilebackupset restore channel t1: specifying datafile(s) to restore from backup set restoringdatafile 00001 to +DATA restoringdatafile 00002 to +DATA restoringdatafile 00003 to +DATA restoringdatafile 00004 to +DATA restoringdatafile 00005 to +DATA restoringdatafile 00006 to +DATA channel t1: reading from backup piece bkpi0-data-D-OSELO-DBID-2831035320-T-20130806-NB-6289.bkp channel t1: restored backup piece 1 piece handle=bkpi0-data-D-OSELO-DBID-2831035320-T-20130806-NB-6289.bkp tag=BKP-INCR0-DB channel t1: restore complete, elapsed time: 00:50:46 channel t1: starting datafilebackupset restore channel t1: specifying datafile(s) to restore from backup set restoringdatafile 00009 to +DATA channel t1: reading from backup piece bkpi0-data-D-OSELO-DBID-2831035320-T-20130806-NB-6290.bkp channel t1: restored backup piece 1 piece handle=bkpi0-data-D-OSELO-DBID-2831035320-T-20130806-NB-6290.bkp tag=BKP-INCR0-DB channel t1: restore complete, elapsed time: 00:04:45 Finishedrestoreat 07-AUG-13 contents of Memory Script: {    switch clone datafile all; } executing Memory Script datafile 1 switched to datafile copy

MONTANDO A BASE DE DADOS

Depois de clonar o banco você pode montar o banco de dados. Eu recomento realizar um shutdown do standby e um startup com o pfile, principalmente pela necessidade de corrigir o parâmetro que aponta para os controlfiles. Existe a necessidade de correção, pois com OFA, no restore/clone novos nomes são gerados.

Para verificar, basta ir no ASM identificar eles e corrigir o pfile:

[oracle@rac11stb01 ~]$ export ORACLE_HOME=/u01/app/grid/11.2.0.3

[oracle@rac11stb01 ~]$ export ORACLE_SID=+ASM1

[oracle@rac11stb01 ~] asmcmd ASMCMD> ls +DG01/MAASTB/CONTROLFILE/ Current.265.843606857 ASMCMD> ls +FRA/MAASTB/CONTROLFILE/ Current.260.843606857 ASMCMD> exit 
[oracle@rac11stb01 ~] cat /tmp/pfile-primary-standby.ora |grep control *.control_files='+DG01/maastb/controlfile/current.273.843488553','+FRA/maastb/controlfile/current.256.843488553' [oracle@rac11stb01 ~]$ 
[oracle@rac11stb01 ~] vi /tmp/pfile-primary-standby.ora 
[oracle@rac11stb01 ~] cat /tmp/pfile-primary-standby.ora |grep control *.control_files='+DG01/maastb/controlfile/current.265.843606857','+FRA/maastb/controlfile/current.260.843606857' [oracle@rac11stb01 ~]$

Após a edição do pfile, a base standby pode ser montada (uma instância só até o momento).

[oracle@rac11stb01 ~]$ export ORACLE_HOME=/u01/app/oracle/product/11.2.0.3/db_1

[oracle@rac11stb01 ~]$ export ORACLE_SID=maastb1

[oracle@rac11stb01 ~] sqlplus / as sysdba 

SQL*Plus: Release 11.2.0.3.0 Production on Sun Mar 30 19:01:38 2014 Copyright (c) 1982, 2011, Oracle.  All rights reserved. Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production With the Partitioning, Real Application Clusters, Automatic Storage Management and Real Application Testing options SQL> shutdown immediate; ORA-01109: database not open Database dismounted. ORACLE instance shut down. SQL> STARTUP PFILE='/tmp/pfile-primary-standby.ora' MOUNT; ORACLE instance started. Total System Global Area 1068937216 bytes Fixed Size                  2235208 bytes Variable Size             343934136 bytes Database Buffers          717225984 bytes Redo Buffers                5541888 bytes Databasemounted. SQL>

Pronto, agora você tem uma instância standby criada e montada através de um clone da primary que já aponta para os controlfiles corretos.

STANDBY LOGS

Você até poderia habilitar o DG, mas não estaria como desejamos, você não conseguiria abrir ela com um grau de proteção ideal para MAA. Para que isso seja possível, temos que criar o os standbyredo logs.

Standbyredo logs são idênticos aos redo logs. Eles são utilizados como destino das informações (de redo) recebidas da primary. Quando ocorre um log switch na primary, existe um standbyredo log switch na standby e este é arquivado através de um processo ARCn (você pode ler isso no documento Oracle Data Guard Concepts and Administration).

Na documentação fica claro a necessidade de criar um standbyredo log a mais do que os redo log groups existentes na primary. Existe uma fórmula para calcular o número correto em um ambiente RAC:

( (# de redo logs por instância) + 1 ) x ( # de instâncias )  (Referência existente neste documento)

Em um ambiente com duas instâncias que tem 2 grupos você teria que criar 6 standbyredo logs. Sendo que estes seriam divididos em 3 grupos por instância. Vejamos no nosso caso:

SQL> SELECT group#, thread#, bytes FROM v$log;

    GROUP#    THREAD#      BYTES

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

         1          1   52428800

         2          1   52428800

         3          2   52428800

         4          2   52428800

SQL>

Aqui temos 2 instâncias que tem 4 grupos de redo (dois por instância). Consequentemente através da fórmula calculamos que teremos que criar 6 standby redo log groups (divididos 3 para cada instância):

SQL> ALTER DATABASE ADD STANDBY LOGFILE THREAD 1 SIZE 52428800;

Database altered.

SQL> ALTER DATABASE ADD STANDBY LOGFILE THREAD 1 SIZE 52428800;

Database altered.

SQL> ALTER DATABASE ADD STANDBY LOGFILE THREAD 1 SIZE 52428800;

Database altered.

SQL> ALTER DATABASE ADD STANDBY LOGFILE THREAD 2 SIZE 52428800;

Database altered.

SQL> ALTER DATABASE ADD STANDBY LOGFILE THREAD 2 SIZE 52428800;

Database altered.

SQL> ALTER DATABASE ADD STANDBY LOGFILE THREAD 2 SIZE 52428800;

Database altered.

SQL>

SQL> SELECT group#, thread# FROM v$standby_log;

    GROUP#    THREAD#

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

         5          1

         6          1

         7          1

         8          2

         9          2

        10          2

6 rows selected.

SQL>

Para verificar como ficamos poder executar o SQL abaixo. Observe a quantidade e standby logs groups:

SQL> COL MEMBER FORMAT A60

SQL> SELECT group#, type, member FROM v$logfile;

    GROUP# TYPE    MEMBER

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

         1 ONLINE  +DATA/maa/onlinelog/group_1.272.843488553

         1 ONLINE  +FRA/maa/onlinelog/group_1.286.843488555

         2 ONLINE  +DATA/maa/onlinelog/group_2.271.843488555

         2 ONLINE  +FRA/maa/onlinelog/group_2.285.843488555

         3 ONLINE  +DATA/maa/onlinelog/group_3.257.843489101

         3 ONLINE  +FRA/maa/onlinelog/group_3.284.843489101

         4 ONLINE  +DATA/maa/onlinelog/group_4.262.843489103

         4 ONLINE  +FRA/maa/onlinelog/group_4.283.843489103

         5 STANDBY +DATA/maa/onlinelog/group_5.263.843615365

         5 STANDBY +FRA/maa/onlinelog/group_5.289.843615367

         6 STANDBY +DATA/maa/onlinelog/group_6.261.843615373

    GROUP# TYPE    MEMBER

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

         6 STANDBY +FRA/maa/onlinelog/group_6.670.843615373

         7 STANDBY +DATA/maa/onlinelog/group_7.260.843615379

         7 STANDBY +FRA/maa/onlinelog/group_7.263.843615379

         8 STANDBY +DATA/maa/onlinelog/group_8.259.843615383

         8 STANDBY +FRA/maa/onlinelog/group_8.703.843615385

         9 STANDBY +DATA/maa/onlinelog/group_9.256.843615389

         9 STANDBY +FRA/maa/onlinelog/group_9.504.843615389

        10 STANDBY +DATA/maa/onlinelog/group_10.274.843615393

        10 STANDBY +FRA/maa/onlinelog/group_10.496.843615393

20 rows selected.

SQL>

Estes grupos também precisam ser criados no standby, utilize a formula anterior, mas como temos o mesmo número de instâncias eles são criados em igual número.

[oracle@rac11stb01 ~] sqlplus / as sysdba 

SQL*Plus: Release 11.2.0.3.0 Production on Sun Mar 30 19:39:19 2014 Copyright (c) 1982, 2011, Oracle.  All rights reserved. Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production With the Partitioning, Real Application Clusters, Automatic Storage Management and Real Application Testing options 

SQL> select instance_name FROM v$instance; INSTANCE_NAME ---------------- maastb1 SQL> SELECT group#, thread#, bytes FROM v$log;     GROUP#    THREAD#      BYTES ---------- ---------- ----------          1          1   52428800          2          1   52428800          3          2   52428800          4          2   52428800 SQL> ALTER DATABASE ADD STANDBY LOGFILE THREAD 1 SIZE 52428800; Database altered. SQL> ALTER DATABASE ADD STANDBY LOGFILE THREAD 1 SIZE 52428800; Database altered. 
SQL> ALTER DATABASE ADD STANDBY LOGFILE THREAD 1 SIZE 52428800; Database altered. 
SQL> ALTER DATABASE ADD STANDBY LOGFILE THREAD 2 SIZE 52428800; Database altered. 
SQL> ALTER DATABASE ADD STANDBY LOGFILE THREAD 2 SIZE 52428800; Database altered. 
SQL> ALTER DATABASE ADD STANDBY LOGFILE THREAD 2 SIZE 52428800; Database altered. SQL> SELECT group#, thread# FROM v$standby_log;     GROUP#    THREAD# ---------- ----------          5          1          6          1          7          1          8          2          9          2         10          2 6 rows selected. 

SQL> COL MEMBER FORMAT a50 
SQL> SELECT group#, type, member FROM v$logfile;     GROUP# TYPE    MEMBER ---------- ------- --------------------------------------------------          1 ONLINE  +DG01/maastb/onlinelog/group_1.268.843607109          1 ONLINE  +FRA/maastb/onlinelog/group_1.579.843607111          2 ONLINE  +DG01/maastb/onlinelog/group_2.269.843607115          2 ONLINE  +FRA/maastb/onlinelog/group_2.568.843607117          3 ONLINE  +DG01/maastb/onlinelog/group_3.270.843607121          3 ONLINE  +FRA/maastb/onlinelog/group_3.564.843607123          4 ONLINE  +DG01/maastb/onlinelog/group_4.271.843607125          4 ONLINE  +FRA/maastb/onlinelog/group_4.562.843607129          5 STANDBY +DG01/maastb/onlinelog/group_5.267.843615577          5 STANDBY +FRA/maastb/onlinelog/group_5.559.843615581          6 STANDBY +DG01/maastb/onlinelog/group_6.266.843615585     GROUP# TYPE    MEMBER ---------- ------- --------------------------------------------------          6 STANDBY +FRA/maastb/onlinelog/group_6.553.843615589          7 STANDBY +DG01/maastb/onlinelog/group_7.261.843615593          7 STANDBY +FRA/maastb/onlinelog/group_7.604.843615595          8 STANDBY +DG01/maastb/onlinelog/group_8.260.843615599          8 STANDBY +FRA/maastb/onlinelog/group_8.600.843615601          9 STANDBY +DG01/maastb/onlinelog/group_9.259.843615607          9 STANDBY +FRA/maastb/onlinelog/group_9.611.843615611         10 STANDBY +DG01/maastb/onlinelog/group_10.258.843615615         10 STANDBY +FRA/maastb/onlinelog/group_10.591.843615617 20 rows selected. SQL>

Assim, temos tanto o primary e standby configurados para permitir o envio correto de redoentre eles. Criamos os standbyredo logs na primary para garantir que em uma eventual troca de roles já esteja tudo correto.

SPFILE/PFILE STANDBY

Independente da forma como você clona o standby tanto o spfile quanto o pfile estarão errados quanto ao seu destino, você terá que corrigir o caminho deles. Na base standby você vera que o spfile não existe:

SQL> SHOW PARAMETER spfile

NAME                                 TYPE        VALUE

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

spfile                               string

SQL>

A primeira coisa a ser feita é criar o SPFILE no local correto, neste caso estamos armazenando ele no ASM. A origem do SPFILE será o PFILE que editamos em passos anteriores e utilizamos para fazer o startup da standby:

SQL> CREATE spfile = '+DG01' FROM pfile = '/tmp/pfile-primary-standby.ora';

File created.

SQL>

Infelizmente nem tudo são flores e o SPFILE fica errado no ASM e precisa ser corrigido. O erro está no fato de que o alias que aponta para o parameterfile não ser criado. Observe:

[oracle@rac11stb01 ~]$ export ORACLE_SID=+ASM1

[oracle@rac11stb01 ~]$ export ORACLE_HOME=/u01/app/grid/11.2.0.3

[oracle@rac11stb01 ~] asmcmd 

ASMCMD> cd +DG01 
ASMCMD> cd maastb 
ASMCMD> ls -l Type  Redund  Striped  Time             Sys  Name                                         Y    CONTROLFILE/                                         Y    DATAFILE/                                         Y    ONLINELOG/                                         Y    PARAMETERFILE/ ASMCMD> ls -l PARAMETERFILE/ Type           Redund  Striped  Time             Sys  Name PARAMETERFILE  UNPROT  COARSE   APR 10 01:00:00  Y    spfile.273.844479295 ASMCMD> ASMCMD> mkalias +DG01/maastb/PARAMETERFILE/spfile.273.844479295 spfilemaastb.ora 
ASMCMD> ls -l Type           Redund  Striped  Time             Sys  Name                                                  Y    CONTROLFILE/                                                  Y    DATAFILE/                                                  Y    ONLINELOG/                                                  Y    PARAMETERFILE/                                                  N    spfilemaastb.ora => +DG01/MAASTB/PARAMETERFILE/spfile.273.844479295 ASMCMD>

Depois disso, o seu caminho do SPFILE dentro do ASM está correto e apontando para o arquivo desejado. Agora basta corrigir a pasta “dbs” existente dentro do ORACLE_HOME da instância. Lá deve ser criado um pfile/init que aponta para o SPFILE do ASM.

[oracle@rac11stb01 ~]$ export ORACLE_HOME=/u01/app/oracle/product/11.2.0.3/db_1

[oracle@rac11stb01 ~] cd $ORACLE_HOME/dbs 
[oracle@rac11stb01 dbs] ls -l 
total 28 -rw-rw---- 1 
oracle oinstall  
1544 Apr  9 19:27 hc_maastb1.dat -rw-r--r-- 1 
oracleoinstall  2851 May 15  2009 
init.ora -rw-r----- 1 
oracleoinstall  1536 Mar 30 17:14 orapwmaastb1 -rw-r----- 1 
oracleoinstall 15872 Mar 30 17:15 spfilemaastb1.ora 
[oracle@rac11stb01 dbs]$ 
[oracle@rac11stb01 dbs] rm spfilemaastb1.ora 
[oracle@rac11stb01 dbs]$ 
[oracle@rac11stb01 dbs]$ 
[oracle@rac11stb01 dbs]$ vi initmaastb1.ora 
[oracle@rac11stb01 dbs] cat initmaastb1.ora 
SPFILE='+DG01/maastb/spfilemaastb.ora' 
[oracle@rac11stb01 dbs]$

Se você observar, já existe um arquivo spfile da base standby, infelizmente em um ambiente RAC ele deve residir em um local compartilhado. Assim, removemos ele da pasta DBS.Além disso, precisamos corrigir a pasta “dbs”  do outro nó do RAC. Copiamos o arquivo do nó 1 para este nó (observe o nome correto do arquivo de destino):

[oracle@rac11stb02 ~] cd $ORACLE_HOME/dbs 
[oracle@rac11stb02 dbs] pwd /u01/app/oracle/product/11.2.0.3/db_1/dbs 
[oracle@rac11stb02 dbs] ls -l 
total 12 -rw-rw---- 1 
oracle oinstall 1544 Mar 30 15:39 hc_maastb2.dat -rw-r--r-- 1 
oracle oinstall 2851 Aug 18  2013 
init.ora 
[oracle@rac11stb02 dbs]$ 
[oracle@rac11stb02 dbs] scp oracle@rac11stb01:/u01/app/oracle/product/11.2.0.3/db_1/dbs/initmaastb1.ora initmaastb2.ora initmaastb1.ora                                                                                                                                                                                            100%   39     0.0KB/s   00:00 
[oracle@rac11stb02 dbs]$

Por fim, vamos testar o spfile da standby que está no local correto agora:

[oracle@rac11stb01 ~]$ export ORACLE_SID=maastb1

[oracle@rac11stb01 ~]sqlplus / as sysdba 

SQL*Plus: Release 11.2.0.3.0 Production on Wed Apr 9 19:48:46 2014 Copyright (c) 1982, 2011, Oracle.  All rights reserved. Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production With the Partitioning, Real Application Clusters, Automatic Storage Management and Real Application Testing options 
SQL> SHOW PARAMETER spfile NAME                                 TYPE        VALUE ------------------------------------ ----------- ------------------------------ spfile                               string SQL> SHUTDOWN IMMEDIATE; ORA-01109: database not open Database dismounted. ORACLE instance shut down. 
SQL> 
SQL> 
SQL> 
SQL> STARTUP MOUNT; 
ORACLE instance started. Total System Global Area 1068937216 bytes Fixed Size                  2235208 bytes Variable Size             343934136 bytes Database Buffers          717225984 bytes Redo Buffers                5541888 bytes Database mounted. 
SQL> 
SQL> 
SQL> SHOW PARAMETER spfile; 
NAME                                 TYPE        VALUE ------------------------------------ ----------- ------------------------------ spfile                               string      +DG01/maastb/spfilemaastb.ora SQL>

REINICIANDO A PRIMARY

Até o momento temos um ambiente onde existe um standby que foi clonado da primary e estáconfigurado para receber os redologs enviados da primary. O banco primary foi configurado para enviar os dados para o standby, mas isso ainda não foi habilitado.

Se você revisar os passos até aqui irá perceber que somente configuramos os parâmetros da primary no spfile. Fizemos toda a configuração sem qualquer interrupção da primary, sem downtime. Precisamos agora reiniciar o banco do primary para que os parâmetros modificados passem a valer.

Eu recomendo fazer isso com a base parada em ambos os nós. Recomendo abrir uma segunda seção a instância que irá subir a base primary para acompanhar o seu alert.log. Observe os passos abaixo:

[oracle@rac11pri01 ~] srvctl stop database -d maa -o immediate 
[oracle@rac11pri01 ~]$ 
[oracle@rac11pri01 ~] srvctl start instance -d maa -i maa1 
[oracle@rac11pri01 ~]$

No alert (cropado para só mostrar pontos importantes):

    [root@rac11pri01 ~]# tail -f /u01/app/oracle/diag/rdbms/maa/maa1/trace/alert_maa1.log

    NOTE: force a map free for map id 3992

    Thu Apr 10 02:32:27 2014

    Stopping background process VKTM

    NOTE: force a map free for map id 3991

    Thu Apr 10 02:32:28 2014

    NOTE: Shutting down MARK background process

    Thu Apr 10 02:32:33 2014

    freeingrdom 0

    Thu Apr 10 02:32:36 2014

    Instance shutdown complete

    ...

    ...            

    Starting up:

    Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production

    ...

    ...

    Using parameter settings in server-side pfile /u01/app/oracle/product/11.2.0.3/db_1/dbs/initmaa1.ora

    System parameters with non-default values:

      processes                = 150

      spfile                   = "+DATA/maa/spfilemaa.ora"

      sga_target               = 1G

      control_files            = "+DATA/maa/controlfile/current.273.843488553"

      control_files            = "+FRA/maa/controlfile/current.256.843488553"

      db_file_name_convert     = "+DG01/maastb"

      db_file_name_convert     = "+DATA/maa"

      db_file_name_convert     = "+FRA/maastb"

      db_file_name_convert     = "+FRA/maa"

      log_file_name_convert    = "+DG01/maastb"

      log_file_name_convert    = "+DATA/maa"

      log_file_name_convert    = "+FRA/maastb"

      log_file_name_convert    = "+FRA/maa"

      db_block_size            = 8192

      compatible               = "11.2.0.0.0"

      log_archive_dest_1       = "LOCATION=USE_DB_RECOVERY_FILE_DEST VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=maa"

      log_archive_dest_2       = "SERVICE=maastb SYNC AFFIRM LGWR VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=maastb"

      log_archive_dest_state_2 = "DEFER"

      fal_server               = "MAASTB"

      log_archive_config       = "DG_CONFIG=(maa,maastb)"

      log_archive_format       = "arch_%t_%s_%r.arc"

      cluster_database         = TRUE

      db_create_file_dest      = "+DATA"

      db_recovery_file_dest    = "+FRA"

      db_recovery_file_dest_size= 10G

      standby_file_management  = "AUTO"

      thread                   = 1

      undo_tablespace          = "UNDOTBS1"

      instance_number          = 1

      remote_login_passwordfile= "EXCLUSIVE"

      db_domain                = ""

      remote_listener          = "rac11pri-scan.tjsc.jus.br:1521"

      audit_file_dest          = "/u01/app/oracle/admin/maa/adump"

      audit_trail              = "DB"

      db_name                  = "maa"

      db_unique_name           = "maa"

      open_cursors             = 300

      pga_aggregate_target     = 256M

      diagnostic_dest          = "/u01/app/oracle"

    ...

    ...

    Reconfiguration started (old inc 0, new inc 2)

    List of instances:

     1 (myinst: 1)

    ...

    ...            

    ALTER DATABASE OPEN /* db agent *//* {1:22542:638} */

    This instance was first to open

    ...

    ...

    ARC2: Becoming the 'no FAL' ARCH

    ARC2: Becoming the 'no SRL' ARCH

    ARC1: Becoming the heartbeat ARCH

    Thu Apr 10 02:36:35 2014

    ARC3 started with pid=36, OS id=16657

    ARC3: Archival started

    ARC0: STARTING ARCH PROCESSES COMPLETE

    ...

    ...

    Completed: ALTER DATABASE OPEN /* db agent *//* {1:22542:638} */

    Thread 1 advanced to log sequence 39 (LGWR switch)

      Current log# 1 seq# 39 mem# 0: +DATA/maa/onlinelog/group_1.272.843488553

      Current log# 1 seq# 39 mem# 1: +FRA/maa/onlinelog/group_1.286.843488555

    Starting background process SMCO

    ...

    ...

Observe que não tivemos qualquer problema em abrir a base. Peço que analise com atenção a saída que mostrada acima, principalmente nos parâmetros que fazem referência ao DG (destaquei eles em negrito).Depois, basta subir a instância nos outros nós.

PROTECTION

Agora chegamos a mais um ponto importante na definição do nosso ambiente, a definição do grau de proteção do nosso ambiente. Existem três modos que descreverei abaixo, cada um tem seu grau de proteção e você deve avaliar qual o melhor para o seu ambiente.

-MAXIMUM PROTECTION: Neste modo ambas as bases primary e standby estão completamente sincronizadas, nenhuma transação é perdida ou deixa de ser enviada para o standby. Infelizmente isso tem um custo, caso o standby tenha alguma falha e fique indisponível, o primary também fica indisponível.

-MAXIMUM AVAILABILITY: Este modo trabalha de forma semelhante ao anterior, mas permite que ocorra a indisponibilidade do standby sem que isso afete o primary. Assim, o primary continua disponível para os usuários e na volta do standby ele envia os archives para que a sincronia seja restabelecida. Um detalhe, caso o standby esteja fora e ocorra uma falha no primary (perda do Storage por exemplo), as transações que não foram enviadas foram perdidas e você terá “data loss”.

-MAXIMUM PERFORMANCE: Aqui os archives são transferidos de maneira assíncrona entre o primary e o standby. Você deve estar ciente que está trabalhando com a possibilidade de perda de dados, caso ocorra uma falha com o primary você terá perdido informação.

A escolha do modo de proteção depende do projeto/ambiente que está montando, claro que a criticidade dos seus dados também influencia na escolha. Existe uma relação que as vezes não fica clara (principalmente a gestores) que quanto maior o grau de proteção, mais garantias você tem que ter sobre o seu ambiente. Não adianta montar um DG com MAXIMUM PROTECTION em um ambiente que não lhe dá as mesmas garantias do primary.

Aqui vamos utilizar e configurar o DG em MAXIMUM AVAILABILITY, você terá uma garantia de sincroniza entre primary e standby em tempo real. Isso sem deixar o seu ambiente indisponível caso seu standby resolva acordar de mau humor.

Para que possamos ter isso precisamos configurar o modo de proteção do primary, por padrão ele vem em MAXIMUM PROTECTION, precisamos aumentar isso. Observe os comandos abaixo:

SQL> SELECT protection_mode, protection_level FROM v$database;

PROTECTION_MODE      PROTECTION_LEVEL

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

MAXIMUM PERFORMANCE  MAXIMUM PERFORMANCE

SQL> ALTER DATABASE SET STANDBY TO MAXIMIZE AVAILABILITY;

Database altered.

SQL> SELECT protection_mode, protection_level FROM v$database;

PROTECTION_MODE      PROTECTION_LEVEL

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

MAXIMUM AVAILABILITY RESYNCHRONIZATION

SQL>

LIGANDO O STANDBY

Configurar modo de proteção não é tudo, você precisa fazer com que seu standy entenda que ele é um standby, explico. Até o momento você tem um clone do seu ambiente primary e só isso. Você não disse a ele que é um standby, as configurações que foram feitas no spfile não dizem nada.

Antes disso, precisamos ajustar um detalhe do seu banco standby. Quando você clonou seu banco para o standby o processo o deixou com o flashback desligado. Assim, recomendo ligar ele para evitar problemas futuros (em eventuais trocas de papeis entre primary e standby):

SQL> SELECT log_mode, flashback_on FROM v$database;

LOG_MODE     FLASHBACK_ON

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

ARCHIVELOG   NO

SQL> ALTER DATABASE FLASHBACK ON;

Database altered.

SQL> SELECT log_mode, flashback_on FROM v$database;

LOG_MODE     FLASHBACK_ON

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

ARCHIVELOG   YES

SQL>

Depois disso você pode dizer ao banco clonado que ele é um standby:

SQL> SELECT instance_name, status FROM v$instance;

INSTANCE_NAME    STATUS

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

maastb1          MOUNTED

SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT;

Database altered.

SQL>

Vamos entender o que aconteceu aqui. Primeiro, temos o seguinte comando: ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT;Isso nos diz que o banco ficará em estado de recuperação para ser standby  (RECOVER MANAGED STANDBY DATABASE) e utilizará o logfile para sincronia (USING CURRENT LOGFILE) e o comando retornará ao prompt ao fim da execução (DISCONNECT).

Indo um pouco além, você poderia não ter utilizado a opção USING CURRENT LOGFILE, mas desde o início foi dito que iríamos utilizar real-time apply. Mas o que é o real-time apply? Vou deixar a definição da documentação:

If the real-time apply feature is enabled, apply services can apply redo data as it is received, without waiting for the current standby redo log file to be archived. This results in faster switchover and failover times because the standby redo log files have been applied already to the standby databaseby the time the failover or switchover begins.

Acredito que a definição seja clara, mas resumindo, o que acontecer no redo da primary é enviado ao standby (aos standbyred logs do banco standby) e já aplicado diretamente na base antes de esperar o swicthover de redo da primary. Isso é bem interessante, pois permite uma troca de papeis bem mais rápida para o standby.

Claro que isso tem algumas implicações, no DG você pode definir um tempo (delay) quando uma transação ocorre no primary e quando ela é aplicada no standby. Com real-time apply essa definição é ignorada. Além disso, para utilizar real-time apply é necessário operar em modo síncrono o envio de redo para o standby e utilizar standbyredo logs.

A título de curiosidade, deixo o que apareceu no alert.log da instância standby no momento que executamos o comando acima:

[oracle@rac11stb01 ~]tail -f 
/u01/app/oracle/diag/rdbms/maastb/maastb1/trace/alert_maastb1.log database for recovery-related files, and does not reflect the amount of space available in the underlying filesystem or ASM diskgroup. Sat Apr 12 08:51:08 2014 ALTER DATABASE FLASHBACK ON Sat Apr 12 08:51:10 2014 RVWR started with pid=31, OS id=23476 Allocated 3981120 bytes in shared pool for flashback generation buffer Sat Apr 12 08:51:20 2014 Flashback Database Enabled at SCN 435603 Completed: ALTER DATABASE FLASHBACK ON Sat Apr 12 08:56:26 2014 ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT Attempt to start background Managed Standby Recovery process (maastb1) Sat Apr 12 08:56:26 2014 MRP0 started with pid=36, OS id=23650 MRP0: Background Managed Standby Recovery process started (maastb1) startedlogmerger process Sat Apr 12 08:56:31 2014 Managed Standby Recovery starting Real Time Apply Parallel Media Recovery started with 2 slaves Waiting for all non-current ORLs to be archived... All non-current ORLs have been archived. Sat Apr 12 08:56:33 2014 Media Recovery Waiting for thread 1 sequence 19 Completed: ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT

SINCRONIZANDO

Até agora tudo está tranquilo e temos um banco primary configurado, esperando que o standby esteja preparado para operar em MAXIMUM AVAILABILITY. Para tal ele espera enviar os dados de forma síncrona ao standby. No lado do standby temos um banco configurado e já esperando receber as informações do primary.

Assim, chegou a hora de ligar a sincronia entre os lados. Se você observar os passos anteriores verá que o destino dos archives que aponta para o standby está desligado, nada foi transferido até o momento. Observe abaixo:

SQL> SELECT inst_id, name, value FROM gv$parameter WHERE name = 'log_archive_dest_2';

   INST_ID NAME                           VALUE

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

         1 log_archive_dest_2             SERVICE=maastb SYNC AFFIRM LGW

                                          R VALID_FOR=(ONLINE_LOGFILES,P

                                          RIMARY_ROLE) DB_UNIQUE_NAME=ma

                                          astb

         2 log_archive_dest_2             SERVICE=maastb SYNC AFFIRM LGW

                                          R VALID_FOR=(ONLINE_LOGFILES,P

                                          RIMARY_ROLE) DB_UNIQUE_NAME=ma

                                          astb

SQL> SELECT inst_id, name, value FROM gv$parameter WHERE name = 'log_archive_dest_state_2';

   INST_ID NAME                           VALUE

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

         1 log_archive_dest_state_2       DEFER

         2 log_archive_dest_state_2       DEFER

SQL>

Ambas as instâncias do primary estão com seu destino que aponta para o standby em modo DEFFER (desabilitado). Para habilitar basta executar o comando abaixo:

SQL> ALTER SYSTEM SET log_archive_dest_state_2 = enable SCOPE = BOTH SID = '*';

System altered.

SQL>

Observe o que aconteceu no alertlog de ambas as instâncias (das primary e da standby):

No final observe que o dest_2 está sincronizado.

No alert da primary (este alertnão foi cropado e foi copiado de um único nó):

    [oracle@rac11pri01 ~]tail -f 
/u01/app/oracle/diag/rdbms/maa/maa1/trace/alert_maa1.log     Sat Apr 12 14:32:39 2014     Thread 1 cannot allocate new log, sequence 70     Checkpoint not complete       Current log# 1 seq# 69 mem# 0: +DATA/maa/onlinelog/group_1.272.843488553       Current log# 1 seq# 69 mem# 1: +FRA/maa/onlinelog/group_1.286.843488555     Thread 1 advanced to log sequence 70 (LGWR switch)       Current log# 2 seq# 70 mem# 0: +DATA/maa/onlinelog/group_2.271.843488555       Current log# 2 seq# 70 mem# 1: +FRA/maa/onlinelog/group_2.285.843488555     Sat Apr 12 14:32:42 2014     Archived Log entry 156 added for thread 1 sequence 69 ID 0x2b099804 dest 1:     Sat Apr 12 14:33:12 2014     ALTER SYSTEM SET log_archive_dest_state_2='ENABLE' SCOPE=BOTH SID='*';     Sat Apr 12 14:33:14 2014     ARC3: Standby redo logfile selected for thread 1 sequence 65 for destination LOG_ARCHIVE_DEST_2     Sat Apr 12 14:33:15 2014     Destination LOG_ARCHIVE_DEST_2 is UNSYNCHRONIZED     ******************************************************************     LGWR: Setting 'active' archival for destination LOG_ARCHIVE_DEST_2     ******************************************************************     LGWR: Standby redo logfile selected to archive thread 1 sequence 71     LGWR: Standby redo logfile selected for thread 1 sequence 71 for destination LOG_ARCHIVE_DEST_2     Thread 1 advanced to log sequence 71 (LGWR switch)       Current log# 1 seq# 71 mem# 0: +DATA/maa/onlinelog/group_1.272.843488553       Current log# 1 seq# 71 mem# 1: +FRA/maa/onlinelog/group_1.286.843488555     Sat Apr 12 14:33:21 2014     Archived Log entry 162 added for thread 1 sequence 70 ID 0x2b099804 dest 1:     ARC3: Standby redo logfile selected for thread 1 sequence 70 for destination LOG_ARCHIVE_DEST_2     Sat Apr 12 14:33:29 2014     Destination LOG_ARCHIVE_DEST_2 is SYNCHRONIZED     LGWR: Standby redo logfile selected to archive thread 1 sequence 72     LGWR: Standby redo logfile selected for thread 1 sequence 72 for destination LOG_ARCHIVE_DEST_2     Thread 1 advanced to log sequence 72 (LGWR switch)       Current log# 2 seq# 72 mem# 0: +DATA/maa/onlinelog/group_2.271.843488555       Current log# 2 seq# 72 mem# 1: +FRA/maa/onlinelog/group_2.285.843488555     Sat Apr 12 14:33:32 2014     Archived Log entry 174 added for thread 1 sequence 71 ID 0x2b099804 dest 1: No alert da Primary (em outro nó):     

[oracle@rac11pri02 ~]tail -f 
/u01/app/oracle/diag/rdbms/maa/maa2/trace/alert_maa2.log       Current log# 4 seq# 48 mem# 0: +DATA/maa/onlinelog/group_4.262.843489103       Current log# 4 seq# 48 mem# 1: +FRA/maa/onlinelog/group_4.283.843489103     Sat Apr 12 20:32:25 2014     Archived Log entry 154 added for thread 2 sequence 47 ID 0x2b099804 dest 1:     Sat Apr 12 20:32:39 2014     Thread 2 advanced to log sequence 49 (LGWR switch)       Current log# 3 seq# 49 mem# 0: +DATA/maa/onlinelog/group_3.257.843489101       Current log# 3 seq# 49 mem# 1: +FRA/maa/onlinelog/group_3.284.843489101     Sat Apr 12 20:32:40 2014     Archived Log entry 155 added for thread 2 sequence 48 ID 0x2b099804 dest 1:     Sat Apr 12 20:33:12 2014     Using STANDBY_ARCHIVE_DEST parameter default value as USE_DB_RECOVERY_FILE_DEST     Sat Apr 12 20:33:16 2014     Destination LOG_ARCHIVE_DEST_2 is UNSYNCHRONIZED     ******************************************************************     LGWR: Setting 'active' archival for destination LOG_ARCHIVE_DEST_2     ******************************************************************     Sat Apr 12 20:33:16 2014     NSS2 started with pid=48, OS id=17931     LGWR: Standby redo logfile selected to archive thread 2 sequence 50     LGWR: Standby redo logfile selected for thread 2 sequence 50 for destination LOG_ARCHIVE_DEST_2     Thread 2 advanced to log sequence 50 (LGWR switch)       Current log# 4 seq# 50 mem# 0: +DATA/maa/onlinelog/group_4.262.843489103       Current log# 4 seq# 50 mem# 1: +FRA/maa/onlinelog/group_4.283.843489103     Sat Apr 12 20:33:31 2014     Destination LOG_ARCHIVE_DEST_2 is SYNCHRONIZED     LGWR: Standby redo logfile selected to archive thread 2 sequence 51     LGWR: Standby redo logfile selected for thread 2 sequence 51 for destination LOG_ARCHIVE_DEST_2     Thread 2 advanced to log sequence 51 (LGWR switch)       Current log# 3 seq# 51 mem# 0: +DATA/maa/onlinelog/group_3.257.843489101       Current log# 3 seq# 51 mem# 1: +FRA/maa/onlinelog/group_3.284.843489101     Sat Apr 12 20:33:32 2014     Archived Log entry 175 added for thread 2 sequence 50 ID 0x2b099804 dest 1:     Sat Apr 12 20:33:35 2014     Starting background process SMCO     Sat Apr 12 20:33:35 2014     SMCO started with pid=49, OS id=17946

No alert da standby pode-se observar que os archives começaram a ser recebidos.Estesarchives recebidos são aqueles com dados entre o momento que o duplicate foi feito e o que o dest_2 foi habilitado (o gap).

Estes arquivos foram recebidos e aplicados na base de dados para deixar ela sincronizada.

Observe que só depois de aplicar todos os archives é que o redo da Primary foi sincronizado (Recovery of Online Redo Log) para ambas as threads.

Alert da Standby:

    [oracle@rac11stb01 ~] tail -f 
/u01/app/oracle/diag/rdbms/maastb/maastb1/trace/alert_maastb1.log     MRP0: Background Managed Standby Recovery process started (maastb1)      startedlogmerger process     Sat Apr 12 14:28:46 2014     Managed Standby Recovery starting Real Time Apply     Parallel Media Recovery started with 2 slaves     Waiting for all non-current ORLs to be archived...     All non-current ORLs have been archived.     Sat Apr 12 14:28:48 2014     Media Recovery Waiting for thread 2 sequence 43     Completed: ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT     Sat Apr 12 14:30:07 2014     Using STANDBY_ARCHIVE_DEST parameter default value as USE_DB_RECOVERY_FILE_DEST     Sat Apr 12 14:30:08 2014     RFS[1]: Assigned to RFS process 2456     RFS[1]: Selected log 5 for thread 1 sequence 65 dbid 722024964 branch 843466948     Sat Apr 12 14:30:08 2014     RFS[2]: Assigned to RFS process 2458     RFS[2]: Opened log for thread 1 sequence 66 dbid 722024964 branch 843466948     RFS[3]: Assigned to RFS process 2454     RFS[3]: Opened log for thread 1 sequence 67 dbid 722024964 branch 843466948     Archived Log entry 23 added for thread 1 sequence 66 rlc 843466948 ID 0x2b099804 dest 2:     Archived Log entry 24 added for thread 1 sequence 67 rlc 843466948 ID 0x2b099804 dest 2:     Sat Apr 12 14:30:09 2014     Primary database is in MAXIMUM AVAILABILITY mode     Standby controlfile consistent with primary     RFS[1]: Opened log for thread 1 sequence 68 dbid 722024964 branch 843466948     Sat Apr 12 14:30:10 2014     Archived Log entry 25 added for thread 1 sequence 65 ID 0x2b099804 dest 1:     RFS[2]: Opened log for thread 1 sequence 69 dbid 722024964 branch 843466948     Standby controlfile consistent with primary     RFS[4]: Assigned to RFS process 2460     RFS[4]: Selected log 5 for thread 1 sequence 71 dbid 722024964 branch 843466948     Archived Log entry 26 added for thread 1 sequence 68 rlc 843466948 ID 0x2b099804 dest 2:     Archived Log entry 27 added for thread 1 sequence 69 rlc 843466948 ID 0x2b099804 dest 2:     Sat Apr 12 14:30:14 2014     Primary database is in MAXIMUM AVAILABILITY mode     Standby controlfile consistent with primary     Standby controlfile consistent with primary     RFS[5]: Assigned to RFS process 2467     RFS[5]: Selected log 8 for thread 2 sequence 50 dbid 722024964 branch 843466948     Sat Apr 12 14:30:15 2014     RFS[6]: Assigned to RFS process 2472     RFS[6]: Selected log 6 for thread 1 sequence 70 dbid 722024964 branch 843466948     Sat Apr 12 14:30:16 2014     RFS[7]: Assigned to RFS process 2474     RFS[7]: Selected log 9 for thread 2 sequence 49 dbid 722024964 branch 843466948     Sat Apr 12 14:30:17 2014     Archived Log entry 28 added for thread 1 sequence 70 ID 0x2b099804 dest 1:     Archived Log entry 29 added for thread 2 sequence 49 ID 0x2b099804 dest 1:     Sat Apr 12 14:30:18 2014     Fetching gap sequence in thread 2, gap sequence 43-43     RFS[7]: Opened log for thread 2 sequence 43 dbid 722024964 branch 843466948     Archived Log entry 30 added for thread 2 sequence 43 rlc 843466948 ID 0x2b099804 dest 2:     Sat Apr 12 14:30:18 2014     RFS[8]: Assigned to RFS process 2478     RFS[8]: Opened log for thread 2 sequence 44 dbid 722024964 branch 843466948     Sat Apr 12 14:30:19 2014     RFS[9]: Assigned to RFS process 2476     ...     ...     Media Recovery Log +FRA/maastb/archivelog/2014_04_12/thread_2_seq_44.599.844720219     Media Recovery Log +FRA/maastb/archivelog/2014_04_12/thread_1_seq_65.567.844720209     Media Recovery Log +FRA/maastb/archivelog/2014_04_12/thread_1_seq_66.457.844720209     Sat Apr 12 14:30:24 2014     Changing standby controlfile to MAXIMUM AVAILABILITY level     ...     ...     RFS[5]: Selected log 9 for thread 2 sequence 51 dbid 722024964 branch 843466948     Archived Log entry 37 added for thread 2 sequence 50 ID 0x2b099804 dest 1:     Media Recovery Log +FRA/maastb/archivelog/2014_04_12/thread_2_seq_45.425.844720219     Media Recovery Log +FRA/maastb/archivelog/2014_04_12/thread_2_seq_46.420.844720219     Media Recovery Log +FRA/maastb/archivelog/2014_04_12/thread_1_seq_68.498.844720209     Media Recovery Log +FRA/maastb/archivelog/2014_04_12/thread_2_seq_47.609.844720219     Sat Apr 12 14:30:28 2014     Media Recovery Log +FRA/maastb/archivelog/2014_04_12/thread_1_seq_69.494.844720211     Media Recovery Log +FRA/maastb/archivelog/2014_04_12/thread_2_seq_48.458.844720219     Media Recovery Log +FRA/maastb/archivelog/2014_04_12/thread_2_seq_49.466.844720217     Media Recovery Log +FRA/maastb/archivelog/2014_04_12/thread_1_seq_70.470.844720217     Media Recovery Log +FRA/maastb/archivelog/2014_04_12/thread_1_seq_71.583.844720225     Media Recovery Log +FRA/maastb/archivelog/2014_04_12/thread_2_seq_50.257.844720225     Media Recovery Waiting for thread 1 sequence 72 (in transit)     Recovery of Online Redo Log: Thread 1 Group 6 Seq 72 Reading mem 0       Mem# 0: +DG01/maastb/onlinelog/group_6.267.844716079       Mem# 1: +FRA/maastb/onlinelog/group_6.604.844716081     Media Recovery Waiting for thread 2 sequence 51 (in transit)     Recovery of Online Redo Log: Thread 2 Group 9 Seq 51 Reading mem 0       Mem# 0: +DG01/maastb/onlinelog/group_9.260.844716095       Mem# 1: +FRA/maastb/onlinelog/group_9.591.844716097

Alguns detalhes destes alerts, observe que ambas as instâncias do banco primary estão enviando os seus archives para o standby. Se você observar, irá ver a sequência dos archives enviados do primary para o standby aplicar. Observe também que o standby detectou o GAP e requisitou eles ao primary.

É necessário habilitar o log_archive_dest_state_2 no standby também, pois em caso de uma mudança de papeis já está tudo preparado. Não se preocupe, pois nada será enviado, lembre que na definição ele só envia caso esteja atuando como role primary:

SQL> ALTER SYSTEM SET log_archive_dest_state_2 = enable SCOPE = BOTH SID = '*';

System altered.

SQL>

Podemos fazer alguns testes com a sincroniza para ver se tudo está em ordem. Os passos abaixo mostram como está a sincronia, observe que agora o banco está definido (PROTECTION_MODE) e operando (PROTECTION_LEVEL) em MAXIMUM AVAILABILITY.

SQL> SELECT instance_name FROM gv$instance;

INSTANCE_NAME

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

maa2

maa1

SQL> SELECT protection_mode, protection_level FROM v$database;

PROTECTION_MODE      PROTECTION_LEVEL

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

MAXIMUM AVAILABILITY MAXIMUM AVAILABILITY

SQL> col error format a10

SQL> col dest_name format a20

SQL> col destination format a20

SQL> SELECT inst_id, dest_name, destination, status, error FROM gv$archive_dest_status WHERE status != 'INACTIVE';

   INST_ID DEST_NAME            DESTINATION          STATUS    ERROR

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

         1 LOG_ARCHIVE_DEST_1                        VALID

         1 LOG_ARCHIVE_DEST_2   maastb               VALID

         2 LOG_ARCHIVE_DEST_1                        VALID

         2 LOG_ARCHIVE_DEST_2   maastb               VALID

SQL>

Forçando um arquivamento do primary você verá o seguinte no alert das instâncias:

No alert da Primary (nó 1)

    [oracle@rac11pri01 ~]tail -f 
/u01/app/oracle/diag/rdbms/maa/maa1/trace/alert_maa1.log     Sat Apr 12 21:24:34 2014     LGWR: Standby redo logfile selected to archive thread 1 sequence 74     LGWR: Standby redo logfile selected for thread 1 sequence 74 for destination LOG_ARCHIVE_DEST_2     Thread 1 advanced to log sequence 74 (LGWR switch)       Current log# 2 seq# 74 mem# 0: +DATA/maa/onlinelog/group_2.271.843488555       Current log# 2 seq# 74 mem# 1: +FRA/maa/onlinelog/group_2.285.843488555     Sat Apr 12 21:24:35 2014     Archived Log entry 183 added for thread 1 sequence 73 ID 0x2b099804 dest 1: No alert da Primary (nó 2)     
[oracle@rac11pri02 ~]tail -f 
/u01/app/oracle/diag/rdbms/maa/maa2/trace/alert_maa2.log     Sun Apr 13 03:20:01 2014     Archived Log entry 179 added for thread 2 sequence 51 ID 0x2b099804 dest 1:     Sun Apr 13 03:24:34 2014     LGWR: Standby redo logfile selected to archive thread 2 sequence 53     LGWR: Standby redo logfile selected for thread 2 sequence 53 for destination LOG_ARCHIVE_DEST_2     Thread 2 advanced to log sequence 53 (LGWR switch)       Current log# 3 seq# 53 mem# 0: +DATA/maa/onlinelog/group_3.257.843489101       Current log# 3 seq# 53 mem# 1: +FRA/maa/onlinelog/group_3.284.843489101     Sun Apr 13 03:24:35 2014     Archived Log entry 182 added for thread 2 sequence 52 ID 0x2b099804 dest 1:No alert da Standby:    
[oracle@rac11stb01 ~]tail -f 
/u01/app/oracle/diag/rdbms/maastb/maastb1/trace/alert_maastb1.log     Sat Apr 12 21:21:27 2014     Standby controlfile consistent with primary     RFS[5]: Selected log 9 for thread 2 sequence 53 dbid 722024964 branch 843466948     Sat Apr 12 21:21:28 2014     Archived Log entry 40 added for thread 2 sequence 52 ID 0x2b099804 dest 1:     Sat Apr 12 21:21:28 2014     Standby controlfile consistent with primary     RFS[4]: Selected log 6 for thread 1 sequence 74 dbid 722024964 branch 843466948     Sat Apr 12 21:21:29 2014     Archived Log entry 41 added for thread 1 sequence 73 ID 0x2b099804 dest 1:     Sat Apr 12 21:21:29 2014     Media Recovery Waiting for thread 2 sequence 53 (in transit)     Recovery of Online Redo Log: Thread 2 Group 9 Seq 53 Reading mem 0       Mem# 0: +DG01/maastb/onlinelog/group_9.260.844716095       Mem# 1: +FRA/maastb/onlinelog/group_9.591.844716097     Media Recovery Waiting for thread 1 sequence 74 (in transit)     Recovery of Online Redo Log: Thread 1 Group 6 Seq 74 Reading mem 0       Mem# 0: +DG01/maastb/onlinelog/group_6.267.844716079       Mem# 1: +FRA/maastb/onlinelog/group_6.604.844716081

Observe no alert das instâncias primary que os archives foram gerados e que o standbyarquiva eles e já fica esperando os próximos.

REGISTRANDO O RAC STANDBY

Lembre-se que estamos em um ambiente RAC o banco standby não foi criado através das vias normais, desta forma o CRS do RAC que atende o standby não sabe da existência deste banco. Isso é fácil de resolver, basta registrar o banco:

[oracle@rac11stb01 ~]$ export ORACLE_HOME=/u01/app/grid/11.2.0.3

[oracle@rac11stb01 ~]cd $ORACLE_HOME/bin 
[oracle@rac11stb01 bin]srvctl add database -d maastb -o /u01/app/oracle/product/11.2.0.3/db_1 -c RAC -r PHYSICAL_STANDBY -s MOUNT -t IMMEDIATE -a DG01,FRA 
[oracle@rac11stb01 bin]$

E registrar as instâncias:

[oracle@rac11stb01 bin]srvctl add instance -d maastb -i maastb1 -n rac11stb01 
[oracle@rac11stb01 bin]srvctl add instance -d maastb -i maastb2 -n rac11stb02 
[oracle@rac11stb01 bin]$

Observe que o banco foi registrado como PHYSICAL_STANDBY e para ser iniciado em modo MOUNT. Assim, garantimos que o standby, caso reinicie, volte corretamente.

OUTRAS INSTÂNCIAS

Se você quiser, poderá subir as outras instâncias do standby. Se você já estivesse com o broker, ela seria iniciada automaticamente por ele.

O procedimento é o mesmo, como a instância nunca foi iniciada, você deve criar o diretório “adump” como apontado no spfile. Todos os outros arquivos necessários (como init e password files) já foram copiados em passos anteriores.

Verificando o init da pasta dbs no segundo nó do standby.

    [oracle@rac11stb02 ~]cat /u01/app/oracle/product/11.2.0.3/db_1/dbs/initmaastb2.ora     SPFILE='+DG01/maastb/spfilemaastb.ora'     [oracle@rac11stb02 ~]$

Criando diretório de dump

[oracle@rac11stb02 ~]mkdir -p /u01/app/oracle/admin/maastb/adump     
[oracle@rac11stb02 ~]$

Subindo a instância em modo mount

[oracle@rac11stb02 ~]sqlplus / as sysdba     
SQL*Plus: Release 11.2.0.3.0 Production on Sat Apr 12 21:47:45 2014     Copyright (c) 1982, 2011, Oracle.  All rights reserved.     Connected to an idle instance.     
SQL> STARTUP NOMOUNT;     ORACLE instance started.     Total System Global Area 1068937216 bytes     Fixed Size                  2235208 bytes     Variable Size             343934136 bytes     Database Buffers          717225984 bytes     Redo Buffers                5541888 bytes     
SQL> ALTER DATABASE MOUNT;     Database altered.     
SQL>

AMBIENTE FINAL

Chegando aqui, você tem um DG configurado em que ambos, primary e standby, são RAC. Além disso, seu DG está com o modo de proteção definido como MAXIMUM AVAILABIITY que garante sincronismo no envio do dados entre primary e standby, além de estar com real-time.

Mesmo assim, o seu ambiente não está 100%, o broker não está configurado e não existe a figura do “observador” definida. Caso seu primary fique offline, você precisará chavear manualmente para o standby. De qualquer forma, você já está protegido com DG.

Nos próximos artigos iremos ver como fazer algumas coisas com o DG, failover e switchover manuais. Iremos configurar broker e realizar failover e switchover através dele.

No fim, não esqueça de fazer um backup do seu ambiente primary e do spfile do seu standby.

Fernando Simon

Fernando Simon

Fernando Simon, administrador de banco de dados para o Tribunal de Justiça de Santa Catarina e também como consultor na mesm área no tempo livre. Mantenho um blog (http://www.fernandosimon.com/blog) com informações para o dia a dia de um DBA e DMA Exadata.

Experiência com bancos de dados desde 2004, Oracle (9i e posteriores), SQLServer (versões desde a 2k5) e PortgreSQL (7, 8 e 9). Além de áreas relacionadas como storage, soluções de backup, virtualização e afins.

Database Machine Administrator (DMA) Exadata desde 2010, usuário e administrador (configuração, atualização e manutenção) da solução Exadata desde a versão V2. Administrador de soluções MAA (DataGuard, Rac e afins), Gerenciamento de Recursos (Database Resource Manager e IO Resource Manager - IORM) para banco de dados Oracle e Oracle Exadata.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

plugins premium WordPress