Files
oracle/csierra/cs_dg_protection_mode_switches.sql
2026-03-12 21:23:47 +01:00

185 lines
6.0 KiB
SQL

----------------------------------------------------------------------------------------
--
-- File name: cs_dg_protection_mode_switches.sql
--
-- Purpose: Data Guard Protection Mode Switches as per Log Archive Dest
--
-- Author: Carlos Sierra
--
-- Version: 2021/10/18
--
-- Usage: Execute connected to CDB or PDB
--
-- Example: $ sqlplus / as sysdba
-- SQL> @cs_dg_protection_mode_switches.sql
--
-- Notes: Developed and tested on 12.1.0.2.
--
---------------------------------------------------------------------------------------
--
@@cs_internal/cs_primary.sql
@@cs_internal/cs_set.sql
@@cs_internal/cs_def.sql
@@cs_internal/cs_file_prefix.sql
--
DEF cs_script_name = 'cs_dg_protection_mode_switches';
--
SELECT '&&cs_file_prefix._&&cs_script_name.' cs_file_name FROM DUAL;
--
@@cs_internal/cs_spool_head.sql
PRO SQL> @&&cs_script_name..sql
@@cs_internal/cs_spool_id.sql
--
@@cs_internal/&&cs_set_container_to_cdb_root.
--
COL begin_time FOR A19 HEA 'AWR SNAP|BEGIN TIME';
COL end_time FOR A19 HEA 'AWR SNAP|END TIME';
COL begin_host FOR A64 HEA 'AWR SNAP|BEGIN STANDBY HOST';
COL end_host FOR A64 HEA 'AWR SNAP|END STANDBY HOST';
COL min_date_time FOR A19 HEA 'LOGON STORM|BEGIN TIME';
COL max_date_time FOR A19 HEA 'LOGON STORM|END TIME';
COL max_aas FOR 99,999 HEA 'LOGON STORM|MAX AAS';
COL max_machines FOR 999,990 HEA 'LOGON STORM|MAX AAS';
COL seconds FOR 999,990 HEA 'LOGON STORM|SECONDS';
COL max_pdbs FOR 999,990 HEA 'LOGON STORM|MAX PDBS';
COL begin_mode FOR A15 HEA 'AWR SNAP|BEGIN MODE';
COL end_mode FOR A15 HEA 'AWR SNAP|END MODE';
COL mode_switch FOR A7 HEA 'MODE|SWITCH';
COL switch_over FOR A7 HEA 'SWITCH|OVER';
--
BREAK ON mode_switch SKIP 1 DUPL;
--
PRO
PRO DG PROTECTION MODE SWITCHES
PRO ~~~~~~~~~~~~~~~~~~~~~~~~~~~
WITH
parameter_hist AS (
SELECT /*+ MATERIALIZE NO_MERGE */
h.snap_id,
h.dbid,
h.instance_number,
h.parameter_name,
LAG(h.value) OVER (PARTITION BY h.dbid, h.instance_number, h.parameter_name, h.con_id ORDER BY h.snap_id) AS prior_value,
h.value,
h.con_id
FROM dba_hist_parameter h
WHERE parameter_name LIKE 'log_archive_dest%'
AND parameter_name NOT LIKE 'log_archive_dest_state%'
),
parameter_changes AS (
SELECT /*+ MATERIALIZE NO_MERGE */
h.snap_id,
h.dbid,
h.instance_number,
h.parameter_name,
h.prior_value,
h.value,
REPLACE(REPLACE(REGEXP_SUBSTR(h.prior_value, '\(HOST=([[:alnum:]]|\.|-)+\)'), '(HOST='), ')') AS begin_host,
REPLACE(REPLACE(REGEXP_SUBSTR(h.value, '\(HOST=([[:alnum:]]|\.|-)+\)'), '(HOST='), ')') AS end_host,
CASE
WHEN h.prior_value LIKE '% SYNC AFFIRM %' THEN 'SYNC AFFIRM'
WHEN h.prior_value LIKE '% ASYNC AFFIRM %' THEN 'ASYNC AFFIRM' -- not expected
WHEN h.prior_value LIKE '% SYNC NOAFFIRM %' THEN 'SYNC NOAFFIRM' -- not expected
WHEN h.prior_value LIKE '% ASYNC NOAFFIRM %' THEN 'ASYNC NOAFFIRM'
END AS begin_mode,
CASE
WHEN h.value LIKE '% SYNC AFFIRM %' THEN 'SYNC AFFIRM'
WHEN h.value LIKE '% ASYNC AFFIRM %' THEN 'ASYNC AFFIRM' -- not expected
WHEN h.value LIKE '% SYNC NOAFFIRM %' THEN 'SYNC NOAFFIRM' -- not expected
WHEN h.value LIKE '% ASYNC NOAFFIRM %' THEN 'ASYNC NOAFFIRM'
END AS end_mode,
h.con_id,
s.begin_interval_time,
s.end_interval_time
FROM parameter_hist h,
dba_hist_snapshot s
WHERE NVL(h.value, '-666') <> NVL(h.prior_value, '-666')
AND h.prior_value LIKE '%(HOST=%'
AND h.value LIKE '%(HOST=%'
AND s.snap_id = h.snap_id
AND s.dbid = h.dbid
AND s.instance_number = h.instance_number
),
dg_mode_switches AS (
SELECT CAST(p.begin_interval_time AS DATE) AS begin_time,
CAST(p.end_interval_time AS DATE) AS end_time,
p.begin_mode,
p.end_mode,
p.begin_host,
p.end_host
FROM parameter_changes p
),
over_height AS (
SELECT /*+ MATERIALIZE NO_MERGE */
h.sample_time,
COUNT(*) AS aas,
COUNT(DISTINCT machine) AS machines,
COUNT(DISTINCT con_id) AS pdbs,
(CAST(h.sample_time AS DATE) - LAG(CAST(h.sample_time AS DATE)) OVER (ORDER BY h.sample_time)) * 24 * 3600 AS secs_from_prior
FROM dba_hist_active_sess_history h
GROUP BY
h.sample_time
HAVING COUNT(*) > 1000 -- active sessions!
),
over_time AS (
SELECT CAST(h.sample_time AS DATE) AS sample_time,
h.aas,
h.machines,
h.pdbs
FROM over_height h
WHERE secs_from_prior < 20 -- contiguous
),
logon_storms AS (
SELECT TRUNC(sample_time) AS date_time,
MIN(sample_time - (20/24/3600)) AS min_date_time,
MAX(sample_time) AS max_date_time,
((MAX(sample_time) - MIN(sample_time)) * 24 * 3600) + 20 AS seconds,
MAX(aas) AS max_aas,
MAX(machines) AS max_machines,
MAX(pdbs) AS max_pdbs
FROM over_time
GROUP BY
TRUNC(sample_time)
)
SELECT dg.begin_time,
dg.end_time,
dg.begin_mode,
dg.end_mode,
CASE dg.begin_mode WHEN 'ASYNC NOAFFIRM' THEN 'HP' WHEN 'SYNC AFFIRM' THEN 'HA' END||'->'||
CASE dg.end_mode WHEN 'ASYNC NOAFFIRM' THEN 'HP' WHEN 'SYNC AFFIRM' THEN 'HA' END AS mode_switch,
ls.min_date_time,
ls.max_date_time,
ls.seconds,
ls.max_aas,
ls.max_pdbs,
dg.begin_host,
dg.end_host,
CASE WHEN dg.begin_host <> dg.end_host THEN 'YES' ELSE 'NO' END AS switch_over
FROM dg_mode_switches dg
OUTER APPLY (
SELECT s.min_date_time,
s.max_date_time,
s.seconds,
s.max_aas,
s.max_pdbs
FROM logon_storms s
WHERE (s.min_date_time BETWEEN dg.begin_time AND dg.end_time OR s.max_date_time BETWEEN dg.begin_time AND dg.end_time)
AND ROWNUM >= 1 /* MATERIALIZE NO_MERGE */
ORDER BY
s.min_date_time ASC
FETCH FIRST 1 ROW ONLY
) ls
ORDER BY
dg.begin_time
/
--
PRO
PRO SQL> @&&cs_script_name..sql
--
@@cs_internal/cs_spool_tail.sql
--
@@cs_internal/&&cs_set_container_to_curr_pdb.
--
@@cs_internal/cs_undef.sql
@@cs_internal/cs_reset.sql
--