Hoje iremos criar uma rotina para monitorar o sincronismo de um Oracle database Standard com função standby, infelizmente a melhor solução seria usar o Data Guard, mas esta funcionalidade só está presente na edição Enterprise.
O manual standby, consiste em copiar os archivelogs ou backups de archivelogs do ambiente produtivo para o standby geralmente via rsync com aplicação infinita.
Esta solução pode ser utilizada para recuperação em caso de um desastre ou uma possível migração agendada, sincronizando os archivelogs até o dia agendado da troca dos ambientes.
Tabela de feature/option/pack sobre a edição com Data Guard disponível para uso:
https://docs.oracle.com/database/121/DBLIC/editions.htm#DBLIC109Edição usada para demonstração:
Servidor produtivo:
Servidor standby:
TNSNAMES configurados nos dois servidores:
[oracle@srv04 prdstd]$ cat /u01/app/oracle/product/19.3.0.0/db_2/network/admin/tnsnames.ora
# tnsnames.ora Network Configuration File: /u01/app/oracle/product/19.3.0.0/db_2/network/admin/tnsnames.ora
# Generated by Oracle configuration tools.
LISTENER_PRD19STD =
(ADDRESS = (PROTOCOL = TCP)(HOST = srv03)(PORT = 1522))
PRD19STD =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = srv04)(PORT = 1522))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = orclpdb)
)
)
PRD =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = srv03)(PORT = 1522))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = orclpdb)
)
)Status do ambientes produtivo:
Status de mount do ambiente standby:
Criação de usuário com acesso limitado ao banco de dados de produção:
-- CDB
create user c##ZABBIX_DBA identified by ZAbBix2023;
grant create session to c##ZABBIX_DBA container=ALL;
grant select any dictionary to c##ZABBIX_DBA;
grant unlimited tablespace to C##ZABBIX_DBA;
--NON-CDB
create user ZABBIX_DBA identified by ZAbBix2023;
grant create session to ZABBIX_DBA;
grant select any dictionary to ZABBIX_DBA;
grant unlimited tablespace to ZABBIX_DBA;Criação da tabela que iremos usar para guardar a data e hora do último sincronismo do standby, criada no servidor produtivo:
CREATE TABLE "C##ZABBIX_DBA"."CONTROLE_CONTINGENCIA"
(
"CHECKPOINT_APLICADO" DATE
);Preenchendo a tabela de controle no servidor produtivo:
INSERT INTO "C##ZABBIX_DBA"."CONTROLE_CONTINGENCIA" (CHECKPOINT_APLICADO) VALUES (TO_DATE('2023/02/19 13:57:44', 'yyyy/mm/dd hh24:mi:ss'));
COMMIT;
alter session set nls_date_format='dd/mm/yyyy hh24:mi:ss';
select * FROM "C##ZABBIX_DBA"."CONTROLE_CONTINGENCIA";Teste de acesso via tnsping do servidor standby para o servidor produtivo:
Teste de acesso via sqlplus com o usuário criado do servidor standby para o servidor produtivo:
Verificando o CHECKPOINT_CHANGE atual do ambiente Standby
alter session set nls_date_format = 'DD/MM/YYYY HH24:MI:SS';
set colsep " | "
SET LINESIZE 145
SET PAGESIZE 9999
select to_char(min(CHECKPOINT_CHANGE#)) min_ckpt,
to_char(max(CHECKPOINT_CHANGE#)) max_ckpt,
min(CHECKPOINT_TIME) min_time,
max(CHECKPOINT_TIME) max_time
from v$datafile_header;Aplicando o backup de archivelog no standby manual simulando o sincronismo:
Verificando novamente o CHECKPOINT_CHANGE após o recover do Standby manual:
alter session set nls_date_format = 'DD/MM/YYYY HH24:MI:SS';
set colsep " | "
SET LINESIZE 145
SET PAGESIZE 9999
select to_char(min(CHECKPOINT_CHANGE#)) min_ckpt,
to_char(max(CHECKPOINT_CHANGE#)) max_ckpt,
min(CHECKPOINT_TIME) min_time,
max(CHECKPOINT_TIME) max_time
from v$datafile_header;Script usado para verificar a data e hora do último recover aplicado no standby, realizando o update com estas informações no ambiente produtivo via tnsnames:
[oracle@srv04 scripts]$ cat check_standby.sh
#!/bin/bash
#################################################################
# CHECK SYCRONISM STANDBY ORACLE STANDARD #
# #
# #
#################################################################
# Exportando variaveis de ambiente
export ORACLE_BASE=/u01/app/oracle
export ORACLE_SID=prd19std
export ORACLE_HOME=$ORACLE_BASE/product/19.3.0.0/db_2
export PATH=$PATH:$ORACLE_HOME/bin
var_status=''
export var_checkpoint=`sqlplus -S /nolog << EOF | grep -v '^Connected.$'
connect / as sysdba
set pagesize 0 feedback off verify off heading off echo off
alter session set nls_date_format='dd/mm/yyyy hh24:mi:ss';
select max(CHECKPOINT_TIME) TIME from V\\$datafile_header order by CHECKPOINT_TIME;
exit;
EOF`
$ORACLE_HOME/bin/sqlplus /nolog <<-EOF
conn c##ZABBIX_DBA/ZAbBix2023@PRD
UPDATE c##ZABBIX_DBA.CONTROLE_CONTINGENCIA SET CHECKPOINT_APLICADO = to_date('${var_checkpoint}','DD/MM/YYYY HH24:MI:SS');
exit;
EOF
chmod 775 check_standby.shExecutando script para coletar e armazenar o último checkpoint aplicado no ambiente do standby manual:
[oracle@srv04 scripts]$ ./check_standby.shVerificando a tabela com controle do sincronismo no ambiente produtivo, a tabela deve ter a mesma data e hora da consulta do checkpoint que excutamos após a atualização do standby 19/02/2023 14:11:32:
alter session set nls_date_format='dd/mm/yyyy hh24:mi:ss';
select * FROM "C##ZABBIX_DBA"."CONTROLE_CONTINGENCIA";Irei criar uma view no servidor produtivo para retornar 0 se o standby estiver sincronizado, ou 1 caso o standby esteja com atraso de sincronia no periodo de 01:00h você pode ajustar o tempo que desejar, esta consulta será consumida pelo Zabbix, ele irá alertar a equipe de monitoramento ou banco de dados sobre o possivel problema de sincronia:
CREATE OR REPLACE VIEW "C##ZABBIX_DBA"."VW_CONTROLE_CONTINGENCIA" AS
SELECT CASE WHEN (SYSDATE - CHECKPOINT_APLICADO) * 24 * 60 >= 60
THEN 1 ELSE 0 END SINCRONIA
FROM "C##ZABBIX_DBA"."CONTROLE_CONTINGENCIA";
Consulta para colocar no ZABBIX e alarmar quando retornar 1:
SELECT SINCRONIA FROM "C##ZABBIX_DBA"."VW_CONTROLE_CONTINGENCIA";LAG sincronia:
alter session set nls_date_format='dd/mm/yyyy hh24:mi:ss';
SELECT ROUND(SYSDATE-CHECKPOINT_APLICADO) LAG_SINCRONIA
FROM "C##ZABBIX_DBA"."CONTROLE_CONTINGENCIA";
















