Alterar dados a partir da Physical Standby com Data Guard?!?! Sim, é possível...

 Um dos principais problemas da implementação de sistemas de "Disaster Recover" é o facto de a estrutura de standby estar normalmente subaproveitada ou até nem sequer estar a ser aproveitada de todo.
Com o decorrer dos anos e das versões a Oracle foi introduzindo novidades do lado da "Physical Standby" que permite um melhor aproveitamento da capacidade instalada.
Podemos fazer o backup da DB na Standby, podemos abrir a Standby em modo "Read Only" e com isso mover alguns do relatórios para essa BD.
Na versão 19c a Oracle foi um pouco mais longe e permite executar DML do lado da Standby. Isso mesmo, alterar dados na standby que está aberta em modo read only!!
A ideia não é usar aplicações com alterações intensivas de dados, mas existem alguma aplicações que maioritariamente são de consulta e apenas com operações de DML esporádicas.
Para essas, podemos também usar a "Physical Standby" como BD de operação, usando assim os recursos da standby e libertando alguma carga da Primary.

Para poder tirar partido desta funcionalidade, será necessário usar a opção de "Active Data Guard" que é um opção licenciada, e alterar alguns parâmetros das duas BDs da configuração de Data Guard.

Vamos ver passo a passo como configurar esta opção.
Tenho uma configuração de Data Guard em que a BD Primary chama-se "tstdb" e a physical standby "drtstdb".
Começamos por activar a opção "Active Data Guard" também conhecida como "Real Time Query" na bd de Standby, assumindo que a standby estava a receber e a aplicar o redo vindo da Primary:

        
           
drtstdb > alter database recover managed standby database cancel;

Database altered.

drtstdb> alter database open read only;

Database altered.

drtstdb> alter pluggable database all open;

Pluggable database altered.

drtstdb> show pdbs

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
         2 PDB$SEED                       READ ONLY  NO        
         3 TSTPDB1                        READ ONLY  NO        
         4 TSTPDB2                        READ ONLY  NO             
         

Vemos que neste momento temos todas a pluggable database em open read only mode.
Vamos a seguir configurar o "Active Data Guard" que permitirá ter a BD aberta em read only e em simultâneo estar a aplicar o redo vindo da Primary.

         
           
drtstdb> alter database recover managed standby database disconnect;

Database altered.


drtstdb> select open_mode from v$database;

OPEN_MODE           
--------------------
READ ONLY WITH APPLY

     
         

Depois de termos a BD em modo "Active Data Guard", temos de configurar a possibilidade de DML através da Standby.
Para isso teremos de configurar o parâmetro "adg_redirect_dml" para o valor "true" na Primary e na Standby.

        
           
tstdb> alter system set adg_redirect_dml=true scope=both;

System altered.


drtstdb> alter system set adg_redirect_dml=true scope=both;

System altered.     
         

 E a partir deste momento estamos prontos para poder usar esta funcionalidade. Tão simples como isto.
Vamos agora ver a funcionalidade activa com algumas demonstrações a serem feitas numa das pluggable database existentes, a "tstpdb1"

Com um user chamado user01, vamos começar por criar na primary uma tabela e inserir alguns registos nela:

 

tstpdb1> create table tab1 (col1 number, col2 varchar2(10));

Table created.

tstpdb1> insert into tab1 values (100,'AAAAA');

1 row created.

tstpdb1> commit;

Commit complete.

tstpdb1> select * from tab1;

      COL1 COL2      
---------- ----------
       100 AAAAA     
     
         

  Na Standby database (que está no servidor host03.example.com) tenho, pelo facto de usar o "Active Data Guard" a possibilidade de ver immediatamente os dados inseridos na tabela criada.

        
           
SQL> !hostname
host03.example.com

SQL> select * from tab1;

      COL1 COL2      
---------- ----------
       100 AAAAA     
     
         

 Em seguida vamos executar um insert a partir da standby database. O que vai acontecer internamente é a criação de uma sessão a partir da máquina de standby para a máquina da primary para executar as alterações feitas.
Na verdade, o insert que vou fazer, vai ser feito através de uma sessão aberta na primary e não directamente na standby.

Olhando para a sessões do user01 na máquina da primary temos o seguinte:

 

SQL> select username, machine from v$session where username='USER01';
USERNAME   MACHINE              
USER01     host01.example.com        
         

 Vamos agora executar o comando de insert na standby:

        
           
SQL> !hostname
host03.example.com

SQL> insert into tab1 values (200,'UUUUU');

1 row created.

SQL> commit;     
         

 Se consultarmos as sessões ligadas à máquina da primary, constatamos que neste momento já existem 2 sessões criadas, sendo uma criada a partir da máquina da standby:

        
           
SQL> !hostname
host01.example.com


SQL> select username, machine from v$session where username='USER01';
USERNAME   MACHINE              
USER01     host01.example.com   
USER01     host03.example.com   
     
         

 Ao fazer o commit na standby, vemos que os dados ficam disponíveis na primary, no entanto a sessão é criada ainda antes de se fazer o commit..

 

tstpdb1> !hostname
host01.example.com

tstpdb1> select * from tab1;

      COL1 COL2      
---------- ----------
       200 UUUUU     
       100 AAAAA          
         

 A sessão ligada na primary, continuará activa até se fazer logout na sessão da standby.

Volto a referir que a ideia é usar esta opção em aplicações com pouca necessidade de alterar dados. As alterações terão de ser enviadas via rede através da conecção criada e será sempre mais lento do que se estiver a alterar dados locais.
No entanto, se bem aplicada, esta opção permite tirar muito mais partido da "Physical Standby", retirando alguma da carga existente na "Primary".

Comentários

Mensagens populares deste blogue

DBMS_SQL_FIREWALL - Firewall dentro da Base de Dados (Parte I)

DBMS_SQL_FIREWALL - Firewall dentro da Base de Dados (Parte IV)

DBMS_SQL_FIREWALL - Firewall dentro da Base de Dados (Parte III)