Criação de serviço read-only em um Active Data Guard
Uma das vantagens obtidas quando temos um ambiente Active Data Guard, é a possibilidade de termos um standby físico que fica aberto em modo read-only enquanto o Redo Apply está sendo executado. Isso permite que os dados mais recentes inseridos no ambiente primário sejam replicados e tenhamos consultas sendo executadas no standby, que retornam os mesmos resultados que seriam retornados caso a query fosse executada no banco primário.
Para que isso seja possível, um serviço precisa ser configurado para o standby, para que as aplicações que tem um workload de leitura sejam apontadas para o ambiente read only.
Criação do serviço via SRVCTL no Active Data Guard
Caso o banco de dados esteja rodando em um ambiente que tenha o Oracle Restart ou o Oracle Clusterware, a criação deve ser feita através do utilitário SRVCTL, pois assim o serviço criado será gerenciado por esses softwares, e iniciado automaticamente, caso assim seja configurado.
Para a adição do serviço read-only, executamos, tanto no host primário quanto no standby:
# no host primário [oracle@host_rw ~]$ srvctl add service -d mydb -pdb mypdb -service my_service_ro -role physical_standby # no host standby [oracle@host_ro ~]$ srvctl add service -d mydbsby -pdb mypdb -service my_service_ro -role physical_standby
A opção -role permite configurar o serviço para que seja iniciado somente quando o banco esteja na função de physical standby. A criação do serviço deve ser feita tanto no ambiente primário quanto no standby para que quando uma role transition (switchover ou failover) ocorrer, o serviço seja iniciado corretamente no standby, indepentende do host. Para ambientes RAC as opções available e preferred devem ser configuradas também, indicando os nós nos quais o serviço irá rodar.
Aqui porém, temos um ponto importante. Caso essa adição seja feita, e façamos o comando de start do serviço no standby, teremos o seguinte erro:
[oracle@host_ro ~]$ srvctl start service -d mydbsby -service my_service_ro PRCD-1084 : Failed to start service my_service_ro PRCR-1079 : Failed to start resource ora.mydbsby.my_service_ro.svc CRS-5017: The resource action "ora.mydbsby.my_service_ro.svc start" encountered the following error: ORA-16000: database or pluggable database open for read-only access ORA-06512: at "SYS.DBMS_SERVICE", line 5 ORA-06512: at "SYS.DBMS_SERVICE", line 288 ORA-06512: at line 1 . For details refer to "(:CLSN00107:)" in "/u01/app/oracle/diag/crs/host_ro/crs/trace/ohasd_oraagent_oracle.trc". CRS-2674: Start of 'ora.mydbsby.my_service_ro.svc' on 'host_ro' failed
Isso ocorre porque ao iniciar o serviço pela primeira vez, ele é registrado no banco de dados, e tenta realizar a escrita no dicionário de dados. Como o ambiente é read-only, essa operação falha.
Para resolver essa situação devemos iniciar o serviço manualmente no primário, para que as devidas modificações sejam feitas, e replicadas para o standby através do Redo Apply, para que seja possível iniciar o serviço corretamente no standby:
# no host primário [oracle@host_rw ~]$ srvctl start service -d mydb -service my_service_ro [oracle@host_rw ~]$ srvctl stop service -d mydb -service my_service_ro [oracle@host_rw ~]$ srvctl enable service -d mydb -service my_service_ro # no host standby [oracle@host_ro ~]$ srvctl start service -d mydbsby -service my_service_ro [oracle@host_ro ~]$ srvctl status service -d mydbsby -service my_service_ro Service my_service_ro is running [oracle@host_ro ~]$ srvctl enable service -d mydbsby -service my_service_ro
Com o serviço habilitado, quando o banco for iniciado na função de standby físico, o serviço será iniciado automaticamente pelo Oracle Restart ou Oracle Clusterware.
Criação do serviço via DBMS_SERVICE no Active Data Guard
Em ambientes onde nem o Oracle Restart ou o Oracle Clusterware estão presentes, podemos usar a package DBMS_SERVICE para realizar a criação do serviço.
Para realizar a criação do serviço com a package:
BEGIN DBMS_SERVICE.CREATE_SERVICE(
service_name => 'my_service_ro',
network_name => 'my_service_ro');
END;
/
Para controlar a inicialização automática do serviço, utilizamos uma trigger AFTER STARTUP, validando a role do banco e o modo de abertura:
CREATE OR REPLACE TRIGGER service_startup
AFTER STARTUP ON DATABASE
DECLARE
db_role VARCHAR2(16);
db_mode VARCHAR2(20);
BEGIN
SELECT DATABASE_ROLE, OPEN_MODE INTO db_role, db_mode FROM V$DATABASE;
IF db_role = 'PHYSICAL STANDBY' AND db_mode LIKE 'READ ONLY%' THEN
DBMS_SERVICE.start_service('servico_standby');
END IF;
END;
/
Dessa forma, sempre que o banco assumir a role de standby físico, e for aberto em modo READ ONLY ou READ ONLY WITH APPLY, o serviço será iniciado.
Conclusão
A utilização do standby físico para execução de consultas em ambientes Active Data Guard traz uma melhor utilização da infraestrutura de banco de dados, distribuindo a carga entre o primário e o standby, reduzindo o impacto sobre o banco primário. Vale destacar que essa capacidade não afeta a funcionalidade de recuperação de desastres do standby, apenas utiliza melhor a infraestrutura que estaria subutilizada sem o Active Data Guard.
Publicar comentário