2026-03-12 20:23:15
This commit is contained in:
310
vg/statspack_consolidation_vg.sql
Normal file
310
vg/statspack_consolidation_vg.sql
Normal file
@@ -0,0 +1,310 @@
|
||||
/*
|
||||
*
|
||||
* Author : Vishal Gupta
|
||||
* Purpose : Merge statspack from multiple sources into single database
|
||||
*
|
||||
* Revision History:
|
||||
* ===================
|
||||
* Date Author Description
|
||||
* --------- ------------ -----------------------------------------
|
||||
* 05-Aug-07 Vishal Gupta First Draft
|
||||
*/
|
||||
|
||||
set serveroutput on size 1000000
|
||||
set verify off
|
||||
|
||||
DECLARE
|
||||
sql_text VARCHAR2(32767);
|
||||
v_env_type VARCHAR2(30) := 'PROD';
|
||||
v_db_version VARCHAR2(30) := '10.2';
|
||||
v_instance VARCHAR2(30) := 'TRIP01PD';
|
||||
v_db_link VARCHAR2(4000) ;
|
||||
v_perfstat_schema_owner VARCHAR2(30) ;
|
||||
v_update_cols_count NUMBER;
|
||||
v_scn NUMBER;
|
||||
v_dbid NUMBER;
|
||||
v_snap_id_exists VARCHAR2(1);
|
||||
v_days NUMBER := 3;
|
||||
v_sqlcode NUMBER := 0;
|
||||
|
||||
|
||||
CURSOR cur_constraint_cols(p_owner DBA_TAB_COLUMNS.OWNER%TYPE
|
||||
, p_table_name DBA_TAB_COLUMNS.TABLE_NAME%TYPE)
|
||||
is
|
||||
SELECT cc.COLUMN_NAME, tc.NULLABLE
|
||||
FROM DBA_CONSTRAINTS C, DBA_CONS_COLUMNS CC , DBA_TAB_COLUMNS tc
|
||||
WHERE C.TABLE_NAME = p_table_name
|
||||
AND C.CONSTRAINT_TYPE in ( 'P' ,'U')
|
||||
AND C.OWNER = p_owner
|
||||
AND C.OWNER = CC.OWNER
|
||||
AND C.CONSTRAINT_NAME = CC.CONSTRAINT_NAME
|
||||
AND C.TABLE_NAME = CC.TABLE_NAME
|
||||
AND cc.OWNER = tc.OWNER
|
||||
AND cc.TABLE_NAME = tc.TABLE_NAME
|
||||
AND cc.COLUMN_NAME = tc.COLUMN_NAME
|
||||
order by POSITION;
|
||||
rec_constraint_cols cur_constraint_cols%ROWTYPE;
|
||||
|
||||
CURSOR cur_tab_cols(p_owner DBA_TAB_COLUMNS.OWNER%TYPE
|
||||
, p_table_name DBA_TAB_COLUMNS.TABLE_NAME%TYPE)
|
||||
is
|
||||
SELECT column_name
|
||||
FROM DBA_TAB_COLUMNS
|
||||
WHERE TABLE_NAME = p_table_name
|
||||
AND OWNER = p_owner
|
||||
order by COLUMN_ID;
|
||||
rec_tab_cols cur_tab_cols%ROWTYPE;
|
||||
|
||||
CURSOR cur_is_table_partitioned(p_owner DBA_TAB_COLUMNS.OWNER%TYPE
|
||||
, p_table_name DBA_TAB_COLUMNS.TABLE_NAME%TYPE)
|
||||
is
|
||||
SELECT partitioned
|
||||
FROM dba_tables
|
||||
WHERE TABLE_NAME = p_table_name
|
||||
AND OWNER = p_owner;
|
||||
rec_is_table_partitioned cur_is_table_partitioned%ROWTYPE;
|
||||
|
||||
CURSOR cur_update_cols(p_owner DBA_TAB_COLUMNS.OWNER%TYPE
|
||||
, p_table_name DBA_TAB_COLUMNS.TABLE_NAME%TYPE)
|
||||
is
|
||||
SELECT column_name
|
||||
FROM DBA_TAB_COLUMNS t
|
||||
WHERE TABLE_NAME = p_table_name
|
||||
AND OWNER = p_owner
|
||||
AND t.column_name NOT IN ( SELECT COLUMN_NAME FROM DBA_CONSTRAINTS C, DBA_CONS_COLUMNS CC
|
||||
WHERE C.TABLE_NAME = t.table_name
|
||||
AND C.CONSTRAINT_TYPE in ( 'P' ,'U')
|
||||
AND C.OWNER = t.OWNER
|
||||
AND C.OWNER = CC.OWNER
|
||||
AND C.CONSTRAINT_NAME = CC.CONSTRAINT_NAME
|
||||
AND C.TABLE_NAME = CC.TABLE_NAME)
|
||||
order by COLUMN_ID;
|
||||
rec_update_cols cur_update_cols%ROWTYPE;
|
||||
|
||||
CURSOR cur_check_snapid_exists(p_owner DBA_TAB_COLUMNS.OWNER%TYPE, p_table_name DBA_TAB_COLUMNS.TABLE_NAME%TYPE)
|
||||
is
|
||||
SELECT 'Y'
|
||||
FROM DBA_CONSTRAINTS a
|
||||
WHERE OWNER = p_owner
|
||||
AND TABLE_NAME = p_table_name
|
||||
AND CONSTRAINT_TYPE = 'R'
|
||||
AND R_CONSTRAINT_NAME = 'STATS$SNAPSHOT_PK';
|
||||
|
||||
BEGIN
|
||||
|
||||
DBMS_OUTPUT.PUT_LINE('###########################################');
|
||||
DBMS_OUTPUT.PUT_LINE('Job Started at ' || to_char(sysdate,'DD-MON-YYYY hh24:MI:SS') );
|
||||
|
||||
FOR i in (SELECT database
|
||||
, active
|
||||
, version
|
||||
, environment
|
||||
, schema_name
|
||||
from perfstat_control.STATSPACK_MERGE_CONTROL
|
||||
where active = 'Y'
|
||||
AND version = v_db_version
|
||||
AND environment = v_env_type
|
||||
AND database = NVL(v_instance,database)
|
||||
ORDER BY database)
|
||||
LOOP
|
||||
v_db_link := i.database;
|
||||
v_perfstat_schema_owner := i.schema_name;
|
||||
|
||||
DBMS_OUTPUT.PUT_LINE('------------------------------------------------');
|
||||
DBMS_OUTPUT.PUT_LINE(v_db_link);
|
||||
DBMS_OUTPUT.PUT_LINE(v_perfstat_schema_owner);
|
||||
|
||||
-- New data might get inserted while we are merging all the tables of statspack
|
||||
-- corresponding snap_id would not exists for data inserted after merge of stats$snapshot
|
||||
-- So, we need to use flashback query "as os SCN 1234".
|
||||
v_scn := 0;
|
||||
|
||||
BEGIN
|
||||
|
||||
EXECUTE IMMEDIATE 'SELECT sys.dbms_flashback.get_system_change_number() FROM dual@' || v_db_link INTO v_scn;
|
||||
--dbms_output.put_line('SELECT dbid from FROM v$database@' || v_db_link);
|
||||
EXECUTE IMMEDIATE 'select dbid from stats$database_instance@' || v_db_link || ' where startup_time = (select max(startup_time) from stats$database_instance@' || v_db_link || ')' INTO v_dbid;
|
||||
--dbms_output.put_line('SELECT dbid from FROM v$database@' || v_db_link);
|
||||
|
||||
FOR tbl in (
|
||||
select 'STATS$DATABASE_INSTANCE' table_name from dual
|
||||
UNION ALL
|
||||
select 'STATS$LEVEL_DESCRIPTION' from dual
|
||||
UNION ALL
|
||||
select 'STATS$STATSPACK_PARAMETER' from dual
|
||||
UNION ALL
|
||||
select 'STATS$SNAPSHOT' from dual
|
||||
UNION ALL
|
||||
select *
|
||||
from (SELECT table_name
|
||||
FROM DBA_TABLES
|
||||
WHERE OWNER = v_perfstat_schema_owner
|
||||
and table_name not in ('STATS$DATABASE_INSTANCE'
|
||||
,'STATS$LEVEL_DESCRIPTION'
|
||||
,'STATS$STATSPACK_PARAMETER'
|
||||
,'STATS$SNAPSHOT'
|
||||
,'STATS$IDLE_EVENT')
|
||||
order by 1
|
||||
)
|
||||
)
|
||||
loop
|
||||
|
||||
/* Sample Merge statement
|
||||
--
|
||||
-- Limit the historical data to be sampled from source database to x days old.
|
||||
-- Old data in central repository is not deleted.
|
||||
--
|
||||
-- MERGE
|
||||
-- INTO table_l l
|
||||
-- USING (select a.* from stats$sql_summary@FIRE02PD a as of SCN 1234, stats$snapshot@FIRE02PD b as of SCN 1234
|
||||
-- where a.dbid = b.dbid and a.instance_number = b.instance_number and a.snap_id = b.snap_id
|
||||
-- and and b.snap_time > sysdate - 3 ) r
|
||||
-- ON( l.primary_key_col1 = r.primary_key_col1
|
||||
-- AND l.primary_key_col2 = r.primary_key_col2 -- For nullable columns use NVL
|
||||
-- )
|
||||
-- WHEN matched THEN
|
||||
-- UPDATE
|
||||
-- SET l.col1 = r.col2,
|
||||
-- l.col2 = r.col2
|
||||
-- WHERE l.col1 != r.col1
|
||||
-- OR l.col2 != r.col2
|
||||
-- OR l.col3 != r.col3
|
||||
-- WHEN NOT matched THEN
|
||||
-- INSERT(col1, col2)
|
||||
-- VALUES(r.col1, r.col2)
|
||||
-- ;
|
||||
|
||||
|
||||
*/
|
||||
|
||||
v_snap_id_exists := 'N';
|
||||
OPEN cur_check_snapid_exists(v_perfstat_schema_owner, tbl.table_name);
|
||||
FETCH cur_check_snapid_exists INTO v_snap_id_exists;
|
||||
CLOSE cur_check_snapid_exists;
|
||||
|
||||
OPEN cur_is_table_partitioned(v_perfstat_schema_owner, tbl.table_name);
|
||||
FETCH cur_is_table_partitioned INTO rec_is_table_partitioned;
|
||||
CLOSE cur_is_table_partitioned;
|
||||
|
||||
sql_text := 'merge /*+ index(L) index(R) */ into ' ;
|
||||
sql_text := sql_text || v_perfstat_schema_owner || '.' || tbl.table_name ;
|
||||
|
||||
IF v_snap_id_exists = 'Y' AND rec_is_table_partitioned.partitioned = 'YES' THEN
|
||||
sql_text := sql_text || ' PARTITION (P' || v_dbid || ') ';
|
||||
END IF;
|
||||
|
||||
sql_text := sql_text || ' l using ( SELECT a.* from ' || tbl.table_name || '@' || v_db_link || ' as of SCN ' || v_scn || ' a ';
|
||||
|
||||
IF v_snap_id_exists = 'Y' THEN
|
||||
sql_text := sql_text || ' , stats$snapshot@' || v_db_link || ' as of SCN ' || v_scn || ' b ';
|
||||
sql_text := sql_text || ' where a.dbid = b.dbid ';
|
||||
sql_text := sql_text || ' and a.instance_number = b.instance_number ';
|
||||
sql_text := sql_text || ' and a.snap_id = b.snap_id ';
|
||||
sql_text := sql_text || ' and b.snap_time > sysdate - ' || v_days ;
|
||||
END IF;
|
||||
|
||||
sql_text := sql_text || ' ) r ON ( ';
|
||||
|
||||
OPEN cur_constraint_cols(v_perfstat_schema_owner, tbl.table_name);
|
||||
LOOP
|
||||
FETCH cur_constraint_cols INTO rec_constraint_cols;
|
||||
EXIT WHEN cur_constraint_cols%NOTFOUND;
|
||||
IF rec_constraint_cols.nullable = 'Y' THEN
|
||||
sql_text := sql_text || 'nvl(l.' || rec_constraint_cols.COLUMN_NAME || ',''0'') = nvl(r.' || rec_constraint_cols.column_name||',''0'') AND ';
|
||||
ELSE
|
||||
sql_text := sql_text || 'l.' || rec_constraint_cols.COLUMN_NAME || ' = r.' || rec_constraint_cols.column_name||' AND ';
|
||||
END IF;
|
||||
END LOOP;
|
||||
CLOSE cur_constraint_cols;
|
||||
sql_text := SUBSTR(sql_text,1, LENGTH(sql_text) -4);
|
||||
sql_text := sql_text || ' ) ';
|
||||
|
||||
OPEN cur_update_cols(v_perfstat_schema_owner, tbl.table_name);
|
||||
LOOP
|
||||
FETCH cur_update_cols INTO rec_update_cols;
|
||||
EXIT WHEN cur_update_cols%NOTFOUND;
|
||||
END LOOP;
|
||||
v_update_cols_count := cur_update_cols%ROWCOUNT;
|
||||
CLOSE cur_update_cols;
|
||||
|
||||
IF v_update_cols_count > 0 THEN
|
||||
sql_text := sql_text || ' WHEN MATCHED THEN UPDATE SET ';
|
||||
OPEN cur_update_cols(v_perfstat_schema_owner, tbl.table_name);
|
||||
LOOP
|
||||
FETCH cur_update_cols INTO rec_update_cols;
|
||||
EXIT WHEN cur_update_cols%NOTFOUND;
|
||||
sql_text := sql_text || 'l.' || rec_update_cols.COLUMN_NAME || ' = r.' || rec_update_cols.column_name||',';
|
||||
END LOOP;
|
||||
CLOSE cur_update_cols;
|
||||
sql_text := SUBSTR(sql_text,1, LENGTH(sql_text) - 1);
|
||||
|
||||
sql_text := sql_text || ' WHERE ' ;
|
||||
OPEN cur_update_cols(v_perfstat_schema_owner, tbl.table_name);
|
||||
LOOP
|
||||
FETCH cur_update_cols INTO rec_update_cols;
|
||||
EXIT WHEN cur_update_cols%NOTFOUND;
|
||||
sql_text := sql_text || 'l.' || rec_update_cols.COLUMN_NAME || ' != r.' || rec_update_cols.column_name||' OR ';
|
||||
END LOOP;
|
||||
CLOSE cur_update_cols;
|
||||
sql_text := SUBSTR(sql_text,1, LENGTH(sql_text) -3);
|
||||
|
||||
END IF;
|
||||
|
||||
sql_text := sql_text || ' WHEN NOT MATCHED THEN INSERT (' ;
|
||||
|
||||
OPEN cur_tab_cols(v_perfstat_schema_owner, tbl.table_name);
|
||||
LOOP
|
||||
FETCH cur_tab_cols INTO rec_tab_cols;
|
||||
EXIT WHEN cur_tab_cols%NOTFOUND;
|
||||
sql_text := sql_text || rec_tab_cols.COLUMN_NAME || ',';
|
||||
END LOOP;
|
||||
CLOSE cur_tab_cols;
|
||||
sql_text := SUBSTR(sql_text,1, LENGTH(sql_text) -1);
|
||||
|
||||
sql_text := sql_text || ' ) VALUES (';
|
||||
|
||||
OPEN cur_tab_cols(v_perfstat_schema_owner, tbl.table_name);
|
||||
LOOP
|
||||
FETCH cur_tab_cols INTO rec_tab_cols;
|
||||
EXIT WHEN cur_tab_cols%NOTFOUND;
|
||||
sql_text := sql_text || 'r.' || rec_tab_cols.COLUMN_NAME || ',';
|
||||
END LOOP;
|
||||
CLOSE cur_tab_cols;
|
||||
sql_text := SUBSTR(sql_text,1, LENGTH(sql_text) -1);
|
||||
sql_text := sql_text || ' ) ' ;
|
||||
DBMS_OUTPUT.PUT_LINE (tbl.table_name);
|
||||
IF tbl.table_name = 'STATS$SGASTAT' THEN
|
||||
null;
|
||||
DBMS_OUTPUT.PUT_LINE (SQL_TEXT);
|
||||
EXIT;
|
||||
END IF;
|
||||
--DBMS_OUTPUT.PUT_LINE (SQL_TEXT);
|
||||
--execute immediate sql_text ;
|
||||
--commit;
|
||||
end loop;
|
||||
|
||||
--EXECUTE immediate 'alter session close database link ' || v_db_link ;
|
||||
|
||||
EXCEPTION
|
||||
WHEN others THEN
|
||||
DBMS_OUTPUT.PUT_LINE(sqlerrm);
|
||||
IF v_sqlcode = 0 THEN
|
||||
v_sqlcode := SQLCODE;
|
||||
END IF;
|
||||
FOR i in (select db_link from v$dblink)
|
||||
LOOP
|
||||
commit;
|
||||
EXECUTE immediate 'alter session close database link ' || i.db_link ;
|
||||
END LOOP;
|
||||
END;
|
||||
|
||||
END LOOP;
|
||||
DBMS_OUTPUT.PUT_LINE('###########################################');
|
||||
DBMS_OUTPUT.PUT_LINE('Job Finished at ' || to_char(sysdate,'DD-MON-YYYY hh24:MI:SS') );
|
||||
|
||||
IF v_sqlcode <> 0 THEN
|
||||
raise_application_error(-20001,'There were some errors in statspack consolidation');
|
||||
END IF;
|
||||
END;
|
||||
/
|
||||
|
||||
Reference in New Issue
Block a user