--=================================
--### DATA GUARD - CHECKLIST E LAG
--=================================
--SCRIPT IDENTIFICACAO
set lines 400 pages 500
alter session set NLS_DATE_FORMAT = 'DD/MM/YYYY HH24:MI:SS';
prompt ### INDENTIFICA (primary ou phisical standby)
SELECT DBID,NAME,DB_UNIQUE_NAME,DATABASE_ROLE FROM gv$DATABASE
/
prompt ### STATUS DATA GUARD (open ou mounted)
col HOST_NAME for a55
col ACTIVE_STATE for a17
SELECT INSTANCE_NAME, HOST_NAME, STATUS, DATABASE_STATUS, ACTIVE_STATE FROM gv$INSTANCE
/
--SCRIPT LAG VALUE (conectado no Physical Standby)
col NAME for a18
col value for a18
SELECT name, value, datum_time, time_computed FROM V$DATAGUARD_STATS WHERE name like 'apply lag' or name like 'transport lag';
set lines 200 pages 50
col name format a30
col value format a18
col unit format a35
col time_computed format a22
SELECT
NAME
, VALUE
, UNIT
, DATUM_TIME
, TIME_COMPUTED
FROM v$dataguard_stats
ORDER BY time_computed;
--SCRIPT ARCHIVE APLICADO - atividade nos blocks (conectado no Physical Standby)
--MRP0 este processo e responsavel por mostra onde esta o gap - aplicando
SELECT PROCESS, SEQUENCE#, THREAD#, BLOCK#, BLOCKS, TO_CHAR(SYSDATE, 'DD-MON-YYYY HH:MI:SS') TIME
FROM gv$MANAGED_STANDBY WHERE PROCESS='MRP0';
--SCRIPT GAP (conectado no PRIMARY ou Physical Standby)
SELECT al.thread# "THREAD",
almax "ULTIMA SEQ RECEBIDA",
lhmax "ULTIMA SEQ APLICADA",
(almax - lhmax) "GAP"
FROM (SELECT thread#, Max(sequence#) almax
FROM v$archived_log
WHERE resetlogs_change# = (SELECT resetlogs_change# FROM v$database)
GROUP BY thread#) al,
(SELECT thread# thrd, Max(sequence#) lhmax
FROM v$log_history
WHERE resetlogs_change# = (SELECT resetlogs_change# FROM v$database)
GROUP BY thread#) lh
WHERE al.thread# = lh.thrd;
--ERROS DE COMUNICACAO ENTRE PRIMARIO E STANDBY - ARCHIVES SENDO ENVIADOS OU RECEBIDOS e ARCHIVES APLICADOS
--Quando executado no PRIMARIO, ele mostra o archive que foi GERADO, e a transferencia para o standby
--Quando executado no STANDBY, ele mostra o archive sendo RECEBIDO, aplicado no banco de dados, e possivel falha de comunicação com o primario.
--Ele tambem mostra se existe erro de comunicação
col MESSAGE for a100
col TIMESTAMP for a20
SELECT message, TO_CHAR(TIMESTAMP, 'DD-MM-RRRR HH24:MI:SS') "TIMESTAMP" FROM v$DATAGUARD_STATUS;
--DATA GUARD - seq gerada (conectado no primary)
SQL>
SELECT thread#, Max(sequence#) "ULT_SEQ_GERADA_PRIMARY"
FROM v$ARCHIVED_LOG alog, v$DATABASE db
WHERE alog.resetlogs_change# = db.resetlogs_change#
GROUP BY thread#
ORDER BY 1;
--DATA GUARD - seq recebida (conectado no Physical Standby)
SELECT thread#, Max(sequence#) "ULT_SEQ_RECEBIDA_STANDBY"
FROM v$ARCHIVED_LOG alog, v$DATABASE db
WHERE alog.resetlogs_change# = db.resetlogs_change#
GROUP BY thread#
ORDER BY 1;
--DATA GUARD - seq aplicada (conectado no Physical Standby)
SELECT thread#, Max(sequence#) "ULT_SEQ_APLICADA_STANDBY"
FROM v$ARCHIVED_LOG alog, v$DATABASE db
WHERE alog.resetlogs_change# = db.resetlogs_change#
AND alog.applied IN ( 'YES', 'IN-MEMORY' )
GROUP BY thread#
ORDER BY 1;
--===============================
--### DATA GUARD - REPLICACAO STOP START
--===============================
--DATA GUARD - PARAR REPLICACAO (conectado no Physical Standby)
SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;
--DATA GUARD - INICIAR REPLICACAO COM PARALLEL (conectado no Physical Standby)
SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE PARALLEL 30 THROUGH ALL SWITCHOVER DISCONNECT USING CURRENT LOGFILE;
SQL>
--DATA GUARD - INICIA REPLICACAO CASO NAO RETORNE VALORES no SCRIPT ARCHIVE APLICADO (conectado no Physical Standby)
--verificar se dataguard esta recebendo os archives ou em modo de recovery
SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT FROM SESSION;
--COMANDO FORCA NOVA SEQUENCIA de LOG (conectado no primary)
SQL> ALTER SYSTEM SWITCH LOGFILE;
--========================================================
--### DATA GUARD - PROCEDIMENTO PARA TRANSPORTE DOS ARCHIVES DA ORIGEM PARA DESTINO
--========================================================
O tempo estimado neste momento para finalizar o apply dos redos está em cerca de 1 hora, desta forma não vale a pena criar um backup incremental para o transporte
Como o +ASM irá ficar no ar o tempo todo é possível que mesmo que o archive_dest_3 esteja em disable continuar copiando os archives e aplicando no destino.
Para este procedimento, seguir os passos abaixo, qualquer dúvida favor entrar em contato.
--### query 1 monitora o status se o archive a ser transportado ficar com status de "Wait for GAP"
--==============
por mais de 5 minutos executar a query 3 com os parâmetros (thread# e sequence# ela irá gerar o comando ASM para cópia do archive)
SELECT process, status, thread#, sequence#, block#, blocks, DELAY_MINS FROM v$managed_standby ORDER BY 3,4;
--### monitora o gap do transporte e do apply redo, nas colunas transport lag e apply finish time
--==============
col name format a30
col value format a18
col unit format a35
col time_computed format a22
SELECT
NAME
, VALUE
, UNIT
, DATUM_TIME
, TIME_COMPUTED
FROM v$dataguard_stats
ORDER BY time_computed;
NAME VALUE UNIT DATUM_TIME TIME_COMPUTED
------------------------------ ------------------ ----------------------------------- ------------------------------ ----------------------
transport lag +00 00:00:00 day(2) to second(0) interval 05/28/2016 22:28:23 05/28/2016 23:21:44
estimated startup time 19 second 05/28/2016 23:21:44
apply finish time +00 00:55:42.542 day(2) to second(3) interval 05/28/2016 23:21:44
apply lag +00 20:41:57 day(2) to second(0) interval 05/28/2016 22:28:23 05/28/2016 23:21:44
--### gera um comando de SO que copia os archives faltantes
--==============
Executar o comando abaixo como o usuário grid, com as variáveis exportadas para o GRID, no RDBMS de origem ele irá copiar o archive diretamente para dentro do ASM de destino.
set lines 256
col comando format a256
SELECT 'asmcmd -p cp --port 1530 ' || name || ' sys/welcome1@"10.116.68.36".+ASM1:' || replace(substr(name,1,INSTR(name,'.',-1,1)-1),'siebelp2','siebels2') as comando FROM v$archived_log WHERE sequence# in (&seq) and thread# = &thread and dest_id =1;
--### A query 4 Registra os archives copiados após a cópia ser finalizada
--==============
registra os archives no banco de destino como o usuário oracle e exportado para o RDBMS requisitado.
Os archives que faltam ou aparecem como wait for gap na query 1 ou no alert log do RDBMS d edestino.
set lines 256
col comando format a256
SELECT 'alter database register logfile ' || CHR(39) || replace(substr(name,1,INSTR(name,'.',-1,1)-1),'siebelp2','siebels2') || CHR(39) || ';' as comando FROM v$archived_log WHERE sequence# in (&seq) and thread# = &thread and dest_id =1;