Rem drv:
Rem
Rem $Header: emcore/source/oracle/sysman/emdrep/sql/core/latest/admin/admin_maintenance_pkgbody.sql /st_emcore_10.2.0.4.4db11.2.0.3/1 2011/06/30 10:11:47 edemembe Exp $
Rem
Rem admin_maintenance_pkgbody.sql
Rem
Rem Copyright (c) 2002, 2011, Oracle and/or its affiliates.
Rem All rights reserved.
Rem
Rem NAME
Rem admin_maintenance_pkgbody.sql -
Rem
Rem DESCRIPTION
rem
rem This maintanence package handles statistics maintenance for the EMD Schema.
rem This package contains the following procedures:
rem
rem update_stale_stats
rem
rem This procedure collects stale statistics for the specified schema.
rem It collects it every Saturday at 2am by default.
rem These parameters can be configured.
rem
rem delete_all_stats
rem
rem This procedure deletes all stats for the specified schema. It will
rem delete all schema statistics once on Saturday at 1am by default. These
rem parameters can be configured.
rem
rem analyze_emd_schema
rem
rem This procedure is called by update_stale_stats. It gathers
rem statistics for all objects in the schema. It runs only once.
rem It calls GATHER_STALE for objects that have monitoring turned on
rem and already have statistics or just analyzes objects that do not
rem have statistics.
rem
rem pin_plsql
rem
rem This procedure is called by update_stale_stats. This procedure will
rem pin all the critical EMD PL/SQL packages in memory. This is critical
rem to ensure that we do not fragment the shared pool.
rem
rem INTENDED USAGE:
rem
rem The first time you use this package run delete_all_stats before
rem scheduling update_stale_stats. This will ensure all statistics are
rem generated fresh. This package assumes monitoring is enabled on
rem all objects in the schema.
rem
rem Once update_stale_stats is run it will continue schedule itself
rem analyze_emd_schema to run once a week on (i.e.) Saturday at 2:00am
rem (this is configurable, see above).
rem
rem COMMENTS:
rem
rem To see scheduled/completed jobs use the dba_jobs (or user_jobs) table.
rem To see running jobs use dba_jobs_running or user_jobs_running.
rem To cancel a job use the above tables to find the job number ( job ) and
rem then call: dbms_jobs.remove_job(job)
rem
rem Due to a bug in 8.1.7 the analyze_emd_schema function
rem calls analyze directly for any tables that do not have statistics.
rem
Rem NOTES
Rem
Rem
Rem MODIFIED (MM/DD/YY)
Rem edemembe 06/27/11 - Backport 12401461
Rem edemembe 02/24/10 - Bug 8912823
Rem jsadras 12/29/08 - Backport jsadras_bug-7585160 from
Rem st_emcore_10.2.0.1.0
Rem jsadras 10/21/08 - Backport jsadras_bug-7479372 from
Rem st_emcore_10.2.0.1.0
Rem edemembe 10/07/08 - Backport edemembe_bug-6630325 from main
Rem jsadras 09/23/08 - Bug:7426052, add dbms_assert calls
Rem lsatyapr 07/10/08 - Bug7214155 Avoid jobtype upg in non-central mode
Rem edemembe 06/03/08 - Backport edemembe_bug-7010689 from main
Rem edemembe 07/11/07 - Bug 6157164 removed recompile_invalid_objects
Rem edemembe 07/17/07 - Backport edemembe_bug-6157164 from main
Rem jsadras 04/20/07 - Bug:5967369, resolve dbms_shared_pool
Rem jsadras 04/20/07 - Bug:5967369, resolve dbms_shared_pool
Rem jsadras 06/07/07 - Backport jsadras_bug-5967369 from main
Rem minfan 05/22/07 - bug 5894442
Rem minfan 05/22/07 - bug 5894442
Rem rrawat 05/21/07 - Backport rrawat_bug-5502664 from main
Rem zmi 05/11/07 - Back out change for bug 5890927.
Rem jsadras 05/03/07 - Backport jsadras_bug-5357916 from main
Rem dytong 05/02/07 - Bugfix 5890927
Rem neearora 03/30/07 - changed schedule duraion of check_for_severites
Rem dbms_job
Rem neearora 07/25/06 - Backport neearora_bug-4967160 from main
Rem rrawat 09/06/06 - Bug-5502664
Rem jsadras 08/10/06 - Moved drop_partition/recompile invalid
Rem to emd_maint_util. Bug:5357916
Rem pmodi 07/11/06 - Bug4465878 - call drop partition from
Rem analyze_emd_schema job
Rem pmodi 07/20/06 - Backport pmodi_bug-4465878 from main
Rem pmodi 07/07/06 - Backport pmodi_bug-3900473 from main
Rem jsadras 12/11/05 - Backport jsadras_bug-4746117 from main
Rem neearora 06/30/06 - bug 4967160. added maintenance job to clenup the
Rem mgmt_targets_delete table
Rem pmodi 04/20/06 - Bug:3900473 Use function to get default
Rem retention window for truncation
Rem jsadras 11/22/05 - Bug:4746117, skip of partition creation
Rem pmodi 09/09/05 - Add new job
Rem pmodi 08/30/05 - Bug:4581761 Handle ORA-23421 in remove_dbms_job
Rem jsadras 08/22/05 - upper in compress index
Rem pmodi 08/17/05 - Bug:4547155 - Diff days to analyze data in raw,
Rem 1hour and 1day table
Rem jsadras 08/03/05 - Bug:4527081 temporarily remove compression for
Rem IOT due to RDBMS bug
Rem jriel 07/20/05 - add RCA job to remove proc
Rem scgrover 07/07/05 - add extended sql trace
Rem gsbhatia 07/01/05 - New repmgr header impl
Rem pmodi 05/30/05 - Bug:4392834 - Adding weekly job to
Rem analyze_emd_schema
Rem niramach 05/09/05 - Add dbms job for clear expired suppressions-bug
Rem fix 4229157.
Rem jriel 05/17/05 - add RCA purge job
Rem jsadras 05/16/05 - Security fixes
Rem jsadras 04/26/05 - change to call em_task.get_worker_count
Rem jberesni 04/21/05 - add mgmt_bsln calls for GC
Rem jsadras 03/28/05 - Bug:4148613, added security checks
Rem gsbhatia 03/15/05 - bug 4178702
Rem edemembe 03/09/05 - bug-4211429
Rem jsadras 03/02/05 - Bug:4162225
Rem edemembe 01/21/05 - Bug 3556656
Rem scgrover 01/10/05 - add index compress sql
Rem jsadras 12/27/04 - Bug3315409
Rem jsadras 12/27/04 - bug3883828
Rem snakai 11/22/04 - update beacon avail job
Rem jsadras 09/01/04 - repocollect
Rem ramalhot 08/30/04 - cutover to new assoc tables
Rem jsadras 08/25/04 - bug3356702
Rem dcawley 07/21/04 - Remove notification job
Rem dcawley 07/12/04 - Add job for checking state changes
Rem dcawley 07/07/04 - Increase user name size
Rem edemembe 06/24/04 - Adding pin PLSQL to database startup trigger
Rem edemembe 04/13/04 - Bug 3227319: Collect histograms for non-idx cols
Rem edemembe 04/13/04 - Moving partition truncation
Rem rpinnama 04/16/04 - Analyze the schema that has MGMT_TARGETS table
Rem rpinnama 12/12/03 - Fix bug 3296613: Record the outofbox configured
Rem rzazueta 10/30/03 - Use mgmt_global.elapsed_time_msec function
Rem rzazueta 10/29/03 - Log elapsed time for execute_em_dbms_job_procs
Rem gan 10/17/03 - Fix dbms job submission
Rem lgloyd 09/18/03 - perf: bug 3092790
Rem rpinnama 09/07/03 - Submit purge policies job
Rem edemembe 08/25/03 - Partition truncation added
Rem glavash 08/07/03 - improve partition check
Rem rpinnama 07/25/03 - Merge all dbms jobs to one for standalone repository
Rem rpinnama 07/14/03 - Start CENTRAL jobs only in central mode
Rem yfeng 07/10/03 - Remove the job for bad sql evaluation
Rem dcawley 07/10/03 - Remove notification delivery job
Rem rpinnama 07/02/03 - Remove hardcoded SYSMAN
Rem rpinnama 07/01/03 - APIs to submit and remove EM jobs
Rem edemembe 07/01/03 - Adding partition support
Rem rpinnama 03/11/03 - Implement move_tablespace procedure
Rem rpinnama 11/19/02 - Add move procedure
Rem rpinnama 03/17/03 - Provide get/setVersion APIs
Rem sgrover 02/04/03 - ignore ORA-25191 errors
Rem sgrover 01/20/03 - fix analyze
Rem sgrover 01/14/03 - remove perf logging
Rem sgrover 01/13/03 - add log of rebuild
Rem sgrover 01/13/03 - use day of year
Rem sgrover 01/10/03 - customize index rebuilds
Rem edemembe 11/04/02 - Fixing perf logging
Rem rpinnama 10/14/02 - Modify the CORE SDK
Rem rpinnama 10/08/02 - Grant privileges to viewas
Rem rpinnama 10/07/02 - Add grant core sdk procedure
Rem edemembe 10/04/02 - Moving index rebuilds
Rem edemembe 09/25/02 - Changing analysis param
Rem edemembe 08/23/02 - Adding IOTs
Rem edemembe 08/15/02 - Adding performance logging
Rem edemembe 08/14/02 - Changing the index rebuild frequency to 1 day
Rem edemembe 07/10/02 - Adding index rebuilds
Rem rpinnama 05/15/02 - rpinnama_reorg_rep_scripts
Rem rpinnama 05/15/02 - Created
Rem
create or replace package body emd_maintenance as
-- suffix to be added to table name to get the
-- parameter name for last truncated partition
g_trunc_suffix CONSTANT VARCHAR2(11) := '_LAST_TRUNC' ;
--
-- forward declaration
--
PROCEDURE cleanup_deleted_targets;
FUNCTION REPOSITORY_DB_V91 RETURN BOOLEAN ;
FUNCTION REPOSITORY_DB_V10 RETURN BOOLEAN ;
FUNCTION REPOSITORY_DB_V102 RETURN BOOLEAN ;
--
-- PURPOSE
-- Procedure(s) to enable/disable/verify detailed logging
--
PROCEDURE enable_detailed_logging IS
BEGIN
BEGIN
INSERT INTO MGMT_PARAMETERS
(parameter_name, parameter_value, parameter_comment,
internal_flag)
VALUES
(DETAILED_MAINT_LOGGING, 'TRUE', DETAILED_MAINT_LOGGING_CMT, 1);
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
UPDATE MGMT_PARAMETERS
SET parameter_value = 'TRUE'
WHERE parameter_name = DETAILED_MAINT_LOGGING;
END;
END enable_detailed_logging;
PROCEDURE disable_detailed_logging IS
BEGIN
BEGIN
INSERT INTO MGMT_PARAMETERS
(parameter_name, parameter_value, parameter_comment,
internal_flag)
VALUES
(DETAILED_MAINT_LOGGING, 'FALSE', DETAILED_MAINT_LOGGING_CMT, 1);
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
UPDATE MGMT_PARAMETERS
SET parameter_value = 'FALSE'
WHERE parameter_name = DETAILED_MAINT_LOGGING;
END;
END disable_detailed_logging;
FUNCTION is_detailed_logging_enabled
RETURN INTEGER IS
l_retVal INTEGER := 0;
l_cnt INTEGER := 0;
BEGIN
SELECT COUNT(*) into l_cnt
FROM MGMT_PARAMETERS
WHERE parameter_name=DETAILED_MAINT_LOGGING
AND upper(parameter_value)='TRUE';
IF (l_cnt > 0) THEN
-- detailed_maint_logging property is TRUE
l_retVal := 1;
END IF;
RETURN l_retVal;
END is_detailed_logging_enabled;
--
-- This is to keep track of already truncated partitions
-- so we do not have to truncate again bug:3356702
--
PROCEDURE upd_trunc_partition(table_name IN VARCHAR2,
partition_name IN VARCHAR2
)
IS
BEGIN
UPDATE mgmt_parameters
SET parameter_value = partition_name
WHERE parameter_name = table_name||g_trunc_suffix ;
IF SQL%NOTFOUND
THEN
INSERT INTO MGMT_PARAMETERS
(parameter_name, parameter_value, parameter_comment,
internal_flag)
VALUES
(table_name||g_trunc_suffix,partition_name,
'Last partition truncated', 1) ;
END IF ;
END upd_trunc_partition;
-- PROCEDURE: update_stale_stat
--
-- PARAMETERS:
--
-- emd_schema VARCHAR2
--
-- Name of the schema containing the emd objects you want current
-- statistics on i.e. SCOTT
--
-- start_day VARCHAR2 DEFAULT 'SATURDAY'
--
-- The day of the week you want statistics estimated on.
-- The default is to have stats generated on SATURDAY.
--
-- start_hour DEFAULT 2
--
-- The hour you want statistics estimated on, in military time
-- By default this is 2am. If you want it at 1pm you would pass 13.
--
-- start_minutes DEFAULT 0
--
-- Number of minutes after the hour you want statistics estimated on.
-- The default is to estimate on the hour ( 0 minutes ).
--
-- frequency_in_days DEFAULT 1
--
-- How often you want to estimate statistics.
-- The default case is once every day.
--
-- EXAMPLE:
--
-- If this is Monday, this example would start a job that updates stale
-- statistics, in schema emd, everyday, at 2:50pm, including today.
--
-- > exec emd_maintenance.update_stale_stats('emd','MONDAY',14,50,1);
--
procedure update_stale_stats(emd_schema VARCHAR2,
start_day VARCHAR2 DEFAULT 'SATURDAY',
start_hour NUMBER DEFAULT 0,
start_minutes NUMBER DEFAULT 0,
frequency_in_days NUMBER DEFAULT 1) IS
jobnum number;
BEGIN
dbms_job.submit ( jobnum,
'emd_maintenance.analyze_emd_schema(''' ||
em_check.schema_name(emd_schema) || ''');',
trunc(next_day((sysdate-1),start_day)) +
start_hour/24+start_minutes/60/24,
'trunc(sysdate + '''|| frequency_in_days||''') + ''' ||
start_hour || ''' /24 + ''' || start_minutes ||
''' /60/24');
commit;
END update_stale_stats;
-- PROCEDURE: Add/truncate partitions
-- procedure to add/truncate partitions called from analyze_emd_schema
-- PARAMETERS: None
PROCEDURE add_truncate_partitions
IS
l_retries NUMBER := 0 ;
l_max_retries NUMBER := 2 ;
l_next_start_loc NUMBER := 1 ;
l_success BOOLEAN := FALSE ;
l_error_message VARCHAR2(1000) ;
BEGIN
-- l_max_retries=2 means the loop at most will be
-- executed thrice ( the first time and 2 retries)
WHILE l_retries <= l_max_retries
LOOP
BEGIN
l_retries := l_retries + 1 ;
IF l_next_start_loc = 1
THEN
ADD_PARTITIONS(EMD_LOADER.p_metrics_raw_table,
EMD_LOADER.p_prepopulate_days_raw);
l_next_start_loc := 2 ;
END IF ;
IF l_next_start_loc = 2
THEN
TRUNCATE_PARTITIONS(EMD_LOADER.p_metrics_raw_table,
EMD_MAINT_UTIL.get_raw_retention_window);
l_next_start_loc := 3 ;
END IF ;
IF l_next_start_loc =3
THEN
ADD_PARTITIONS(EMD_LOADER.p_metrics_1hour_table,
EMD_LOADER.p_prepopulate_days_1hour, TRUE);
l_next_start_loc := 4 ;
END IF ;
IF l_next_start_loc = 4
THEN
TRUNCATE_PARTITIONS(EMD_LOADER.p_metrics_1hour_table,
EMD_MAINT_UTIL.get_1hour_retention_window);
l_next_start_loc := 5 ;
END IF ;
IF l_next_start_loc = 5
THEN
ADD_PARTITIONS(EMD_LOADER.p_metrics_1day_table,
EMD_LOADER.p_prepopulate_days_1day, TRUE);
l_next_start_loc := 6 ;
END IF ;
IF l_next_start_loc = 6
THEN
TRUNCATE_PARTITIONS(EMD_LOADER.p_metrics_1day_table,
EMD_MAINT_UTIL.get_1day_retention_window);
l_next_start_loc := 7 ;
END IF ;
l_success := TRUE ;
-- Exit the loop on successful execution till here
EXIT ;
EXCEPTION
-- release locks and retry
WHEN OTHERS THEN ROLLBACK ;
l_error_message := substr(sqlerrm,1,1000) ;
END ;
END LOOP ;
IF NOT l_success
THEN
MGMT_LOG.LOG_ERROR('ANALYZE', null,
'Error during maintenance: ' || l_error_message) ;
END IF ;
END add_truncate_partitions ;
-- PROCEDURE: analyze_emd_schema
--
-- PARAMETERS:
--
-- emd_schema VARCHAR2
--
-- Name of the schema containing the emd objects that you want
-- to delete statistics on ( i.e. 'SCOTT' )
--
-- EXAMPLE:
--
-- This is called by update_stale_stats. If called directly this function
-- will immediatly update the stale_stats of all objects and generate
-- stats for any objects that don't have statistics.
-- NOTE: objects will only be evaluated as having stale stats if
-- monitoring is turned on for the object.
--
-- > execute emd_maintenance.analyze_emd_schema('emd');
--
PROCEDURE analyze_emd_schema(emd_schema VARCHAR2) IS
OLIST DBMS_STATS.OBJECTTAB;
start_timestamp DATE DEFAULT SYSDATE;
object_count NUMBER := 0;
l_emd_schema VARCHAR2(30) := EM_CHECK.schema_name(emd_schema);
l_table_name USER_TABLES.table_name%TYPE ;
CURSOR partitioned_tables IS
SELECT table_name, num_rows
FROM USER_TABLES
WHERE partitioned = 'YES' AND
(IOT_TYPE IS NULL OR IOT_TYPE <> 'IOT_OVERFLOW');
can_not_access_overflow_table EXCEPTION;
PRAGMA EXCEPTION_INIT(can_not_access_overflow_table, -25191);
BEGIN
BEGIN
cleanup_deleted_targets;
END;
MGMT_SQLTRACE.EXTENDED_SQL_TRACE(EST_ANALYZE_NAME);
-- Rebuild the high update indexes.
rebuild_indexes;
DBMS_APPLICATION_INFO.SET_MODULE(
module_name => 'Oracle Enterprise Manager.analyze EM schema',
action_name => 'start');
-- The following code block is obsolete in 10g or higher repository
-- databases.
IF (REPOSITORY_DB_V9) THEN
-- Get list of objects with stale stats
DBMS_STATS.GATHER_SCHEMA_STATS(l_emd_schema, DBMS_STATS.AUTO_SAMPLE_SIZE,
FALSE, 'FOR ALL COLUMNS SIZE AUTO',NULL,'DEFAULT',FALSE,NULL,NULL,
'LIST STALE',OLIST);
-- Loop through the list of objects with stale stats. Analyze the
-- objects that are not partitioned. Obsolete in 10g database.
IF (OLIST.COUNT > 0) THEN
FOR TABLE_ROW IN OLIST.FIRST..OLIST.LAST LOOP
BEGIN
IF OLIST(TABLE_ROW).OBJTYPE = 'TABLE' AND
OLIST(TABLE_ROW).PARTNAME IS NULL AND
OLIST(TABLE_ROW).OBJNAME NOT IN ('MGMT_METRICS_RAW',
'MGMT_METRICS_1HOUR',
'MGMT_METRICS_1DAY') THEN
dbms_stats.gather_table_stats(l_emd_schema, OLIST(TABLE_ROW).OBJNAME,
NULL, DBMS_STATS.AUTO_SAMPLE_SIZE, FALSE,
'FOR ALL COLUMNS SIZE AUTO',NULL,'GLOBAL',TRUE,NULL,NULL,NULL);
END IF;
EXCEPTION
WHEN can_not_access_overflow_table THEN
NULL;
WHEN OTHERS THEN
MGMT_LOG.LOG_ERROR('ANALYZE', null,
'Error analyzing object: ' || OLIST(TABLE_ROW).OBJNAME ||
' Error: ' || SUBSTR(SQLERRM, 1, 1000));
END;
END LOOP;
END IF; -- OLIST.COUNT > 0
-- For performance logging
object_count := OLIST.COUNT;
-- Clear the object list for reuse.
OLIST.DELETE;
-- Get list of objects with empty stats
DBMS_STATS.GATHER_SCHEMA_STATS(l_emd_schema, DBMS_STATS.AUTO_SAMPLE_SIZE,
FALSE, 'FOR ALL COLUMNS SIZE AUTO',NULL,'DEFAULT',FALSE,NULL,NULL,
'LIST EMPTY',OLIST);
-- Loop through the list of objects with empty stats. Analyze the
-- objects that are not partitioned. Obsolete in 10g database.
IF (OLIST.COUNT > 0) THEN
FOR TABLE_ROW IN OLIST.FIRST..OLIST.LAST LOOP
BEGIN
IF OLIST(TABLE_ROW).OBJTYPE = 'TABLE' AND
OLIST(TABLE_ROW).PARTNAME IS NULL AND
OLIST(TABLE_ROW).OBJNAME NOT IN ('MGMT_METRICS_RAW',
'MGMT_METRICS_1HOUR',
'MGMT_METRICS_1DAY') THEN
dbms_stats.gather_table_stats(l_emd_schema, OLIST(TABLE_ROW).OBJNAME,
NULL, DBMS_STATS.AUTO_SAMPLE_SIZE, FALSE,
'FOR ALL COLUMNS SIZE AUTO',NULL,'GLOBAL',TRUE,NULL,NULL,NULL);
END IF;
EXCEPTION
WHEN can_not_access_overflow_table THEN
NULL;
WHEN OTHERS THEN
MGMT_LOG.LOG_ERROR('ANALYZE', null,
'Error analyzing object: ' || OLIST(TABLE_ROW).OBJNAME ||
' Error: ' || SUBSTR(SQLERRM, 1, 1000));
END;
END LOOP;
END IF; -- OLIST.COUNT > 0
-- For performance logging
object_count := object_count + OLIST.COUNT;
-- Clear the object list for reuse.
OLIST.DELETE;
END IF; -- REPOSITORY_DB_V9
--
-- Only execute the next block if the repository database version is
-- 9.2 or higher. Partitioned table analysis is expected to be handled
-- manually in repositories less than 9.2. Still required in 10g
-- database due to inefficient analysis of large partitioned IOTs
-- by default system analysis job.
--
IF NOT (REPOSITORY_DB_V91) THEN
-- Loop through the list of partitioned tables and analyze them with the
-- smallest possible sample size. We only want to analyze them more than
-- once a week if the table is less that a set number of rows in size.
-- We will analyze the partitioned tables once a week otherwise.
FOR part_rec in partitioned_tables LOOP
BEGIN
l_table_name := part_rec.table_name;
-- All table other then MGMT_METRICS_RAW and MGMT_METRICS_1HOUR to be analysed on 7th day of week
-- MGMT_METRICS_1HOUR to be analysed on 6th day of week
-- MGMT_METRICS_RAW to be analysed on 5th day of week
IF (part_rec.num_rows < 1000000 OR part_rec.num_rows is null) OR
(to_char(SYSDATE,'d') = '7' AND part_rec.table_name NOT IN ('MGMT_METRICS_RAW', 'MGMT_METRICS_1HOUR')) OR
(to_char(SYSDATE,'d') = '6' AND part_rec.table_name = 'MGMT_METRICS_1HOUR') OR
(to_char(SYSDATE,'d') = '5' AND part_rec.table_name = 'MGMT_METRICS_RAW') THEN
-- Only run the following procedure on v10 DBs or higher.
IF NOT (REPOSITORY_DB_V9) THEN
execute immediate
'call dbms_stats.unlock_table_stats(' ||
em_check.enquote_name(l_emd_schema) || ', ' ||
em_check.enquote_name(l_table_name) || ')';
END IF;
dbms_stats.gather_table_stats(l_emd_schema, l_table_name,
NULL, .000001 , FALSE, 'FOR ALL INDEXED COLUMNS',NULL,
'GLOBAL',TRUE,NULL,NULL,NULL);
-- Only run the following procedure on v10 DBs or higher.
IF NOT (REPOSITORY_DB_V9) THEN
execute immediate
'call dbms_stats.lock_table_stats(' ||
em_check.enquote_name(l_emd_schema) || ', ' ||
em_check.enquote_name(l_table_name) || ')';
END IF;
-- For performance logging
object_count := object_count+1;
END IF;
EXCEPTION
WHEN can_not_access_overflow_table THEN
BEGIN
EXECUTE IMMEDIATE
'call dbms_stats.lock_table_stats(' ||
em_check.enquote_name(l_emd_schema) || ', ' ||
em_check.enquote_name(l_table_name) || ')';
EXCEPTION
WHEN OTHERS THEN
NULL; -- Ignore errors
END;
WHEN OTHERS THEN
BEGIN
EXECUTE IMMEDIATE
'call dbms_stats.lock_table_stats(' ||
em_check.enquote_name(l_emd_schema) || ', ' ||
em_check.enquote_name(l_table_name) || ')';
EXCEPTION
WHEN OTHERS THEN
NULL; -- Ignore errors
END;
MGMT_LOG.LOG_ERROR('ANALYZE', null,
'Error analyzing object: ' || part_rec.table_name ||
' Error: ' || SUBSTR(SQLERRM, 1, 1000));
END;
END LOOP;
END IF;
-- Executing DBMS_STATS.gather_system_stats on every Saturday
IF TO_CHAR(SYSDATE, 'DAY') LIKE 'SATURDAY%' THEN
DBMS_STATS.gather_system_stats();
END IF;
-- Log overall maintenance performance.
MGMT_LOG.LOG_PERFORMANCE('ANALYZE',
(SYSDATE-start_timestamp)*(24*60*60*1000),
start_timestamp, 'Y', 'OBJECTS', object_count);
-- Pin all PL/SQL packages and triggers in memory.
pin_plsql;
--
-- Perform partion truncation after analysis due to bug: 353446
--
add_truncate_partitions ;
-- partition_maintenance will drop the partition beyond retention period
-- IF DB versio is >= 10.2
IF REPOSITORY_DB_V102 THEN
EMD_MAINT_UTIL.partition_maintenance ( p_stop_job => FALSE );
END IF;
--add recreate synonyms to recreate invalidated records in 10
IF REPOSITORY_DB_V10 THEN
EMD_MAINT_UTIL.recreate_synonyms;
END IF;
DBMS_APPLICATION_INFO.SET_MODULE(
module_name => ' ',
action_name => ' ');
EXCEPTION
WHEN can_not_access_overflow_table THEN
NULL;
WHEN OTHERS THEN
MGMT_LOG.LOG_ERROR('ANALYZE', null,
'Error during maintenance: ' || SUBSTR(SQLERRM, 1, 1000));
END analyze_emd_schema;
--
-- Procedure to tun on/of extended sql trace for analyze schema dbms job
--
PROCEDURE DBMSJOB_EXTENDED_SQL_TRACE_ON(p_value IN BOOLEAN) IS
BEGIN
MGMT_SQLTRACE.EXTENDED_SQL_TRACE_ON(EST_ANALYZE_NAME, p_value);
END DBMSJOB_EXTENDED_SQL_TRACE_ON;
-- PROCEDURE: analyze_objects_without_stats
--
-- PARAMETERS:
--
-- emd_schema VARCHAR2
--
-- Name of the schema containing the emd objects without stats that you want
-- to analyze( i.e. 'SCOTT' )
--
-- EXAMPLE:
--
-- This is called by RepMgr uprade script (emrepmgr.pl). If called
-- directly this function
-- will immediatly generate stats for tables in db version 9.2+ that
-- are not partitioned
-- > execute emd_maintenance.analyze_objects_without_stats('emd');
--
PROCEDURE analyze_objects_without_stats(emd_schema VARCHAR2) IS
OLIST DBMS_STATS.OBJECTTAB;
l_emd_schema VARCHAR2(30) := EM_CHECK.schema_name(emd_schema);
BEGIN
DBMS_APPLICATION_INFO.SET_MODULE(
module_name => 'Oracle Enterprise Manager.analyze objects without stats',
action_name => 'start');
--If repository is 9.2 or above
IF NOT (REPOSITORY_DB_V91) THEN
-- Get list of objects with empty stats
DBMS_STATS.GATHER_SCHEMA_STATS(l_emd_schema, DBMS_STATS.AUTO_SAMPLE_SIZE,
FALSE, 'FOR ALL COLUMNS SIZE AUTO',NULL,'DEFAULT',FALSE,NULL,NULL,
'LIST EMPTY',OLIST);
-- Loop through the list of objects with empty stats. Analyze the
-- objects that are not partitioned.
IF (OLIST.COUNT > 0) THEN
FOR TABLE_ROW IN OLIST.FIRST..OLIST.LAST LOOP
BEGIN
IF OLIST(TABLE_ROW).OBJTYPE = 'TABLE' AND
OLIST(TABLE_ROW).PARTNAME IS NULL THEN
--If table is not mgmt_metric_raw, 1day or 1hour,
--let Oracle determine appropriate sample size
IF OLIST(TABLE_ROW).OBJNAME NOT IN ('MGMT_METRICS_RAW',
'MGMT_METRICS_1HOUR',
'MGMT_METRICS_1DAY') THEN
dbms_stats.gather_table_stats(l_emd_schema, OLIST(TABLE_ROW).OBJNAME, NULL, DBMS_STATS.AUTO_SAMPLE_SIZE, FALSE,
'FOR ALL COLUMNS SIZE AUTO',NULL,'GLOBAL',TRUE,NULL,NULL,NULL); ELSE
--If table is either mgmt_metric_raw, 1day or 1hour,
--use estimate percentage as 0.000001
dbms_stats.gather_table_stats(l_emd_schema, OLIST(TABLE_ROW).OBJNAME, NULL, 0.000001, FALSE,
'FOR ALL COLUMNS SIZE AUTO',NULL,'GLOBAL',TRUE,NULL,NULL,NULL); END IF;
END IF;
EXCEPTION
WHEN OTHERS THEN
MGMT_LOG.LOG_ERROR('ANALYZE OBJECTS WITHOUT STATS', null,
'Error analyzing object: ' || OLIST(TABLE_ROW).OBJNAME ||
' Error: ' || SUBSTR(SQLERRM, 1, 1000));
END;
END LOOP;
END IF; -- OLIST.COUNT > 0
-- Clear the object list
OLIST.DELETE;
END IF; -- REPOSITORY_DB_V9.2+
DBMS_APPLICATION_INFO.SET_MODULE(
module_name => ' ',
action_name => ' ');
EXCEPTION
WHEN OTHERS THEN
MGMT_LOG.LOG_ERROR('ANALYZE OBJECTS WITHOUT STATS', null,
'Error during maintenance: ' || SUBSTR(SQLERRM, 1, 1000));
END analyze_objects_without_stats;
-- PROCEDURE: delete_all_stats
--
-- PARAMETERS:
--
-- emd_schema VARCHAR2
--
-- name of the schema containing the emd objects that you want
-- to delete statistics on. i.e. 'SCOTT'
--
-- start_day VARCHAR2 DEFAULT 'SATURDAY' -
--
-- The day of the week you want to delete statistics on.
-- The default is to have stats deleted on SATURDAY.
--
-- start_hour DEFAULT 1
--
-- The hour you want statistics deleted on, in military time
-- By default this is 1am. If you want it at 1pm you would pass 13.
--
-- start_minutes DEFAULT 0
--
-- Number of minutes after the hour you want statistics deleted on.
-- The default is to delete statistics on the hour ( 0 minutes ).
--
-- EXAMPLE:
--
-- If this is Monday, this example would delete all stats, in schema emd,
-- today, at 2:50pm.
--
-- > execute emd_maintenance.delete_all_stats('emd','MONDAY',14,50);
--
procedure delete_all_stats(emd_schema VARCHAR2,
start_day VARCHAR2 DEFAULT 'SATURDAY',
start_hour NUMBER DEFAULT 0,
start_minutes NUMBER DEFAULT 0) IS
jobnum number;
BEGIN
dbms_job.submit ( jobnum,
'dbms_stats.delete_schema_stats(''' ||
EM_CHECK.schema_name(emd_schema) || ''');',
trunc(next_day((sysdate-1),start_day)) +
start_hour/24+start_minutes/60/24);
commit;
END delete_all_stats;
-- PROCEDURE: monitor_indexes
--
-- This procedure will turn on index usage monitoring for all indexes in the
-- schema which it is run.
--
-- PARAMETERS:
--
-- none
--
-- EXAMPLE:
--
-- > execute emd_maintenance.monitor_indexes();
--
procedure monitor_indexes IS
CURSOR user_indexes IS
SELECT index_name
FROM USER_INDEXES
WHERE index_type = 'NORMAL' AND status = 'VALID';
BEGIN
-- Loop through the index names and turn usage monitoring on.
FOR idx_rec in user_indexes LOOP
execute immediate 'alter index ' ||
em_check.enquote_name(idx_rec.index_name)
|| ' monitoring usage';
END LOOP;
END monitor_indexes;
-- PROCEDURE: rebuild_indexes
--
-- This procedure will rebuild indexes on the repository tables
-- with the highest proportion of inserts/deletes.
--
-- PARAMETERS:
--
-- none
--
-- EXAMPLE:
--
-- > execute emd_maintenance.rebuild_indexes();
--
procedure rebuild_indexes IS
CURSOR table_list IS
SELECT table_name, interval, table_type FROM mgmt_rebuild_indexes;
TYPE p_table_names IS TABLE OF VARCHAR(30);
TYPE p_intervals IS TABLE OF NUMBER(10);
TYPE p_table_types IS TABLE OF VARCHAR(30);
v_rebuild_flag NUMBER(10);
v_table_names p_table_names;
v_intervals p_intervals;
v_table_types p_table_types;
start_timestamp DATE DEFAULT SYSDATE;
BEGIN
DBMS_APPLICATION_INFO.SET_MODULE(
module_name => 'Oracle Enterprise Manager.rebuild EM indexes',
action_name => ' ');
-- get tables to rebuild
OPEN table_list;
FETCH table_list BULK COLLECT INTO v_table_names, v_intervals, v_table_types;
CLOSE table_list;
FOR i IN 1..v_table_names.LAST LOOP
SELECT MOD(TO_CHAR(sysdate, 'DDD'), v_intervals(i)) INTO v_rebuild_flag FROM DUAL;
IF v_rebuild_flag = 0 THEN
IF v_table_types(i) = 'IOT' THEN
rebuild_iot(v_table_names(i));
END IF;
rebuild_table_indexes(v_table_names(i));
END IF;
END LOOP;
-- Log index rebuild performance
MGMT_LOG.LOG_PERFORMANCE('MAINT INDEX REBUILDS',
(SYSDATE-start_timestamp)*(24*60*60*1000),
start_timestamp, 'Y', 'NONE', 0);
DBMS_APPLICATION_INFO.SET_MODULE(
module_name => ' ',
action_name => ' ');
EXCEPTION
WHEN OTHERS THEN
IF table_list%ISOPEN THEN
CLOSE table_list;
END IF;
MGMT_LOG.LOG_ERROR('MAINT INDEX REBUILDS', null,
'Error during index rebuilds: ' || SUBSTR(SQLERRM, 1, 1000));
END rebuild_indexes;
-- PROCEDURE: rebuild_iot
--
-- This procedure will rebuild an iot
--
-- PARAMETERS:
--
-- iot name
procedure rebuild_iot(iot IN VARCHAR2) IS
begin_timestamp DATE DEFAULT SYSDATE;
BEGIN
DBMS_APPLICATION_INFO.SET_ACTION(action_name => iot || ' IOT rebuild');
execute immediate 'alter table ' || EM_CHECK.enquote_name(iot) ||
' move online';
DBMS_APPLICATION_INFO.SET_ACTION(action_name => ' ');
EXCEPTION
WHEN OTHERS THEN
MGMT_LOG.LOG_ERROR('MAINT INDEX REBUILDS', null,
'Error rebuilding ' || iot || ' IOT: ' || SUBSTR(SQLERRM, 1, 1000));
END rebuild_iot;
-- PROCEDURE: rebuild_table_indexes
--
-- This procedure will rebuild all indexes on a given table
--
-- PARAMETERS:
--
-- table name
procedure rebuild_table_indexes(tablename IN VARCHAR2) IS
TYPE p_IndexNameList IS TABLE OF VARCHAR2(30)
INDEX BY BINARY_INTEGER;
CURSOR table_indexes IS
SELECT index_name
FROM USER_INDEXES
WHERE index_type = 'NORMAL' AND status = 'VALID' AND
table_name = tablename;
start_timestamp DATE DEFAULT SYSDATE;
v_index_names p_IndexNameList;
BEGIN
OPEN table_indexes;
-- Loop through the target cursor limiting to purge batch so we scale.
FETCH table_indexes BULK COLLECT INTO v_index_names;
CLOSE table_indexes;
IF v_index_names.COUNT != 0 THEN
FOR i IN v_index_names.FIRST..v_index_names.LAST LOOP
BEGIN
DBMS_APPLICATION_INFO.SET_ACTION(action_name => v_index_names(i) ||
' rebuilding');
execute immediate 'alter index ' ||
em_check.enquote_name(v_index_names(i)) ||
' rebuild online nologging';
DBMS_APPLICATION_INFO.SET_ACTION(action_name => ' ');
EXCEPTION
WHEN OTHERS THEN
MGMT_LOG.LOG_ERROR('MAINT INDEX REBUILDS', null,
'Error rebuilding index ' || v_index_names(i) ||
' Error: ' || SUBSTR(SQLERRM, 1, 1000));
END;
END LOOP; -- Index size loop
END IF;
EXCEPTION
WHEN OTHERS THEN
IF table_indexes%ISOPEN THEN
CLOSE table_indexes;
END IF;
END rebuild_table_indexes;
-- PROCEDURE: pin_plsql
--
-- This procedure will pin all the most heavily used SQL objects into
-- the shared pool. This will help prevent fragmentation of the shared pool
-- on busy systems.
--
-- PARAMETERS:
--
-- none
--
-- EXAMPLE:
--
-- > execute emd_maintenance.pin_plsql();
--
procedure pin_plsql IS
CURSOR pinnable_objects IS
SELECT object_name
FROM ALL_OBJECTS
WHERE object_type in ('PROCEDURE','PACKAGE','FUNCTION')
AND status = 'VALID'
AND owner = MGMT_USER.GET_REPOSITORY_OWNER;
l_object_exists NUMBER := 0 ;
BEGIN
-- Make this routine a no-op for EM 11g. epd
RETURN;
DBMS_APPLICATION_INFO.SET_MODULE(
module_name => 'Oracle Enterprise Manager.pin EM plsql',
action_name => 'start');
BEGIN
IF EM_CHECK.SQL_OBJECT_NAME('SYS.DBMS_SHARED_POOL.KEEP') =
'SYS.DBMS_SHARED_POOL.KEEP'
THEN
l_object_exists := 1 ;
END IF ;
EXCEPTION
WHEN OTHERS THEN
l_object_exists := 0 ;
END ;
-- Pin the key SQL based objects in memory, if
-- the DBMS_SHARED_POOL package exists.
IF (l_object_exists > 0) THEN
FOR pin_rec in pinnable_objects LOOP
EXECUTE IMMEDIATE
'BEGIN sys.dbms_shared_pool.keep(:1); END;'
USING MGMT_USER.GET_REPOSITORY_OWNER||'.'||pin_rec.object_name;
END LOOP;
END IF;
EXCEPTION
WHEN OTHERS THEN
IF pinnable_objects%ISOPEN THEN
CLOSE pinnable_objects;
END IF;
MGMT_LOG.LOG_ERROR('MAINT PIN PLSQL', null,
'Error pinning PLSQL: ' || SUBSTR(SQLERRM, 1, 1000));
END pin_plsql;
procedure collect_segment_sizes IS
TYPE p_TableNameList IS TABLE OF VARCHAR2(30)
INDEX BY BINARY_INTEGER;
TYPE p_AllocSizeList IS TABLE OF NUMBER
INDEX BY BINARY_INTEGER;
TYPE p_SpaceUsedList IS TABLE OF NUMBER
INDEX BY BINARY_INTEGER;
TYPE p_IndexNameList IS TABLE OF VARCHAR2(30)
INDEX BY BINARY_INTEGER;
TYPE p_TableRec IS RECORD
(tableName p_TableNameList, -- The name of the table
AllocatedSize p_AllocSizeList, -- The total space allocated for table
SpaceUsed p_SpaceUsedList); -- The actual used space for table
TYPE p_IndexRec IS RECORD
(indexName p_IndexNameList, -- The name of the index
tableName p_TableNameList, -- The name of the table the index is on
AllocatedSize p_AllocSizeList, -- The total space allocated for index
SpaceUsed p_SpaceUsedList); -- The actual used space for index
CURSOR table_alloc_cursor IS
SELECT t.table_name,
s.bytes
FROM USER_TABLES t, USER_SEGMENTS s
WHERE t.table_name = s.segment_name
AND s.segment_type = 'TABLE';
CURSOR index_alloc_cursor IS
SELECT i.index_name,
i.table_name,
s.bytes
FROM USER_INDEXES i, USER_SEGMENTS s
WHERE i.index_name = s.segment_name
AND s.segment_type = 'INDEX';
v_tables p_TableRec;
v_indexes p_IndexRec;
v_user VARCHAR2(256);
rows NUMBER := 0;
--
-- Output variables for DBMS_SPACE package
--
v_tblocks number;
v_tbytes number;
v_ublocks number;
v_ubytes number;
v_luef number;
v_lueb number;
v_lub number;
i BINARY_INTEGER;
start_timestamp DATE DEFAULT SYSDATE;
BEGIN
DBMS_APPLICATION_INFO.SET_MODULE(
module_name => 'Oracle Enterprise Manager.Segment Sizing',
action_name => 'Collect');
OPEN table_alloc_cursor;
-- Loop through the target cursor limiting to purge batch so we scale.
FETCH table_alloc_cursor BULK COLLECT INTO v_tables.tableName,
v_tables.AllocatedSize;
-- Get the user for the sizing procedure
SELECT USER INTO v_user FROM DUAL;
-- Loop through the tables finding the allocated size.
FOR i IN v_tables.tableName.FIRST..v_tables.tableName.LAST LOOP
dbms_space.unused_space(v_user,v_tables.tableName(i),
'TABLE',
v_tblocks, v_tbytes,
v_ublocks, v_ubytes,
v_luef, v_lueb,
v_lub, null);
v_tables.SpaceUsed(i) := v_tbytes - v_ubytes;
END LOOP; -- Table size loop
CLOSE table_alloc_cursor;
OPEN index_alloc_cursor;
FETCH index_alloc_cursor BULK COLLECT INTO v_indexes.indexName,
v_indexes.tableName,
v_indexes.AllocatedSize;
-- Loop through the indexes finding the allocated size.
FOR i IN v_indexes.indexName.FIRST..v_indexes.indexName.LAST LOOP
dbms_space.unused_space(v_user,v_indexes.indexName(i),
'INDEX',
v_tblocks, v_tbytes,
v_ublocks, v_ubytes,
v_luef, v_lueb,
v_lub, null);
v_indexes.SpaceUsed(i) := v_tbytes - v_ubytes;
END LOOP; -- Index size loop
CLOSE index_alloc_cursor;
-- Insert the collected table size records.
FORALL i IN v_tables.tableName.FIRST..v_tables.tableName.LAST
INSERT INTO MGMT_TABLE_SIZES (TABLE_NAME, ALLOCATED_SIZE, SPACE_USED)
VALUES(v_tables.tableName(i), v_tables.AllocatedSize(i),
v_tables.SpaceUsed(i));
-- Insert the collected index size records.
FORALL i IN v_indexes.indexName.FIRST..v_indexes.indexName.LAST
INSERT INTO MGMT_INDEX_SIZES (INDEX_NAME, TABLE_NAME,
ALLOCATED_SIZE, SPACE_USED)
VALUES(v_indexes.indexName(i), v_indexes.tableName(i),
v_indexes.AllocatedSize(i), v_indexes.SpaceUsed(i));
COMMIT;
MGMT_LOG.LOG_PERFORMANCE('MAINT COLLECT SEG SIZES',
(SYSDATE-start_timestamp)*(24*60*60*1000),
start_timestamp, 'Y', 'NONE', 0);
EXCEPTION
WHEN OTHERS THEN
IF table_alloc_cursor%ISOPEN THEN
CLOSE table_alloc_cursor;
END IF;
IF index_alloc_cursor%ISOPEN THEN
CLOSE index_alloc_cursor;
END IF;
MGMT_LOG.LOG_ERROR('MAINT COLLECT SEG SIZES', null,
'Error during seg sizing: ' || SUBSTR(SQLERRM, 1, 1000));
end collect_segment_sizes;
-- internal procedure to submit a job
PROCEDURE submit_dbms_job(v_job_num OUT NUMBER,
v_what VARCHAR2,
v_start_date DATE,
v_interval VARCHAR2)
IS
l_count NUMBER;
BEGIN
SELECT count(*)
INTO l_count
FROM user_jobs
WHERE what = v_what;
-- If the job already exists, then don't submit
-- a new one
IF (l_count != 0) THEN
RETURN;
END IF;
DBMS_JOB.SUBMIT(v_job_num, v_what, v_start_date, v_interval);
END submit_dbms_job;
-- The following procedures are used to start and stop
-- EM jobs
PROCEDURE submit_em_dbms_jobs
IS
jobNum NUMBER;
l_user_name VARCHAR2(32);
l_worker_count NUMBER ;
BEGIN
-- Submit the following jobs for central mode only.
IF (is_central_mode > 0) THEN
-- Collections job
BEGIN
MGMT_COLLECTION.start_workers ;
COMMIT ;
END ;
-- Basic rollup job
submit_dbms_job(jobNum, 'EMD_LOADER.ROLLUP();',
sysdate + (1/48), 'sysdate + (1/24)' );
COMMIT;
-- Notification check job
submit_dbms_job(jobNum, 'EMD_NOTIFICATION.CHECK_FOR_SEVERITIES();',
SYSDATE, 'sysdate + (1/(24*60*2))' );
COMMIT;
-- Ping system job
submit_dbms_job(jobNum, 'EM_PING.MARK_NODE_STATUS();',
SYSDATE, 'sysdate + (1/(24*60*2))' );
COMMIT;
-- Submit job to compute the severities every minute
submit_dbms_job(jobNum, 'EM_SEVERITY_REPOS.EXECUTE_REPOS_SEVERITY_EVAL();',
SYSDATE, 'sysdate + 1 / (24 * 60)' );
COMMIT;
-- Job engine jobs
submit_dbms_job(JobNum, 'MGMT_JOB_ENGINE.apply_purge_policies();',
SYSDATE, 'sysdate + 1' );
COMMIT;
-- maintenace / analysis job
l_user_name := user;
BEGIN
SELECT owner INTO l_user_name
FROM all_tables
WHERE table_name = 'MGMT_TARGETS';
EXCEPTION
WHEN NO_DATA_FOUND THEN
-- Default to SYSMAN
l_user_name := 'SYSMAN';
END;
submit_dbms_job(jobNum,
'emd_maintenance.analyze_emd_schema(''' || l_user_name || ''');',
trunc(next_day((sysdate-1), TO_CHAR((SYSDATE+1),'DAY'))) +
3/24 + 10/60/24,
'trunc(sysdate + 1) + 3/24 + 10/60/24');
COMMIT;
-- RT Rollup job
submit_dbms_job(jobNum, 'EMD_RT_ROLLUP.ROLLUP();',
SYSDATE, 'sysdate + (1/24)' );
COMMIT;
-- E2E rollup job
submit_dbms_job(jobNum, 'EMD_E2E_ROLLUP.ROLLUP();',
SYSDATE, 'sysdate + (1/24)' );
COMMIT;
-- Service beacon availability job
submit_dbms_job(jobNum, 'MGMT_GENSVC_AVAIL.EXEC_AVAIL_JOB();',
SYSDATE, 'sysdate + (1/1440)' );
COMMIT;
-- Purge policies job
submit_dbms_job(jobNum, 'EM_PURGE.APPLY_PURGE_POLICIES();',
trunc(SYSDATE+1), 'trunc(sysdate + 1)' );
COMMIT;
-- RCA purge job
submit_dbms_job(jobNum, 'MGMT_RCA.PURGE_RCA_RESULTS();',
SYSDATE, 'sysdate + 1' );
COMMIT;
-- Metric baselines compute stats and set thresholds jobs
MGMT_BSLN.SUBMIT_BSLN_JOBS;
COMMIT;
-- Clear expired policy suppressions job
submit_dbms_job(jobNum, 'EM_POLICY.CLEAR_EXPIRED_SUPPRESSIONS;',
SYSDATE, 'trunc(SYSDATE + 1)+(1/60/24)' );
COMMIT;
--
-- Submit RESUBMIT_FAILED_TASK to run every hour, starting from next hour.
--
submit_dbms_job(jobNum, 'EM_TASK.RESUBMIT_FAILED_TASK();',
TRUNC(SYSDATE, 'HH24')+1/24,
'SYSDATE+1/24'
);
COMMIT;
ELSE
-- Submit only one job for stand alone
submit_dbms_job(jobNum, 'EMD_MAINTENANCE.EXECUTE_EM_DBMS_JOB_PROCS();',
SYSDATE, 'sysdate + 1 / (24 * 60)' );
COMMIT;
END IF;
END submit_em_dbms_jobs;
PROCEDURE execute_em_dbms_job_procs
IS
v_proc_start_date DATE DEFAULT SYSDATE;
l_start_timestmp TIMESTAMP := SYSTIMESTAMP;
l_status NUMBER ;
BEGIN
-- Collections proc
IF MOD(to_char(v_proc_start_date,'MI'),2) = 0
THEN
BEGIN
l_status := EM_TASK.run_tasks(1) ;
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
END IF ;
-- Ping system proc
BEGIN
EM_PING.MARK_NODE_STATUS();
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
-- compute severities proc
BEGIN
EM_SEVERITY_REPOS.EXECUTE_REPOS_SEVERITY_EVAL();
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
-- Run the following jobs once every hour
IF (to_char(v_proc_start_date, 'MI') = '00') THEN
-- Basic rollup proc
BEGIN
EMD_LOADER.ROLLUP();
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
--
-- Execute resubmit_failed_task to resubmit failed task.
-- To be executed on hourly basis
--
BEGIN
EM_TASK.resubmit_failed_task();
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
END IF;
-- Run this once a day at mid night.
IF (to_char(v_proc_start_date, 'HH24:MI') = '00:00') THEN
-- Purge policies job
BEGIN
EM_PURGE.APPLY_PURGE_POLICIES();
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
-- Job engine proc
BEGIN
MGMT_JOB_ENGINE.apply_purge_policies();
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
END IF;
-- Run clear expired violation suppressions proc at 12:01 AM everyday.
IF (to_char(v_proc_start_date, 'HH24:MI') = '00:01') THEN
-- Clear expired suppressions
BEGIN
EM_POLICY.CLEAR_EXPIRED_SUPPRESSIONS;
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
END IF;
IF (is_detailed_logging_enabled > 0) THEN
MGMT_LOG.LOG_PERFORMANCE('MAINT EXEC DBMS JOB PROCS',
MGMT_GLOBAL.ELAPSED_TIME_MSEC(l_start_timestmp, SYSTIMESTAMP),
l_start_timestmp, 'Y', 'NONE', 0);
END IF;
END execute_em_dbms_job_procs;
PROCEDURE remove_em_dbms_jobs
IS
l_error VARCHAR2(100) := NULL;
l_error_count NUMBER := 0 ;
BEGIN
SAVEPOINT remove_em_dbms_jobs_start ;
FOR crec IN (select job, what FROM user_jobs
where what in (
'MGMT_GENSVC_AVAIL.EXEC_AVAIL_JOB();',
'EMD_E2E_ROLLUP.ROLLUP();',
'EMD_EVALUATION.EVALSQLMETRICS();',
'EMD_LOADER.ROLLUP();',
'EMD_NOTIFICATION.CHECK_FOR_SEVERITIES();',
'EMD_RT_ROLLUP.ROLLUP();',
'EM_PING.MARK_NODE_STATUS();',
'EM_PURGE.APPLY_PURGE_POLICIES();',
'EM_SEVERITY_REPOS.EXECUTE_REPOS_SEVERITY_EVAL();',
'MGMT_JOB_ENGINE.apply_purge_policies();',
'EMD_MAINTENANCE.EXECUTE_EM_DBMS_JOB_PROCS();',
'EM_POLICY.CLEAR_EXPIRED_SUPPRESSIONS;',
'MGMT_RCA.PURGE_RCA_RESULTS();',
'EM_TASK.RESUBMIT_FAILED_TASK();'
)
OR what LIKE 'emd_maintenance.analyze_emd_schema%'
OR what LIKE 'EM_TASK.WORKER%'
)
LOOP
BEGIN
DBMS_JOB.REMOVE(crec.job);
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -23421 THEN
l_error_count := l_error_count + 1 ;
IF l_error IS NULL
THEN
l_error := SUBSTR(SQLERRM,1,100) ;
END IF ;
END IF;
END;
END LOOP;
BEGIN
DELETE MGMT_COLLECTION_WORKERS ;
EXCEPTION
WHEN OTHERS THEN NULL ;
END ;
BEGIN
MGMT_BSLN.DELETE_BSLN_JOBS;
EXCEPTION
WHEN OTHERS THEN NULL;
END;
IF l_error_count > 0
THEN
ROLLBACK TO SAVEPOINT remove_em_dbms_jobs_start ;
raise_application_error(MGMT_GLOBAL.UNEXPECTED_ERR,
l_error_count||' error(s) when dropping dbms_jobs '||
',first error='||l_error) ;
END IF ;
END remove_em_dbms_jobs;
-- The following procedure is used to move em repository
-- from one table space to another.
PROCEDURE move_em_tblspc(dest_tbs_in IN VARCHAR2)
IS
l_source_tbs VARCHAR2(30);
l_dest_tbs VARCHAR2(30);
TYPE p_TableNameList IS TABLE OF VARCHAR2(30)
INDEX BY BINARY_INTEGER;
TYPE p_IndexNameList IS TABLE OF VARCHAR2(30)
INDEX BY BINARY_INTEGER;
CURSOR table_names(v_tablespace_name VARCHAR2) IS
SELECT table_name
FROM USER_TABLES
WHERE tablespace_name = v_tablespace_name
AND iot_name IS NULL;
CURSOR index_names(v_tablespace_name VARCHAR2) IS
SELECT index_name
FROM USER_INDEXES
WHERE index_type = 'NORMAL'
AND status = 'VALID'
AND tablespace_name = v_tablespace_name;
l_table_names p_TableNameList;
l_index_names p_IndexNameList;
BEGIN
-- Check that dest_tbs_in exists..
BEGIN
SELECT tablespace_name INTO l_dest_tbs
FROM user_tablespaces
WHERE tablespace_name=upper(dest_tbs_in);
EXCEPTION
WHEN OTHERS THEN
raise_application_error(-20001, 'Destination tablespace ' ||
dest_tbs_in || ' does not exists.');
END;
-- Get source tablespace
BEGIN
SELECT tablespace_name INTO l_source_tbs
FROM user_tables
WHERE table_name = 'MGMT_TARGETS';
EXCEPTION
WHEN OTHERS THEN
raise_application_error(-20002, 'Error getting source tablespace name.');
END;
-- Check source_tbs != dest_tbs
IF (l_source_tbs = l_dest_tbs) THEN
raise_application_error(-20003, 'Source and destination tablespaces are same.');
END IF;
-- Move schema to destination tablespace
-- Get list of tables to move..
OPEN table_names(l_source_tbs);
FETCH table_names BULK COLLECT INTO l_table_names;
CLOSE table_names;
IF l_table_names.COUNT != 0 THEN
FOR i IN l_table_names.FIRST..l_table_names.LAST LOOP
BEGIN
-- Move the table.
-- This will fail if the table has LONG RAW columns
-- Currently the following tables have LONG RAW columns..
-- MGMT_PORTLET_PREFERENCE_STORE
-- MIGRATE_EVENT_DETAILS
-- MIGRATE_PREFERRED_CREDENTIALS
execute immediate 'ALTER TABLE ' ||
em_check.enquote_name(l_table_names(i)) ||
' MOVE TABLESPACE ' ||
em_check.enquote_name(l_dest_tbs);
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Error while moving table ' ||
l_table_names(i) || '. ERROR = ' || SQLERRM);
END;
END LOOP;
END IF;
-- Recreate indexes..
OPEN index_names(l_source_tbs);
FETCH index_names BULK COLLECT INTO l_index_names;
CLOSE index_names;
IF (l_index_names.COUNT > 0) THEN
FOR j IN l_index_names.FIRST..l_index_names.LAST LOOP
BEGIN
-- Move the index.
-- This will fail if the index key length is greater
execute immediate 'alter index ' ||
em_check.enquote_name(l_index_names(j))||
' rebuild online nologging tablespace ' ||
em_check.enquote_name(l_dest_tbs);
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Error while moving index ' ||
l_index_names(j) || '. ERROR = ' || SQLERRM);
END;
END LOOP;
END IF;
END move_em_tblspc;
-- Get repository version
FUNCTION get_version(p_comp_name VARCHAR2 DEFAULT 'CORE')
RETURN VARCHAR2 IS
l_comp_ver MGMT_VERSIONS.version%TYPE;
BEGIN
SELECT version INTO l_comp_ver
FROM MGMT_VERSIONS
WHERE component_name = UPPER(p_comp_name);
RETURN l_comp_ver;
END get_version;
-- Get repository mode
FUNCTION get_mode(p_comp_name VARCHAR2 DEFAULT 'CORE')
RETURN VARCHAR2 IS
l_comp_mode MGMT_VERSIONS.component_mode%TYPE;
BEGIN
SELECT component_mode INTO l_comp_mode
FROM MGMT_VERSIONS
WHERE component_name = UPPER(p_comp_name);
RETURN l_comp_mode;
END get_mode;
FUNCTION is_central_mode(p_comp_name VARCHAR2 DEFAULT 'CORE')
RETURN NUMBER IS
BEGIN
RETURN(EMD_MAINT_UTIL.is_central_mode(p_comp_name)) ;
END is_central_mode;
FUNCTION get_comp_status(p_comp_name VARCHAR2 DEFAULT 'CORE')
RETURN NUMBER IS
l_comp_status MGMT_VERSIONS.status%TYPE;
BEGIN
SELECT status INTO l_comp_status
FROM MGMT_VERSIONS
WHERE component_name = UPPER(p_comp_name);
RETURN l_comp_status;
END get_comp_status;
PROCEDURE set_version(p_comp_name VARCHAR2 DEFAULT 'CORE',
p_version VARCHAR2 DEFAULT NULL,
p_compat_ver VARCHAR2 DEFAULT NULL,
p_comp_mode VARCHAR2 DEFAULT NULL,
p_comp_status NUMBER DEFAULT G_STATUS_INITIALIZED) IS
l_version MGMT_VERSIONS.version%TYPE;
l_compat_version MGMT_VERSIONS.compat_core_version%TYPE;
l_comp_mode MGMT_VERSIONS.component_mode%TYPE;
BEGIN
-- Default version
IF (p_version IS NULL) THEN
l_version := G_VERSION;
ELSE
l_version := p_version;
END IF;
IF (p_compat_ver IS NULL) THEN
l_compat_version := G_COMPAT_VERSION;
ELSE
l_compat_version := p_compat_ver;
END IF;
IF (p_comp_mode IS NULL) THEN
l_comp_mode := G_COMPONENT_MODE_CENTRAL;
ELSE
l_comp_mode := p_comp_mode;
END IF;
UPDATE MGMT_VERSIONS
SET version = l_version,
compat_core_version = l_compat_version,
component_mode = l_comp_mode,
status = p_comp_status
WHERE component_name = p_comp_name;
IF (SQL%ROWCOUNT = 0) THEN
INSERT INTO MGMT_VERSIONS
(component_name, version, compat_core_version, component_mode, status)
VALUES
(p_comp_name, l_version, l_compat_version, l_comp_mode, p_comp_status);
END IF;
END set_version;
PROCEDURE set_comp_status(p_comp_name VARCHAR2 DEFAULT 'CORE',
p_comp_status NUMBER DEFAULT G_STATUS_INITIALIZED) IS
BEGIN
UPDATE MGMT_VERSIONS
SET status = p_comp_status
WHERE component_name = p_comp_name;
END set_comp_status;
FUNCTION get_sdk_list
RETURN EM_SDK_COMPS IS
l_sdk_list EM_SDK_COMPS;
BEGIN
l_sdk_list := EM_SDK_COMPS (
EM_SDK_COMP('MGMT_METRICS', 'TABLE', 'SELECT'),
EM_SDK_COMP('MGMT_TARGETS', 'TABLE', 'SELECT'),
EM_SDK_COMP('MGMT_TYPE_PROPERTIES', 'TABLE', 'SELECT'),
EM_SDK_COMP('MGMT_TARGET_PROPERTIES', 'TABLE', 'SELECT'),
EM_SDK_COMP('MGMT_METRICS_RAW', 'TABLE', 'SELECT'),
EM_SDK_COMP('MGMT_CURRENT_METRICS', 'TABLE', 'SELECT'),
EM_SDK_COMP('MGMT_STRING_METRIC_HISTORY', 'TABLE', 'SELECT'),
EM_SDK_COMP('MGMT_LONG_TEXT', 'TABLE', 'SELECT'),
EM_SDK_COMP('MGMT_METRICS_COMPOSITE_KEYS', 'TABLE', 'SELECT'),
EM_SDK_COMP('MGMT_METRICS_1HOUR', 'TABLE', 'SELECT'),
EM_SDK_COMP('MGMT_METRICS_1DAY', 'TABLE', 'SELECT'),
EM_SDK_COMP('MGMT_METRIC_ERRORS', 'TABLE', 'SELECT'),
EM_SDK_COMP('MGMT_CURRENT_METRIC_ERRORS', 'TABLE', 'SELECT'),
EM_SDK_COMP('MGMT_SEVERITY', 'TABLE', 'SELECT'),
EM_SDK_COMP('MGMT_CURRENT_SEVERITY', 'TABLE', 'SELECT'),
EM_SDK_COMP('MGMT_AVAILABILITY', 'TABLE', 'SELECT'),
EM_SDK_COMP('MGMT_CURRENT_AVAILABILITY', 'TABLE', 'SELECT'),
EM_SDK_COMP('MGMT_METRIC_COLLECTIONS', 'TABLE', 'SELECT'),
EM_SDK_COMP('MGMT_COLLECTION_PROPERTIES', 'TABLE', 'SELECT'),
EM_SDK_COMP('MGMT_METRIC_THRESHOLDS', 'TABLE', 'SELECT'),
EM_SDK_COMP('MGMT_TARGET_ASSOCS', 'TABLE', 'SELECT'),
EM_SDK_COMP('MGMT_JOB', 'TABLE', 'SELECT'),
EM_SDK_COMP('MGMT_JOB_PARAMETER', 'TABLE', 'SELECT'),
EM_SDK_COMP('MGMT_JOB_TARGET', 'TABLE', 'SELECT'),
EM_SDK_COMP('MGMT_JOB_SCHEDULE', 'TABLE', 'SELECT'),
EM_SDK_COMP('MGMT_JOB_EXECPLAN', 'TABLE', 'SELECT'),
EM_SDK_COMP('MGMT_JOB_EXEC_SUMMARY', 'TABLE', 'SELECT'),
EM_SDK_COMP('MGMT_JOB_OUTPUT', 'TABLE', 'SELECT'),
EM_SDK_COMP('MGMT_JOB_EXECUTION', 'TABLE', 'SELECT'),
EM_SDK_COMP('MGMT_DELTA_IDS', 'TABLE', 'SELECT'),
EM_SDK_COMP('MGMT_DELTA_ID_VALUES', 'TABLE', 'SELECT'),
EM_SDK_COMP('MGMT_DELTA_ENTRY', 'TABLE', 'SELECT'),
EM_SDK_COMP('MGMT_DELTA_ENTRY_VALUES', 'TABLE', 'SELECT'),
-- Types
EM_SDK_COMP('MGMT_SEVERITY_OBJ', 'TYPE', 'EXECUTE'),
EM_SDK_COMP('MGMT_SEVERITY_ARRAY', 'TYPE', 'EXECUTE'),
EM_SDK_COMP('MGMT_GUID_OBJ', 'TYPE', 'EXECUTE'),
EM_SDK_COMP('MGMT_GUID_ARRAY', 'TYPE', 'EXECUTE'),
EM_SDK_COMP('MGMT_DELTA_VALUE', 'TYPE', 'EXECUTE'),
EM_SDK_COMP('MGMT_DELTA_VALUES', 'TYPE', 'EXECUTE'),
EM_SDK_COMP('MGMT_NAME_VALUE', 'TYPE', 'EXECUTE'),
EM_SDK_COMP('MGMT_NAME_VALUES', 'TYPE', 'EXECUTE'),
EM_SDK_COMP('SMP_EMD_NVPAIR', 'TYPE', 'EXECUTE'),
EM_SDK_COMP('SMP_EMD_NVPAIR_ARRAY', 'TYPE', 'EXECUTE'),
EM_SDK_COMP('SMP_EMD_STRING_ARRAY', 'TYPE', 'EXECUTE'),
EM_SDK_COMP('SMP_EMD_INTEGER_ARRAY', 'TYPE', 'EXECUTE'),
EM_SDK_COMP('SMP_EMD_AVAIL_OBJ', 'TYPE', 'EXECUTE'),
EM_SDK_COMP('SMP_EMD_TARGET_OBJ', 'TYPE', 'EXECUTE'),
EM_SDK_COMP('SMP_EMD_TARGET_OBJ_ARRAY', 'TYPE', 'EXECUTE'),
-- Packages
EM_SDK_COMP('MGMT_ADMIN', 'PACKAGE', 'EXECUTE'),
EM_SDK_COMP('MGMT_CREDENTIAL', 'PACKAGE', 'EXECUTE'),
EM_SDK_COMP('MGMT_GLOBAL', 'PACKAGE', 'EXECUTE'),
EM_SDK_COMP('MGMT_JOBS', 'PACKAGE', 'EXECUTE'),
EM_SDK_COMP('MGMT_LOG', 'PACKAGE', 'EXECUTE'),
EM_SDK_COMP('MGMT_PREFERENCES', 'PACKAGE', 'EXECUTE'),
EM_SDK_COMP('MGMT_TARGET', 'PACKAGE', 'EXECUTE'),
EM_SDK_COMP('MGMT_USER', 'PACKAGE', 'EXECUTE'),
EM_SDK_COMP('MGMT_DELTA', 'PACKAGE', 'EXECUTE'),
EM_SDK_COMP('ECM_UTIL', 'PACKAGE', 'EXECUTE'),
EM_SDK_COMP('EMD_MNTR', 'PACKAGE', 'EXECUTE')
);
RETURN l_sdk_list;
END get_sdk_list;
PROCEDURE create_sdk_synonyms
IS
l_sdk_list EM_SDK_COMPS;
err_no NUMBER;
l_object_name all_objects.object_name%TYPE ;
BEGIN
-- Create public synonyms for SDK tables/types/packages.
l_sdk_list := get_sdk_list;
FOR i IN 1..l_sdk_list.count LOOP
BEGIN
EXECUTE IMMEDIATE 'CREATE PUBLIC SYNONYM ' ||
em_check.enquote_name(l_sdk_list(i).name) ||
' FOR ' || em_check.enquote_name(l_sdk_list(i).name) ;
EXCEPTION
WHEN OTHERS THEN
err_no := SQLCODE;
IF err_no = -955
THEN
DBMS_OUTPUT.PUT_LINE('ERROR CREATING PUBLIC SYNONYM ' ||
l_sdk_list(i).name);
ELSE
DBMS_OUTPUT.PUT_LINE('ERROR CREATING PUBLIC SYNONYM ' ||
l_sdk_list(i).name || '. ERROR = ' || SQLERRM);
END IF;
-- continue creating other public synonyms
END;
END LOOP;
-- Create public synonyms for views
FOR crec IN (SELECT object_name from all_objects
WHERE object_name like 'MGMT$%'
AND object_type='VIEW')
LOOP
BEGIN
l_object_name := crec.object_name;
EXECUTE IMMEDIATE 'CREATE PUBLIC SYNONYM ' ||
em_check.enquote_name(l_object_name) ||
' FOR ' || em_check.enquote_name(l_object_name);
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('ERROR CREATING PUBLIC SYNONYM ' ||
crec.object_name);
-- continue creating other public synonyms
END;
END LOOP;
END create_sdk_synonyms;
PROCEDURE grant_core_sdk
(new_user_name_in VARCHAR2)
IS
l_current_user VARCHAR2(256) := MGMT_USER.GET_CURRENT_EM_USER;
l_sdk_list EM_SDK_COMPS;
l_new_user_name_in VARCHAR2(30) := new_user_name_in;
BEGIN
-- Ensure that the caller is a super-user.
IF MGMT_USER.has_priv(l_current_user, 'SUPER_USER') = 0 THEN
raise_application_error(MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR,
'Only superusers can use this procedure');
END IF;
COMMIT;
l_sdk_list := get_sdk_list;
-- grant privileges for SDK tables/types/packages
FOR i IN 1..l_sdk_list.count LOOP
BEGIN
EXECUTE IMMEDIATE 'GRANT ' ||
em_check.simple_sql_name(l_sdk_list(i).grant_type) ||
' ON ' || em_check.enquote_name(l_sdk_list(i).name) ||
' TO ' || em_check.enquote_name(l_new_user_name_in) ||
' WITH GRANT OPTION';
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('ERROR GRANTING ' || SQLERRM);
-- Keep granting other privileges..
NULL;
END;
END LOOP;
-- Grant select privileges for views that start with MGMT$
FOR crec IN (SELECT object_name from all_objects
WHERE object_name like 'MGMT$%'
AND object_type='VIEW')
LOOP
BEGIN
EXECUTE IMMEDIATE 'GRANT SELECT ON ' ||
em_check.enquote_name(crec.object_name)||
' TO ' || em_check.enquote_name(l_new_user_name_in) ||
' WITH GRANT OPTION';
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('ERROR GRANTING SELECT ON VIEW ' || SQLERRM);
END;
END LOOP;
END grant_core_sdk;
--
-- This procedure will prepopulate partitions for the table specified to
-- number of days specified.
--
PROCEDURE add_partitions(v_table_name IN VARCHAR2,
v_max_days IN PLS_INTEGER,
v_day_partitions IN BOOLEAN) IS
CURSOR max_timestamp_cursor (c_table_name VARCHAR2) IS
SELECT MAX(TO_DATE(PARTITION_NAME,'YYYY-MM-DD HH24:MI'))
FROM USER_TAB_PARTITIONS
WHERE TABLE_NAME = UPPER(c_table_name);
v_maxPartition DATE;
v_partitionDate DATE;
v_tempDate DATE;
v_partitionAdded BOOLEAN := FALSE;
v_newMaxDate DATE := TRUNC(SYSDATE+v_max_days,'DD');
v_daysBetween PLS_INTEGER := 0;
v_startDay PLS_INTEGER := 1;
v_starthour PLS_INTEGER := 0;
can_not_access_overflow_table EXCEPTION;
PRAGMA EXCEPTION_INIT(can_not_access_overflow_table, -25191);
BEGIN
DBMS_APPLICATION_INFO.SET_MODULE(
module_name => 'Oracle Enterprise Manager.Add Partitions',
action_name => 'start');
IF NOT (PARTITIONS_ENABLED(v_table_name)) THEN
RETURN;
END IF;
OPEN max_timestamp_cursor(v_table_name);
FETCH max_timestamp_cursor INTO v_maxPartition;
CLOSE max_timestamp_cursor;
IF v_day_partitions THEN
v_daysBetween := ROUND((v_newMaxDate - v_maxPartition),0);
ELSE
v_daysBetween := CEIL(v_newMaxDate-(1/24)-v_maxPartition) ;
-- if the last partition before is not 23:00 hours, then
-- start partition creation from the next hour
-- from previous date
IF to_number(to_char(v_maxPartition,'HH24')) != 23
THEN
v_maxPartition := v_maxPartition -1 ;
v_startHour := to_number(to_char(v_maxPartition,'HH24'))+1;
END IF ;
END IF ;
--
-- This loop creates the new partitions, if necessary.
--
FOR x IN v_startDay..v_daysBetween LOOP
v_partitionDate := TRUNC(v_maxPartition+x, 'DD');
--
-- The table is partitioned by hours.
--
IF NOT (v_day_partitions) THEN
FOR y IN v_startHour..23 LOOP
v_tempDate := v_partitionDate + (y/24);
EXECUTE IMMEDIATE 'ALTER TABLE ' ||
EM_CHECK.enquote_name(v_table_name) ||
' ADD PARTITION ' ||
EM_CHECK.enquote_name(TO_CHAR(v_tempDate, 'YYYY-MM-DD HH24:MI')) ||
' VALUES LESS THAN (TO_DATE(' ||
EM_CHECK.ENQUOTE_LITERAL(TO_CHAR(v_tempDate, 'YYYY-MM-DD HH24:MI')) ||
', ''YYYY-MM-DD HH24:MI''))';
END LOOP;
-- for the next day onwards, start from 0
v_startHour := 0 ;
ELSE -- The table is partitioned by whole days.
EXECUTE IMMEDIATE 'ALTER TABLE ' ||
EM_CHECK.ENQUOTE_NAME(v_table_name)||
' ADD PARTITION ' ||
EM_CHECK.ENQUOTE_NAME(TO_CHAR(v_partitionDate, 'YYYY-MM-DD HH24:MI')) ||
' VALUES LESS THAN (TO_DATE(' ||
EM_CHECK.ENQUOTE_LITERAL(TO_CHAR(v_partitionDate, 'YYYY-MM-DD HH24:MI')) ||
', ''YYYY-MM-DD HH24:MI''))';
END IF;
v_partitionAdded := TRUE;
END LOOP; -- End v_daysBetween LOOP
DBMS_APPLICATION_INFO.SET_MODULE(
module_name => ' ',
action_name => ' ');
EXCEPTION
WHEN OTHERS THEN
IF max_timestamp_cursor%ISOPEN THEN
CLOSE max_timestamp_cursor;
END IF;
p_ErrMsg := SUBSTR(SQLERRM, 1, 2048);
DBMS_APPLICATION_INFO.READ_MODULE(p_Module,p_Action);
MGMT_LOG.LOG_ERROR('MAINT', null, 'Error during ' || p_Module || ' : ' ||
p_ErrMsg,p_Action);
END ADD_PARTITIONS;
--
-- This procedure will drop any partitions for the input table that
-- are older than the input number of days from the current day.
--
PROCEDURE DROP_PARTITIONS (v_table_name IN VARCHAR2,
v_retention_days IN PLS_INTEGER) IS
CURSOR old_partition_cursor (c_table_name VARCHAR2, c_keep_date DATE) IS
SELECT PARTITION_NAME
FROM USER_TAB_PARTITIONS
WHERE TABLE_NAME = UPPER(c_table_name)
AND PARTITION_NAME < TO_CHAR(c_keep_date,'YYYY-MM-DD HH24:MI')
ORDER BY PARTITION_NAME DESC;
v_partitionDate DATE;
v_keepDate DATE;
v_part_names mgmt_medium_string_table := mgmt_medium_string_table() ;
BEGIN
v_keepDate := TRUNC((SYSDATE - v_retention_days), 'HH24');
IF NOT (PARTITIONS_ENABLED(v_table_name)) THEN
RETURN;
END IF;
-- Doing bulk collect up front to avoid snapshot too old
OPEN old_partition_cursor(v_table_name,v_keepDate) ;
FETCH old_partition_cursor BULK COLLECT INTO v_part_names ;
CLOSE old_partition_cursor ;
IF v_part_names IS NULL or v_part_names.COUNT = 0
THEN
RETURN ;
END IF ;
FOR part_rec IN v_part_names.FIRST..v_part_names.LAST
LOOP
EXECUTE IMMEDIATE 'ALTER TABLE '||
EM_CHECK.ENQUOTE_NAME(v_table_name)
||' DROP PARTITION ' ||
EM_CHECK.ENQUOTE_NAME(v_part_names(part_rec),FALSE) ;
END LOOP;
EXCEPTION
WHEN OTHERS THEN
p_ErrMsg := SUBSTR(SQLERRM, 1, 2048);
DBMS_APPLICATION_INFO.READ_MODULE(p_Module,p_Action);
MGMT_LOG.LOG_ERROR('MAINT', null, 'Error during ' || p_Module || ' : ' ||
p_ErrMsg,p_Action);
END DROP_PARTITIONS ;
--
-- This manual procedure will drop any partitions for the partitioned base
-- tables that are older than the keep dates. It is expected that the central
-- OMS(s) will be down and the central repository will be quiet before and
-- during the the execution of this procedure.
--
-- Starting 102DB, we do not need to stop job before dropping
-- partition. We would be calling this from analyze_emd_schema to drop partition
-- with p_stop_job set to FALSE, if DB version is >= 10.2
PROCEDURE PARTITION_MAINTENANCE
(
p_stop_job BOOLEAN DEFAULT TRUE
) IS
BEGIN
EMD_MAINT_UTIL.PARTITION_MAINTENANCE(p_stop_job) ;
END PARTITION_MAINTENANCE;
--
-- This procedure will truncate any partitions for the input table that
-- are older than the input number of days from the current day.
--
PROCEDURE TRUNCATE_PARTITIONS (v_table_name IN VARCHAR2,
v_retention_days IN PLS_INTEGER) IS
CURSOR old_partition_cursor (c_table_name VARCHAR2, c_keep_date DATE,
v_last_partition VARCHAR2) IS
SELECT PARTITION_NAME
FROM USER_TAB_PARTITIONS
WHERE TABLE_NAME = UPPER(c_table_name)
AND PARTITION_NAME < TO_CHAR(c_keep_date,'YYYY-MM-DD HH24:MI')
AND ( v_last_partition IS NULL OR
PARTITION_NAME > v_last_partition )
ORDER BY PARTITION_NAME ;
v_partitionDate DATE;
v_keepDate DATE;
v_last_partition VARCHAR2(256) ;
v_curr_partition VARCHAR2(256) ;
v_part_names mgmt_medium_string_table := mgmt_medium_string_table() ;
BEGIN
v_keepDate := TRUNC((SYSDATE - v_retention_days), 'HH24');
IF NOT (PARTITIONS_ENABLED(v_table_name)) THEN
RETURN;
END IF;
BEGIN
SELECT parameter_value
INTO v_last_partition
FROM mgmt_parameters
WHERE parameter_name= v_table_name||g_trunc_suffix ;
EXCEPTION
WHEN NO_DATA_FOUND THEN NULL ;
END ;
-- Doing bulk collect up front to avoid snapshot too old
OPEN old_partition_cursor(v_table_name,v_keepDate,v_last_partition) ;
FETCH old_partition_cursor BULK COLLECT INTO v_part_names ;
CLOSE old_partition_cursor ;
IF v_part_names IS NULL or v_part_names.COUNT = 0
THEN
RETURN ;
END IF ;
FOR part_rec IN v_part_names.FIRST..v_part_names.LAST
LOOP
EXECUTE IMMEDIATE 'ALTER TABLE '|| EM_CHECK.ENQUOTE_NAME(v_table_name)
||' TRUNCATE PARTITION ' ||
EM_CHECK.ENQUOTE_NAME(v_part_names(part_rec)) || ' DROP STORAGE';
v_curr_partition := v_part_names(part_rec) ;
END LOOP;
upd_trunc_partition(v_table_name,v_curr_partition) ;
EXCEPTION
WHEN OTHERS THEN
p_ErrMsg := SUBSTR(SQLERRM, 1, 2048);
DBMS_APPLICATION_INFO.READ_MODULE(p_Module,p_Action);
MGMT_LOG.LOG_ERROR('MAINT', null, 'Error during ' || p_Module || ' : ' ||
p_ErrMsg,p_Action);
END TRUNCATE_PARTITIONS;
--
-- Determine whether or not partitioning is in use for the EM repository.
-- Returns true if partitions enabled, false otherwise.
--
FUNCTION PARTITIONS_ENABLED(v_table_name IN VARCHAR2) RETURN BOOLEAN IS
v_partitioned VARCHAR2(3);
BEGIN
RETURN(EMD_MAINT_UTIL.PARTITIONS_ENABLED(v_table_name)) ;
END PARTITIONS_ENABLED;
--
-- Determine the database version of the repository.
-- Returns true if the rep database version is higher than 9, false otherwise.
-- Since the earliest repository for this version of EM repository is 9
-- (lowest supported version) all we need to do is verify if the repository
-- is v9 or not. If not, it has to be 10g or higher.
--
FUNCTION REPOSITORY_DB_V9 RETURN BOOLEAN IS
v_version VARCHAR2(3);
BEGIN
--
-- Get the first digit of the db version from the v$instance table.
--
SELECT substr(version,1,1) INTO v_version
FROM v$instance;
IF v_version = '9' THEN
RETURN TRUE;
ELSE
RETURN FALSE;
END IF;
END REPOSITORY_DB_V9;
--
-- Returns TRUE of the DB version is 9.0 or 9.1 ELSE FALSE
--
FUNCTION REPOSITORY_DB_V91 RETURN BOOLEAN IS
v_version VARCHAR2(3);
v_minor_version VARCHAR2(3) ;
BEGIN
--
-- Get the first/third digit of the db version from the v$instance table.
-- If version is 9, then the 3rd digit would be 0,1 or 2, if version is 10
-- then we do not care about 3rd digit
--
SELECT substr(version,1,1) ,
substr(version,3,1)
INTO v_version,
v_minor_version
FROM v$instance;
IF v_version = '9' AND v_minor_version IN ('0','1')
THEN
RETURN TRUE;
ELSE
RETURN FALSE;
END IF;
END REPOSITORY_DB_V91;
--
-- Returns TRUE of the DB version is 10
--
FUNCTION REPOSITORY_DB_V10 RETURN BOOLEAN IS
v_version VARCHAR2(3);
BEGIN
--
-- Get the first two/fourth digit of the db version from the v$instance table.
--
SELECT substr(version,1,2)
INTO v_version
FROM v$instance;
IF (v_version = 10) THEN
RETURN TRUE;
ELSE
RETURN FALSE;
END IF;
END REPOSITORY_DB_V10;
--
-- Returns TRUE of the DB version is 10.2 or higher
--
FUNCTION REPOSITORY_DB_V102 RETURN BOOLEAN IS
v_version VARCHAR2(3);
v_minor_version VARCHAR2(3) ;
BEGIN
--
-- Get the first two/fourth digit of the db version from the v$instance table.
--
SELECT substr(version,1,2) ,
substr(version,4,1)
INTO v_version,
v_minor_version
FROM v$instance;
IF (v_version > 10) OR (v_version = '10' AND v_minor_version > 1) THEN
RETURN TRUE;
ELSE
RETURN FALSE;
END IF;
END REPOSITORY_DB_V102;
--
-- Procedure to compress indexes.
--
-- Parameters
-- rebuild_index_name - name of index to rebuild
-- rebuild_prefix_length - prefixe length to compress
-- do_online - do it online or not
--
-- If the index is already compressed with the given prefix length the procedure return
-- without atempting to compress the index.
--
-- The procedure works with IOT's. It will figure out what hte table name is and move it.
--
PROCEDURE compress_index(rebuild_index_name VARCHAR2, rebuild_prefix_length NUMBER,
do_online BOOLEAN) IS
current_compression VARCHAR(8);
current_prefix_length NUMBER;
current_index_type VARCHAR2(32);
current_table_name VARCHAR2(32);
alter_sql_stmt VARCHAR(128);
BEGIN
SELECT index_type, table_name, compression, NVL(prefix_length, 0)
INTO current_index_type, current_table_name, current_compression,
current_prefix_length
FROM user_indexes WHERE index_name = UPPER(rebuild_index_name);
-- if index is already compressed correctly return
IF rebuild_prefix_length = current_prefix_length THEN
RETURN;
END IF;
IF current_index_type = 'IOT - TOP' THEN
--Temporarily returning due to Bug:4527081
RETURN ;
-- if it is an IOT move the base table
alter_sql_stmt := 'ALTER TABLE ' ||
EM_CHECK.ENQUOTE_NAME(current_table_name)
|| ' MOVE ';
ELSE
alter_sql_stmt := 'ALTER INDEX ' ||
EM_CHECK.ENQUOTE_NAME(rebuild_index_name) || ' REBUILD ';
END IF;
IF do_online = TRUE THEN
alter_sql_stmt := alter_sql_stmt || 'ONLINE ';
END IF;
-- if prefix length is 0 uncompress table
IF rebuild_prefix_length = 0 THEN
alter_sql_stmt := alter_sql_stmt || 'NOCOMPRESS';
ELSE
alter_sql_stmt := alter_sql_stmt || 'COMPRESS ' || rebuild_prefix_length;
END IF;
EXECUTE IMMEDIATE alter_sql_stmt;
EXCEPTION
WHEN NO_DATA_FOUND THEN
MGMT_LOG.LOG_ERROR('COMPRESS INDEX', null, 'Index ' || rebuild_index_name
|| ' does not exist');
WHEN OTHERS THEN
MGMT_LOG.LOG_ERROR('COMPRESS INDEX', null, 'Error compressing index ' ||
rebuild_index_name || ' Error: ' || SUBSTR(SQLERRM, 1, 1600));
END;
PROCEDURE cleanup_deleted_targets
IS
BEGIN
-- Delete all those records where delete complete time < SYSDATE - 5
-- delete in batch of 5000
DELETE
FROM MGMT_TARGETS_DELETE
WHERE delete_complete_time < (SYSDATE - 5)
AND ROWNUM < 5001;
WHILE (SQL%ROWCOUNT = 5000)
LOOP
COMMIT;
DELETE
FROM MGMT_TARGETS_DELETE
WHERE delete_complete_time < (SYSDATE - 5)
AND ROWNUM < 5001;
END LOOP;
COMMIT;
END cleanup_deleted_targets;
-- set the reschedule execs on new jobtype flag in MGMT_PARAMETERS
PROCEDURE set_reschd_on_new_jobtype(p_enable BOOLEAN DEFAULT TRUE) IS
l_value MGMT_PARAMETERS.parameter_value%TYPE := 'TRUE';
BEGIN
IF NOT p_enable THEN
l_value := 'FALSE';
END IF;
INSERT INTO MGMT_PARAMETERS
(parameter_name, parameter_value, parameter_comment, internal_flag)
VALUES (RESCHEDULE_ON_NEW_JOBTYPE, l_value, RESCHEDULE_ON_NEW_JOBTYPE_CMT, 1);
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
UPDATE MGMT_PARAMETERS
SET parameter_value = l_value
WHERE parameter_name = RESCHEDULE_ON_NEW_JOBTYPE;
END set_reschd_on_new_jobtype;
-- check if central mode and set reschedule execs on new jobtype flag
-- accordingly: central -> TRUE, others -> FALSE
PROCEDURE calc_reschd_on_new_jobtype IS
BEGIN
set_reschd_on_new_jobtype(is_central_mode > 0);
END calc_reschd_on_new_jobtype;
-- remove the reschedule execs on new jobtype flag
PROCEDURE clear_reschd_on_new_jobtype IS
BEGIN
DELETE FROM MGMT_PARAMETERS
WHERE parameter_name = RESCHEDULE_ON_NEW_JOBTYPE;
END clear_reschd_on_new_jobtype;
-- return whether the reschedule execs on new jobtype flag is set or not
FUNCTION should_reschd_on_new_jobtype RETURN BOOLEAN IS
l_value MGMT_PARAMETERS.parameter_value%TYPE := 'TRUE';
BEGIN
BEGIN
SELECT parameter_value INTO l_value
FROM MGMT_PARAMETERS
WHERE parameter_name = RESCHEDULE_ON_NEW_JOBTYPE;
EXCEPTION
WHEN NO_DATA_FOUND THEN
NULL;
END;
-- TRUE is default, so check only if value is not FALSE
RETURN (l_value != 'FALSE');
END should_reschd_on_new_jobtype;
end emd_maintenance;
/
show errors;