521 lines
26 KiB
MySQL
521 lines
26 KiB
MySQL
|
|
----------------------------------------------------------------------------------------
|
||
|
|
--
|
||
|
|
-- File name: cs_sprf_export.sql
|
||
|
|
--
|
||
|
|
-- Purpose: Exports Execution Plans for some SQL_ID or all SQL on a PDB using SQL Profile(s)
|
||
|
|
--
|
||
|
|
-- Author: Carlos Sierra
|
||
|
|
--
|
||
|
|
-- Version: 2023/01/04
|
||
|
|
--
|
||
|
|
-- Usage: Connecting into PDB.
|
||
|
|
--
|
||
|
|
-- Enter optional SQL Text Piece or SQL_ID when requested.
|
||
|
|
--
|
||
|
|
-- Example: $ sqlplus / as sysdba
|
||
|
|
-- SQL> @cs_sprf_export.sql
|
||
|
|
--
|
||
|
|
-- Notes: Developed and tested on 12.1.0.2 and 19c.
|
||
|
|
-- Application agnostic
|
||
|
|
-- KIEV aware
|
||
|
|
-- KIEV Statement Caching aware
|
||
|
|
--
|
||
|
|
---------------------------------------------------------------------------------------
|
||
|
|
--
|
||
|
|
@@cs_internal/cs_primary.sql
|
||
|
|
@@cs_internal/cs_cdb_warn.sql
|
||
|
|
@@cs_internal/cs_set.sql
|
||
|
|
@@cs_internal/cs_def.sql
|
||
|
|
@@cs_internal/cs_file_prefix.sql
|
||
|
|
--
|
||
|
|
DEF cs_script_name = 'cs_sprf_export';
|
||
|
|
--
|
||
|
|
COL parsing_schema_name FOR A30;
|
||
|
|
WITH
|
||
|
|
u AS
|
||
|
|
(SELECT /*+ MATERIALIZE NO_MERGE */ user_id, username FROM dba_users WHERE oracle_maintained = 'N' AND common = 'NO' AND ROWNUM >= 1 /* MATERIALIZE NO_MERGE */)
|
||
|
|
SELECT s.parsing_schema_name, COUNT(*) AS sql_statements
|
||
|
|
FROM v$sql s, u
|
||
|
|
WHERE s.plan_hash_value > 0 -- e.g.: PL/SQL has 0 on PHV
|
||
|
|
AND s.exact_matching_signature > 0 -- INSERT from values has 0 on signature
|
||
|
|
AND s.executions > 0
|
||
|
|
AND s.cpu_time > 0
|
||
|
|
AND s.buffer_gets > 0
|
||
|
|
AND s.object_status = 'VALID'
|
||
|
|
AND s.is_obsolete = 'N'
|
||
|
|
AND s.is_shareable = 'Y'
|
||
|
|
AND s.is_resolved_adaptive_plan IS NULL -- to ignore adaptive plans which cause trouble when combined with SPM
|
||
|
|
AND s.last_active_time > SYSDATE - 1
|
||
|
|
AND s.parsing_user_id > 0 -- ddl and stats gathering have parsing_user_id = 0
|
||
|
|
AND u.username = s.parsing_schema_name
|
||
|
|
GROUP BY
|
||
|
|
s.parsing_schema_name
|
||
|
|
ORDER BY
|
||
|
|
s.parsing_schema_name
|
||
|
|
/
|
||
|
|
PRO
|
||
|
|
PRO 1. Parsing Schema Name: (opt)
|
||
|
|
DEF cs_parsing_schema_name = '&1.';
|
||
|
|
UNDEF 1;
|
||
|
|
--
|
||
|
|
PRO
|
||
|
|
PRO 2. SQL Text piece (e.g.: ScanQuery, getValues, TableName, IndexName): (opt)
|
||
|
|
DEF cs2_sql_text_piece = '&2.';
|
||
|
|
UNDEF 2;
|
||
|
|
--
|
||
|
|
PRO
|
||
|
|
PRO 3. SQL_ID: (opt)
|
||
|
|
DEF cs_sql_id = '&3.';
|
||
|
|
UNDEF 3;
|
||
|
|
--
|
||
|
|
SELECT '&&cs_file_prefix._&&cs_script_name.' AS cs_file_name FROM DUAL;
|
||
|
|
--
|
||
|
|
@@cs_internal/cs_spool_head.sql
|
||
|
|
PRO SQL> @&&cs_script_name..sql "&&cs_parsing_schema_name." "&&cs2_sql_text_piece." "&&cs_sql_id."
|
||
|
|
@@cs_internal/cs_spool_id.sql
|
||
|
|
--
|
||
|
|
PRO SCHEMA_NAME : "&&cs_parsing_schema_name."
|
||
|
|
PRO SQL_TEXT : "&&cs2_sql_text_piece."
|
||
|
|
PRO SQL_ID : "&&cs_sql_id."
|
||
|
|
--
|
||
|
|
COL export_version NEW_V export_version NOPRI;
|
||
|
|
SELECT TO_CHAR(SYSDATE, 'HH24MISS') AS export_version FROM DUAL;
|
||
|
|
VAR v_exported NUMBER;
|
||
|
|
EXEC :v_exported := 0;
|
||
|
|
--
|
||
|
|
PRO please wait...
|
||
|
|
SET HEA OFF PAGES 0 TERM OFF SERVEROUT ON;
|
||
|
|
/* ========================================================================================== */
|
||
|
|
-- IMPLEMENT scrip
|
||
|
|
SPO &&cs_file_name._IMPLEMENT.sql;
|
||
|
|
DECLARE
|
||
|
|
l_pos INTEGER;
|
||
|
|
l_pos2 INTEGER;
|
||
|
|
l_hint VARCHAR2(4000);
|
||
|
|
--
|
||
|
|
PROCEDURE o(p_line IN VARCHAR2) IS BEGIN DBMS_OUTPUT.put_line(p_line); END;
|
||
|
|
BEGIN
|
||
|
|
o('/* -------------------------------------------------------------------------------------- */');
|
||
|
|
o('--');
|
||
|
|
o('-- File name: &&cs_file_name._IMPLEMENT.sql');
|
||
|
|
o('--');
|
||
|
|
o('-- Purpose: Implements Execution Plans for some SQL_ID or all SQL on a PDB using SQL Profile(s)');
|
||
|
|
o('--');
|
||
|
|
o('-- Author: Carlos Sierra');
|
||
|
|
o('--');
|
||
|
|
o('-- Version: 2022/02/22');
|
||
|
|
o('--');
|
||
|
|
o('-- Usage: Connecting into PDB.');
|
||
|
|
o('--');
|
||
|
|
o('-- Example: $ sqlplus / as sysdba');
|
||
|
|
o('-- SQL> @&&cs_file_name._IMPLEMENT.sql');
|
||
|
|
o('--');
|
||
|
|
o('/* -------------------------------------------------------------------------------------- */');
|
||
|
|
o('-- exit if executed on standby or from CDB$ROOT');
|
||
|
|
o('WHENEVER SQLERROR EXIT FAILURE;');
|
||
|
|
o('DECLARE');
|
||
|
|
o(' l_is_primary VARCHAR2(5);');
|
||
|
|
o('BEGIN');
|
||
|
|
o(' SELECT CASE WHEN open_mode = ''READ WRITE'' AND database_role = ''PRIMARY'' THEN ''TRUE'' ELSE ''FALSE'' END AS is_primary INTO l_is_primary FROM v$database;');
|
||
|
|
o(' IF l_is_primary = ''FALSE'' THEN raise_application_error(-20000, ''*** MUST EXECUTE ON READ WRITE PRIMARY ***''); END IF;');
|
||
|
|
o(' IF SYS_CONTEXT(''USERENV'', ''CON_NAME'') = ''CDB$ROOT'' THEN raise_application_error(-20000, ''*** MUST EXECUTE ON PDB AND NOT ON CDB$ROOT ***''); END IF;');
|
||
|
|
o('END;');
|
||
|
|
o('/');
|
||
|
|
o('WHENEVER SQLERROR CONTINUE;');
|
||
|
|
o('--');
|
||
|
|
o('SET HEA ON LIN 2490 PAGES 100 TAB OFF FEED OFF ECHO OFF VER OFF TRIMS ON TRIM ON TI OFF TIMI OFF LONG 240000 LONGC 2400 NUM 20 SERVEROUT OFF;');
|
||
|
|
o('SET SERVEROUT ON;');
|
||
|
|
o('COL report_time NEW_V report_time NOPRI;');
|
||
|
|
o('SELECT TO_CHAR(SYSDATE, ''YYYY-MM-DD"T"HH24.MI.SS'') AS report_time FROM DUAL;');
|
||
|
|
o('--');
|
||
|
|
o('SPO &&cs_file_name._IMPLEMENT_&&double_ampersand.report_time..txt;');
|
||
|
|
o('PRO PRO');
|
||
|
|
o('PRO PRO &&cs_file_name._IMPLEMENT_&&double_ampersand.report_time..txt');
|
||
|
|
o('PRO PRO');
|
||
|
|
o('--');
|
||
|
|
o('VAR v_implemented NUMBER;');
|
||
|
|
o('EXEC :v_implemented := 0;');
|
||
|
|
o('--');
|
||
|
|
o('DEF kievbuckets_owner = '''';');
|
||
|
|
o('COL kievbuckets_owner NEW_V kievbuckets_owner NOPRI;');
|
||
|
|
--o('SELECT owner AS kievbuckets_owner FROM dba_tables WHERE table_name = ''KIEVDATASTOREMETADATA'' AND owner NOT IN (''APP_USER'', ''PDBADMIN'') ORDER BY last_analyzed DESC NULLS LAST FETCH FIRST 1 ROW ONLY;');
|
||
|
|
o('SELECT owner AS kievbuckets_owner FROM dba_tables WHERE table_name = ''KIEVDATASTOREMETADATA'' AND owner NOT IN (''PDBADMIN'') ORDER BY last_analyzed DESC NULLS LAST FETCH FIRST 1 ROW ONLY;');
|
||
|
|
-- main cursor
|
||
|
|
FOR i IN (WITH
|
||
|
|
u AS
|
||
|
|
(SELECT /*+ MATERIALIZE NO_MERGE */ user_id, username FROM dba_users WHERE oracle_maintained = 'N' AND common = 'NO' AND ROWNUM >= 1 /* MATERIALIZE NO_MERGE */),
|
||
|
|
s AS
|
||
|
|
(
|
||
|
|
SELECT s.exact_matching_signature AS signature, s.sql_id, s.plan_hash_value, x.plan_hash_value_2, s.sql_text,
|
||
|
|
CASE WHEN '&&cs_kiev_owner.' IS NOT NULL THEN REPLACE(s.sql_fulltext, s.parsing_schema_name||'.', '#kievbuckets_owner#.') ELSE s.sql_fulltext END AS sql_fulltext,
|
||
|
|
s.parsing_schema_name, x.other_xml,
|
||
|
|
ROW_NUMBER() OVER (PARTITION BY s.exact_matching_signature, s.sql_id ORDER BY s.last_active_time DESC) AS rn,
|
||
|
|
-- bucket_name and bucket_id are KIEV specific, and needed to support statement caching on KIEV, which requires to embed the bucket_id into sql decoration (e.g. /* performScanQuery(NOTIFICATION_BOARD,EVENT_BY_SCHEDULED_TIME) [1002] */)
|
||
|
|
CASE
|
||
|
|
WHEN s.sql_text LIKE '%/* %(%,%)% [%] */%' AND (s.sql_text LIKE '%performScanQuery%' OR s.sql_text LIKE '%performSegmentedScanQuery%' OR s.sql_text LIKE '%getValues%')
|
||
|
|
THEN SUBSTR(s.sql_fulltext, INSTR(s.sql_fulltext, '(') + 1, INSTR(s.sql_fulltext, ',') - INSTR(s.sql_fulltext, '(') - 1)
|
||
|
|
END AS bucket_name,
|
||
|
|
CASE
|
||
|
|
WHEN s.sql_text LIKE '%/* %(%,%)% [%] */%' AND (s.sql_text LIKE '%performScanQuery%' OR s.sql_text LIKE '%performSegmentedScanQuery%' OR s.sql_text LIKE '%getValues%')
|
||
|
|
THEN SUBSTR(s.sql_fulltext, INSTR(s.sql_fulltext, '[') + 1, INSTR(s.sql_fulltext, ']') - INSTR(s.sql_fulltext, '[') - 1)
|
||
|
|
END AS bucket_id
|
||
|
|
FROM v$sql s, u u1, u u2
|
||
|
|
OUTER APPLY (
|
||
|
|
SELECT p.other_xml, TO_NUMBER(EXTRACTVALUE(XMLTYPE(p.other_xml),'/*/info[@type = "plan_hash_2"]')) AS plan_hash_value_2
|
||
|
|
FROM v$sql_plan p
|
||
|
|
WHERE p.address = s.address
|
||
|
|
AND p.hash_value = s.hash_value
|
||
|
|
AND p.sql_id = s.sql_id
|
||
|
|
AND p.plan_hash_value = s.plan_hash_value
|
||
|
|
AND p.child_address = s.child_address
|
||
|
|
AND p.child_number = s.child_number
|
||
|
|
AND p.other_xml IS NOT NULL
|
||
|
|
--AND p.id = 1
|
||
|
|
AND TO_NUMBER(EXTRACTVALUE(XMLTYPE(p.other_xml),'/*/info[@type = "plan_hash_2"]')) >= 0
|
||
|
|
AND ROWNUM = 1
|
||
|
|
) x
|
||
|
|
WHERE s.plan_hash_value > 0 -- e.g.: PL/SQL has 0 on PHV
|
||
|
|
AND s.exact_matching_signature > 0 -- INSERT from values has 0 on signature
|
||
|
|
AND s.executions > 0
|
||
|
|
AND s.cpu_time > 0
|
||
|
|
AND s.buffer_gets > 0
|
||
|
|
--AND s.buffer_gets > s.executions
|
||
|
|
AND s.object_status = 'VALID'
|
||
|
|
AND s.is_obsolete = 'N'
|
||
|
|
AND s.is_shareable = 'Y'
|
||
|
|
-- AND s.is_bind_aware = 'N' -- to ignore cursors using adaptive cursor sharing ACS as per CHANGE-190522
|
||
|
|
AND s.is_resolved_adaptive_plan IS NULL -- to ignore adaptive plans which cause trouble when combined with SPM
|
||
|
|
--AND s.is_reoptimizable = 'N' -- to ignore cursors which require adjustments as per cardinality feedback
|
||
|
|
AND s.parsing_user_id > 0 -- ddl and stats gathering have parsing_user_id = 0
|
||
|
|
AND s.last_active_time > SYSDATE - 1 -- select only sql that has been executed recently
|
||
|
|
AND s.parsing_schema_name = NVL(TRIM('&&cs_parsing_schema_name.'), s.parsing_schema_name)
|
||
|
|
AND s.sql_id = NVL(TRIM('&&cs_sql_id.'), s.sql_id)
|
||
|
|
AND ('&&cs2_sql_text_piece.' IS NULL OR UPPER(s.sql_text) LIKE '%'||UPPER('&&cs2_sql_text_piece.')||'%')
|
||
|
|
AND u1.user_id = s.parsing_user_id
|
||
|
|
AND u2.user_id = s.parsing_schema_id
|
||
|
|
AND x.plan_hash_value_2 > 0 -- (Phv2) includes the hash value of the execution(PLAN_HASH_VALUE) and the hash value of its predicate part.
|
||
|
|
AND ROWNUM >= 1 /* MATERIALIZE NO_MERGE */
|
||
|
|
)
|
||
|
|
SELECT signature, sql_id, plan_hash_value, plan_hash_value_2, SUBSTR(sql_text, 1, 100) AS sql_text_100, sql_text, sql_fulltext, parsing_schema_name, other_xml,
|
||
|
|
bucket_name, bucket_id, CASE WHEN bucket_id IS NULL THEN 'NORMAL' ELSE 'BUCKET' END AS type
|
||
|
|
FROM s
|
||
|
|
WHERE rn = 1
|
||
|
|
ORDER BY
|
||
|
|
signature)
|
||
|
|
LOOP
|
||
|
|
o('--');
|
||
|
|
o('PRO');
|
||
|
|
o('PRO '||i.sql_text_100);
|
||
|
|
o('PRO ['||i.signature||']['||i.sql_id||']['||i.plan_hash_value||']['||i.plan_hash_value_2||']['||i.bucket_name||']['||i.bucket_id||']['||i.type||']['||i.parsing_schema_name||']');
|
||
|
|
o('DECLARE');
|
||
|
|
o('l_plan_name VARCHAR2(30);');
|
||
|
|
o('l_description VARCHAR2(500);');
|
||
|
|
o('l_count NUMBER;');
|
||
|
|
o('l_plans NUMBER;');
|
||
|
|
o('l_target_bucket_id VARCHAR2(6);');
|
||
|
|
o('l_target_signature NUMBER;');
|
||
|
|
o('l_sql_text_clob CLOB;');
|
||
|
|
o('l_profile_attr SYS.SQLPROF_ATTR;');
|
||
|
|
o('PROCEDURE o(p_line IN VARCHAR2) IS BEGIN DBMS_OUTPUT.put_line(p_line); END;');
|
||
|
|
o('BEGIN');
|
||
|
|
o('-- sql_text');
|
||
|
|
o(q'{l_sql_text_clob := q'[}'); -- '
|
||
|
|
l_pos := 1;
|
||
|
|
WHILE l_pos > 0
|
||
|
|
LOOP
|
||
|
|
l_pos2 := INSTR(i.sql_fulltext||CHR(10), CHR(10), l_pos);
|
||
|
|
o(SUBSTR(i.sql_fulltext, l_pos, l_pos2 - l_pos));
|
||
|
|
l_pos := NULLIF(l_pos2, 0) + 1;
|
||
|
|
END LOOP;
|
||
|
|
o(q'{]';}'); -- '
|
||
|
|
o('-- hints');
|
||
|
|
o('l_profile_attr := SYS.SQLPROF_ATTR(');
|
||
|
|
o(q'{q'[BEGIN_OUTLINE_DATA]',}');
|
||
|
|
FOR j IN (SELECT hint FROM XMLTABLE('other_xml/outline_data/hint' PASSING XMLTYPE(i.other_xml) COLUMNS hint VARCHAR2(4000) PATH '.'))
|
||
|
|
LOOP
|
||
|
|
l_hint := j.hint;
|
||
|
|
WHILE l_hint IS NOT NULL
|
||
|
|
LOOP
|
||
|
|
IF LENGTH(l_hint) <= 500 THEN
|
||
|
|
o(q'{q'[}'||l_hint||q'{]',}');
|
||
|
|
l_hint := NULL;
|
||
|
|
ELSE
|
||
|
|
l_pos := INSTR(SUBSTR(l_hint, 1, 500), ' ', -1);
|
||
|
|
o(q'{q'[}'||SUBSTR(l_hint, 1, l_pos)||q'{]',}');
|
||
|
|
l_hint := SUBSTR(l_hint, l_pos);
|
||
|
|
END IF;
|
||
|
|
END LOOP;
|
||
|
|
END LOOP;
|
||
|
|
o(q'{q'[END_OUTLINE_DATA]'}');
|
||
|
|
o(');');
|
||
|
|
o('-- transformations');
|
||
|
|
o('IF '''||i.bucket_id||''' IS NOT NULL THEN -- KIEV Statement Caching specific');
|
||
|
|
o('EXECUTE IMMEDIATE ''SELECT TO_CHAR(bucketid) AS bucket_id FROM &&double_ampersand.kievbuckets_owner..kievbuckets WHERE UPPER(name) = UPPER('''''||i.bucket_name||''''')'' INTO l_target_bucket_id;');
|
||
|
|
o('END IF;');
|
||
|
|
o('IF l_target_bucket_id IS NOT NULL THEN');
|
||
|
|
o('l_sql_text_clob := REPLACE(l_sql_text_clob, ''['||i.bucket_id||']'', ''[''||l_target_bucket_id||'']'');');
|
||
|
|
-- o('l_target_signature := DBMS_SQLTUNE.sqltext_to_signature (sql_text => l_sql_text_clob);');
|
||
|
|
-- o('ELSE');
|
||
|
|
-- o('l_target_signature := '||i.signature||';');
|
||
|
|
o('END IF;');
|
||
|
|
o('IF ''&&double_ampersand.kievbuckets_owner.'' IS NOT NULL THEN -- KIEV Bucket Owner');
|
||
|
|
o('l_sql_text_clob := REPLACE(l_sql_text_clob, ''#kievbuckets_owner#'', ''&&double_ampersand.kievbuckets_owner.'');');
|
||
|
|
o('END IF;');
|
||
|
|
o('l_target_signature := DBMS_SQLTUNE.sqltext_to_signature (sql_text => l_sql_text_clob);');
|
||
|
|
o('o(''[''||l_target_signature||''][''||l_target_bucket_id||'']'');');
|
||
|
|
o('l_plan_name := ''exp_'||i.sql_id||'_&&export_version.''||l_target_bucket_id;');
|
||
|
|
o('l_description := ''[''||l_target_signature||'']['||i.plan_hash_value||']['||i.plan_hash_value_2||']['||i.signature||']['||i.sql_id||']['||i.bucket_name||']['||i.bucket_id||'][&&cs_rgn.][&&cs_db_name_u.][&&cs_con_name.][EXP]['||i.type||'][&&cs_reference.]'';');
|
||
|
|
-- DBPERF-8216 begin
|
||
|
|
o('-- drop unexpected profile');
|
||
|
|
o('FOR i IN (SELECT p.name FROM dba_sql_profiles p WHERE p.name = l_plan_name AND p.signature <> l_target_signature)');
|
||
|
|
o('LOOP');
|
||
|
|
o('o(''SPRF drop: ''||i.name);');
|
||
|
|
o('DBMS_SQLTUNE.drop_sql_profile(name => i.name, ignore => TRUE);');
|
||
|
|
o('END LOOP;');
|
||
|
|
-- DBPERF-8216 end
|
||
|
|
o('-- disable prior sql_profile');
|
||
|
|
o('FOR i IN (SELECT p.name FROM dba_sql_profiles p WHERE p.signature = l_target_signature AND p.category = ''DEFAULT'' AND p.status = ''ENABLED'' AND NVL(p.description, ''NULL'') NOT LIKE ''%][EXP][%'' AND NOT EXISTS (SELECT NULL FROM dba_sql_profiles e WHERE e.name = p.name AND e.category = ''BACKUP''))');
|
||
|
|
o('LOOP');
|
||
|
|
o('o(''SPRF disable: ''||i.name);');
|
||
|
|
o('DBMS_SQLTUNE.alter_sql_profile(name => i.name, attribute_name => ''CATEGORY'', value => ''BACKUP'');');
|
||
|
|
o('END LOOP;');
|
||
|
|
o('-- create new sql_profile');
|
||
|
|
o('SELECT COUNT(*) INTO l_count FROM dba_sql_profiles WHERE name = l_plan_name;');
|
||
|
|
o('IF l_count = 0 THEN');
|
||
|
|
o('o(''SPRF create: ''||l_plan_name||'' ''||l_description);');
|
||
|
|
o('DBMS_SQLTUNE.import_sql_profile(sql_text => l_sql_text_clob, profile => l_profile_attr, name => l_plan_name, description => l_description, replace => TRUE);');
|
||
|
|
o(':v_implemented := :v_implemented + 1;');
|
||
|
|
-- DBPERF-7594 begin
|
||
|
|
o('ELSE');
|
||
|
|
o('SELECT COUNT(*) INTO l_count FROM dba_sql_profiles WHERE name = l_plan_name AND status = ''DISABLED'';');
|
||
|
|
o('IF l_count > 0 THEN');
|
||
|
|
o('o(''SPRF enable: ''||l_plan_name||'' ''||l_description);');
|
||
|
|
o('DBMS_SQLTUNE.alter_sql_profile(name => l_plan_name, attribute_name => ''STATUS'', value => ''ENABLED'');');
|
||
|
|
o(':v_implemented := :v_implemented + 1;');
|
||
|
|
o('END IF;');
|
||
|
|
-- DBPERF-7594 end
|
||
|
|
o('END IF;');
|
||
|
|
o('-- disable prior sql_patch');
|
||
|
|
o('FOR i IN (SELECT p.name FROM dba_sql_patches p WHERE p.signature = l_target_signature AND p.category = ''DEFAULT'' AND p.status = ''ENABLED'' AND NOT EXISTS (SELECT NULL FROM dba_sql_patches e WHERE e.name = p.name AND e.category = ''BACKUP''))');
|
||
|
|
o('LOOP');
|
||
|
|
o('o(''SPCH disable: ''||i.name);');
|
||
|
|
o('$IF DBMS_DB_VERSION.ver_le_12_1');
|
||
|
|
o('$THEN');
|
||
|
|
o('DBMS_SQLDIAG.alter_sql_patch(name => i.name, attribute_name => ''CATEGORY'', value => ''BACKUP'');');
|
||
|
|
o('$ELSE');
|
||
|
|
o('DBMS_SQLDIAG.alter_sql_patch(name => i.name, attribute_name => ''CATEGORY'', attribute_value => ''BACKUP'');');
|
||
|
|
o('$END');
|
||
|
|
o('END LOOP;');
|
||
|
|
o('-- disable prior sql_plan_baseline');
|
||
|
|
o('FOR i IN (SELECT p.sql_handle, p.plan_name, p.description FROM dba_sql_plan_baselines p WHERE p.signature = l_target_signature AND p.enabled = ''YES'' AND p.accepted = ''YES'')');
|
||
|
|
o('LOOP');
|
||
|
|
o('o(''SPBL disable: ''||i.sql_handle||'' ''||i.plan_name||'' ''||i.description);');
|
||
|
|
o('l_plans := DBMS_SPM.alter_sql_plan_baseline(sql_handle => i.sql_handle, plan_name => i.plan_name, attribute_name => ''ENABLED'', attribute_value => ''NO'');');
|
||
|
|
o('IF NVL(i.description, ''NULL'') NOT LIKE ''%[&&export_version.]%'' THEN');
|
||
|
|
o('IF LENGTH(i.description) > 470 THEN');
|
||
|
|
o('l_plans := DBMS_SPM.alter_sql_plan_baseline(sql_handle => i.sql_handle, plan_name => i.plan_name, attribute_name => ''DESCRIPTION'', attribute_value => ''[EXP][&&export_version.]'');');
|
||
|
|
o('ELSE');
|
||
|
|
o('l_plans := DBMS_SPM.alter_sql_plan_baseline(sql_handle => i.sql_handle, plan_name => i.plan_name, attribute_name => ''DESCRIPTION'', attribute_value => i.description||'' [EXP][&&export_version.]'');');
|
||
|
|
o('END IF;');
|
||
|
|
o('o(''SPBL update: [EXP][&&export_version.]'');');
|
||
|
|
o('END IF;');
|
||
|
|
o('END LOOP;');
|
||
|
|
o('END;');
|
||
|
|
o('/');
|
||
|
|
:v_exported := :v_exported + 1;
|
||
|
|
END LOOP;
|
||
|
|
o('--');
|
||
|
|
o('PRINT v_implemented;');
|
||
|
|
o('PRO PRO');
|
||
|
|
o('PRO PRO &&cs_file_name._IMPLEMENT_&&double_ampersand.report_time..txt');
|
||
|
|
o('PRO PRO');
|
||
|
|
o('SPO OFF;');
|
||
|
|
o('SET SERVEROUT OFF;');
|
||
|
|
o('--');
|
||
|
|
o('-- &&cs_file_name._IMPLEMENT.sql');
|
||
|
|
o('--');
|
||
|
|
o('HOS ls -l &&cs_file_name._IMPLEMENT*');
|
||
|
|
END;
|
||
|
|
/
|
||
|
|
SPO OFF;
|
||
|
|
HOS chmod 644 &&cs_file_name._IMPLEMENT.sql
|
||
|
|
/* ========================================================================================== */
|
||
|
|
-- ROLLBACK scrip
|
||
|
|
SPO &&cs_file_name._ROLLBACK.sql;
|
||
|
|
DECLARE
|
||
|
|
PROCEDURE o(p_line IN VARCHAR2) IS BEGIN DBMS_OUTPUT.put_line(p_line); END;
|
||
|
|
BEGIN
|
||
|
|
o('/* -------------------------------------------------------------------------------------- */');
|
||
|
|
o('--');
|
||
|
|
o('-- File name: &&cs_file_name._ROLLBACK.sql');
|
||
|
|
o('--');
|
||
|
|
o('-- Purpose: Rollsback Execution Plans for some SQL_ID or all SQL on a PDB using SQL Profile(s)');
|
||
|
|
o('--');
|
||
|
|
o('-- Author: Carlos Sierra');
|
||
|
|
o('--');
|
||
|
|
o('-- Version: 2022/02/14');
|
||
|
|
o('--');
|
||
|
|
o('-- Usage: Connecting into PDB.');
|
||
|
|
o('--');
|
||
|
|
o('-- Example: $ sqlplus / as sysdba');
|
||
|
|
o('-- SQL> @&&cs_file_name._ROLLBACK.sql');
|
||
|
|
o('--');
|
||
|
|
o('/* --------------------------------------------------------------------------------------- */');
|
||
|
|
o('-- exit if executed on standby or from CDB$ROOT');
|
||
|
|
o('WHENEVER SQLERROR EXIT FAILURE;');
|
||
|
|
o('DECLARE');
|
||
|
|
o(' l_is_primary VARCHAR2(5);');
|
||
|
|
o('BEGIN');
|
||
|
|
o(' SELECT CASE WHEN open_mode = ''READ WRITE'' AND database_role = ''PRIMARY'' THEN ''TRUE'' ELSE ''FALSE'' END AS is_primary INTO l_is_primary FROM v$database;');
|
||
|
|
o(' IF l_is_primary = ''FALSE'' THEN raise_application_error(-20000, ''*** MUST EXECUTE ON READ WRITE PRIMARY ***''); END IF;');
|
||
|
|
o(' IF SYS_CONTEXT(''USERENV'', ''CON_NAME'') = ''CDB$ROOT'' THEN raise_application_error(-20000, ''*** MUST EXECUTE ON PDB AND NOT ON CDB$ROOT ***''); END IF;');
|
||
|
|
o('END;');
|
||
|
|
o('/');
|
||
|
|
o('WHENEVER SQLERROR CONTINUE;');
|
||
|
|
o('--');
|
||
|
|
o('SET HEA ON LIN 2490 PAGES 100 TAB OFF FEED OFF ECHO OFF VER OFF TRIMS ON TRIM ON TI OFF TIMI OFF LONG 240000 LONGC 2400 NUM 20 SERVEROUT OFF;');
|
||
|
|
o('SET SERVEROUT ON;');
|
||
|
|
o('COL report_time NEW_V report_time NOPRI;');
|
||
|
|
o('SELECT TO_CHAR(SYSDATE, ''YYYY-MM-DD"T"HH24.MI.SS'') AS report_time FROM DUAL;');
|
||
|
|
o('--');
|
||
|
|
o('SPO &&cs_file_name._ROLLBACK_&&double_ampersand.report_time..txt;');
|
||
|
|
o('PRO PRO');
|
||
|
|
o('PRO PRO &&cs_file_name._ROLLBACK_&&double_ampersand.report_time..txt');
|
||
|
|
o('PRO PRO');
|
||
|
|
o('VAR v_rolled_back NUMBER;');
|
||
|
|
o('EXEC :v_rolled_back := 0;');
|
||
|
|
o('--');
|
||
|
|
o('DECLARE');
|
||
|
|
o('l_plans NUMBER;');
|
||
|
|
o('PROCEDURE o(p_line IN VARCHAR2) IS BEGIN DBMS_OUTPUT.put_line(p_line); END;');
|
||
|
|
o('BEGIN');
|
||
|
|
o('o(''~~~~~~~~~~~~~~~~~~~~~~~~~~'');');
|
||
|
|
o('o(''drop imported sql_profiles'');');
|
||
|
|
o('o(''~~~~~~~~~~~~~~~~~~~~~~~~~~'');');
|
||
|
|
o('FOR i IN (SELECT name FROM dba_sql_profiles WHERE name LIKE ''exp_%_&&export_version.%'' AND category = ''DEFAULT'' AND status = ''ENABLED'' AND description LIKE ''%][EXP][%'')');
|
||
|
|
o('LOOP');
|
||
|
|
o('o(''SPRF drop: ''||i.name);');
|
||
|
|
o('DBMS_SQLTUNE.drop_sql_profile(name => i.name);');
|
||
|
|
o(':v_rolled_back := :v_rolled_back + 1;');
|
||
|
|
o('END LOOP;');
|
||
|
|
o('o(''~~~~~~~~~~~~~~~~~~~~~~~~~'');');
|
||
|
|
o('o(''enable prior sql_profiles'');');
|
||
|
|
o('o(''~~~~~~~~~~~~~~~~~~~~~~~~~'');');
|
||
|
|
o('FOR i IN (SELECT name FROM dba_sql_profiles WHERE name NOT LIKE ''exp_%_&&export_version.%'' AND category = ''BACKUP'' AND status = ''ENABLED'' AND NVL(description, ''NULL'') NOT LIKE ''%][EXP][%'')');
|
||
|
|
o('LOOP');
|
||
|
|
o('o(''SPRF enable: ''||i.name);');
|
||
|
|
o('DBMS_SQLTUNE.alter_sql_profile(name => i.name, attribute_name => ''CATEGORY'', value => ''DEFAULT'');');
|
||
|
|
o('END LOOP;');
|
||
|
|
o('o(''~~~~~~~~~~~~~~~~~~~~~~~~'');');
|
||
|
|
o('o(''enable prior sql_patches'');');
|
||
|
|
o('o(''~~~~~~~~~~~~~~~~~~~~~~~~'');');
|
||
|
|
o('FOR i IN (SELECT p.name FROM dba_sql_patches p WHERE p.category = ''BACKUP'' AND p.status = ''ENABLED'' AND NOT EXISTS (SELECT NULL FROM dba_sql_patches e WHERE e.name = p.name AND e.category = ''DEFAULT''))');
|
||
|
|
o('LOOP');
|
||
|
|
o('o(''SPCH enable: ''||i.name);');
|
||
|
|
o('$IF DBMS_DB_VERSION.ver_le_12_1');
|
||
|
|
o('$THEN');
|
||
|
|
o('DBMS_SQLDIAG.alter_sql_patch(name => i.name, attribute_name => ''CATEGORY'', value => ''DEFAULT'');');
|
||
|
|
o('$ELSE');
|
||
|
|
o('DBMS_SQLDIAG.alter_sql_patch(name => i.name, attribute_name => ''CATEGORY'', attribute_value => ''DEFAULT'');');
|
||
|
|
o('$END');
|
||
|
|
o('END LOOP;');
|
||
|
|
o('o(''~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'');');
|
||
|
|
o('o(''enable prior sql_plan_baselines'');');
|
||
|
|
o('o(''~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'');');
|
||
|
|
o('FOR i IN (SELECT p.sql_handle, p.plan_name, p.description FROM dba_sql_plan_baselines p WHERE p.enabled = ''NO'' AND p.accepted = ''YES'' AND p.description LIKE ''%[&&export_version.]%'')');
|
||
|
|
o('LOOP');
|
||
|
|
o('o(''SPBL enable: ''||i.sql_handle||'' ''||i.plan_name||'' ''||i.description);');
|
||
|
|
o('l_plans := DBMS_SPM.alter_sql_plan_baseline(sql_handle => i.sql_handle, plan_name => i.plan_name, attribute_name => ''ENABLED'', attribute_value => ''YES'');');
|
||
|
|
o('END LOOP;');
|
||
|
|
o('END;');
|
||
|
|
o('/');
|
||
|
|
o('--');
|
||
|
|
o('PRINT v_rolled_back;');
|
||
|
|
o('PRO PRO');
|
||
|
|
o('PRO PRO &&cs_file_name._ROLLBACK_&&double_ampersand.report_time..txt');
|
||
|
|
o('PRO PRO');
|
||
|
|
o('SPO OFF;');
|
||
|
|
o('SET SERVEROUT OFF;');
|
||
|
|
o('--');
|
||
|
|
o('-- &&cs_file_name._ROLLBACK.sql');
|
||
|
|
o('--');
|
||
|
|
o('HOS ls -l &&cs_file_name._ROLLBACK*');
|
||
|
|
END;
|
||
|
|
/
|
||
|
|
SPO OFF;
|
||
|
|
HOS chmod 644 &&cs_file_name._ROLLBACK.sql
|
||
|
|
/* ========================================================================================== */
|
||
|
|
-- VERIFY scrip
|
||
|
|
SPO &&cs_file_name._VERIFY.sql;
|
||
|
|
DECLARE
|
||
|
|
PROCEDURE o(p_line IN VARCHAR2) IS BEGIN DBMS_OUTPUT.put_line(p_line); END;
|
||
|
|
BEGIN
|
||
|
|
o('/* -------------------------------------------------------------------------------------- */');
|
||
|
|
o('--');
|
||
|
|
o('-- File name: &&cs_file_name._VERIFY.sql');
|
||
|
|
o('--');
|
||
|
|
o('-- Purpose: Verify Implemented Execution Plans for some SQL_ID or all SQL on a PDB using SQL Profile(s)');
|
||
|
|
o('--');
|
||
|
|
o('-- Author: Carlos Sierra');
|
||
|
|
o('--');
|
||
|
|
o('-- Version: 2022/02/14');
|
||
|
|
o('--');
|
||
|
|
o('-- Usage: Connecting into PDB.');
|
||
|
|
o('--');
|
||
|
|
o('-- Example: $ sqlplus / as sysdba');
|
||
|
|
o('-- SQL> @&&cs_file_name._VERIFY.sql');
|
||
|
|
o('--');
|
||
|
|
o('/* --------------------------------------------------------------------------------------- */');
|
||
|
|
o('-- exit if executed on standby or from CDB$ROOT');
|
||
|
|
o('WHENEVER SQLERROR EXIT FAILURE;');
|
||
|
|
o('DECLARE');
|
||
|
|
o(' l_is_primary VARCHAR2(5);');
|
||
|
|
o('BEGIN');
|
||
|
|
o(' SELECT CASE WHEN open_mode = ''READ WRITE'' AND database_role = ''PRIMARY'' THEN ''TRUE'' ELSE ''FALSE'' END AS is_primary INTO l_is_primary FROM v$database;');
|
||
|
|
o(' IF l_is_primary = ''FALSE'' THEN raise_application_error(-20000, ''*** MUST EXECUTE ON READ WRITE PRIMARY ***''); END IF;');
|
||
|
|
o(' IF SYS_CONTEXT(''USERENV'', ''CON_NAME'') = ''CDB$ROOT'' THEN raise_application_error(-20000, ''*** MUST EXECUTE ON PDB AND NOT ON CDB$ROOT ***''); END IF;');
|
||
|
|
o('END;');
|
||
|
|
o('/');
|
||
|
|
o('WHENEVER SQLERROR CONTINUE;');
|
||
|
|
o('--');
|
||
|
|
o('SET HEA ON LIN 2490 PAGES 100 TAB OFF FEED OFF ECHO OFF VER OFF TRIMS ON TRIM ON TI OFF TIMI OFF LONG 240000 LONGC 2400 NUM 20 SERVEROUT OFF;');
|
||
|
|
o('SET FEED ON SERVEROUT ON;');
|
||
|
|
o('COL report_time NEW_V report_time NOPRI;');
|
||
|
|
o('SELECT TO_CHAR(SYSDATE, ''YYYY-MM-DD"T"HH24.MI.SS'') AS report_time FROM DUAL;');
|
||
|
|
o('--');
|
||
|
|
o('SPO &&cs_file_name._VERIFY_&&double_ampersand.report_time..txt;');
|
||
|
|
o('PRO PRO');
|
||
|
|
o('PRO PRO &&cs_file_name._VERIFY_&&double_ampersand.report_time..txt');
|
||
|
|
o('PRO PRO');
|
||
|
|
o('SELECT * FROM dba_sql_profiles WHERE name LIKE ''exp_%_&&export_version.%'' AND category = ''DEFAULT'' AND status = ''ENABLED'' AND description LIKE ''%][EXP][%'';');
|
||
|
|
o('PRO PRO');
|
||
|
|
o('PRO PRO &&cs_file_name._VERIFY_&&double_ampersand.report_time..txt');
|
||
|
|
o('PRO PRO');
|
||
|
|
o('SPO OFF;');
|
||
|
|
o('SET FEED OFF SERVEROUT OFF;');
|
||
|
|
o('--');
|
||
|
|
o('-- &&cs_file_name._VERIFY.sql');
|
||
|
|
o('--');
|
||
|
|
o('HOS ls -l &&cs_file_name._VERIFY*');
|
||
|
|
END;
|
||
|
|
/
|
||
|
|
SPO OFF;
|
||
|
|
HOS chmod 644 &&cs_file_name._VERIFY.sql
|
||
|
|
/* ========================================================================================== */
|
||
|
|
SET HEA ON PAGES 100 TERM ON SERVEROUT OFF;
|
||
|
|
--
|
||
|
|
-- continues with original spool
|
||
|
|
SPO &&cs_file_name..txt APP
|
||
|
|
PRO
|
||
|
|
PRINT v_exported;
|
||
|
|
--
|
||
|
|
PRO
|
||
|
|
PRO SQL> @&&cs_script_name..sql "&&cs_parsing_schema_name." "&&cs2_sql_text_piece." "&&cs_sql_id."
|
||
|
|
--
|
||
|
|
@@cs_internal/cs_spool_tail.sql
|
||
|
|
@@cs_internal/cs_undef.sql
|
||
|
|
@@cs_internal/cs_reset.sql
|
||
|
|
--
|
||
|
|
PRO
|
||
|
|
HOS ls -l &&cs_file_prefix._&&cs_script_name.*.*
|
||
|
|
--
|