Sunday 30 March 2014

Rapid Growth of SYSAUX Tablespace


Oracle 10g onwards, The SYSAUX an auxiliary tablespace to the SYSTEM tablespace created in your database.
Some database components that formerly created and used separate tablespaces now occupy the SYSAUX tablespace.
Below table shows the components that uses the SYSAUX tablespace as their default tablespace and the tablespace in which they were stored in earlier releases.

Component Using SYSAUX
Tablespace in Earlier Releases
Analytical Workspace Object Table
SYSTEM
Enterprise Manager Repository
OEM_REPOSITORY
LogMiner
SYSTEM
Logical Standby
SYSTEM
OLAP API History Tables
CWMLITE
Oracle Data Mining
ODM
Oracle Spatial
SYSTEM
Oracle Streams
SYSTEM
Oracle Text
DRSYS
Oracle Ultra Search
DRSYS
Oracle interMedia ORDPLUGINS Components
SYSTEM
Oracle interMedia ORDSYS Components
SYSTEM
Oracle interMedia SI_INFORMTN_SCHEMA Components
SYSTEM
Server Manageability Components

Statspack Repository
User-defined
Oracle Scheduler

Workspace Manager
SYSTEM

The statistics are stored in the data dictionary. Now whenever statistics in the dictionary are modified, old versions of statistics are saved automatically for future restoring. This history information is stored in SYSAUX tablespace and tables involved in this are as below:
WRI$_OPTSTAT_OPR                    
WRI$_OPTSTAT_AUX_HISTORY                
WRI$_OPTSTAT_TAB_HISTORY                
WRI$_OPTSTAT_IND_HISTORY                
WRI$_OPTSTAT_HISTGRM_HISTORY            
WRI$_OPTSTAT_HISTHEAD_HISTORY         
 
By default, the MMON performs the automatic purge that removes all stats history older than the following:
* current time - statistics history retention (by default 31 days)
* time of recent analyze in the system - 1

MMON performs the purge of the optimizer stats history automatically, but it has an internal limit of 5 minutes to perform this job.MMON will do this activity once in 24 hrs. If the operation takes more than 5 minutes, then it is aborted and stats not purged. No trace or alert message is reported. Because of this, as time elapse more data will be accommodated in above tables.
Statistics history retention is configurable using the ALTER_STATS_HISTORY_RETENTION procedure.


I have an Oracle 11g R2 database where I noticed the SYSAUX tablespace was growing larger every day.   After running $ORACLE_HOME/rdbms/admin/awrinfo.sql (Doc ID 1292724.1),
I found the largest consumer to be SM/OPTSTAT(9.5GB) and SM/AWR(1GB) as shown below.

  (1b) SYSAUX occupants space usage (v$sysaux_occupants)
********************************************************
|
| Occupant Name    Schema Name     Space Usage
| -------------------- -------------------- ----------------
| SM/OPTSTAT           SYS                        9,415.1 MB
| SM/AWR                    SYS                        1,005.3 MB
| SM/ADVISOR           SYS                        188.5 MB
| XDB                             XDB                       125.8 MB
| EM                              SYSMAN                 82.3 MB


(3b) Space usage within AWR Components (> 500K)
**********************************
COMP        MB     SEGMENT_NAME - % SPACE_USED                                                                                            
SEGMENT_TYPE
--------- --------- ---------------------------------------------------------------------
------------------------------  ---------------
ASH           382.0  WRH$_ACTIVE_SESSION_HISTORY.WRH$_ACTIVE_3563904870_4350 -  97%  TABLE PARTITION
ASH            38.0  WRH$_ACTIVE_SESSION_HISTORY_PK.WRH$_ACTIVE_3563904870_4350 - 98%  INDEX PARTITION

(4) Space usage by non-AWR components (> 500K)
**********************************

COMPONENT        MB SEGMENT_NAME                                                          SEGMENT_TYPE
--------- --------- --------------------------------------------------------------------- ---------------
NON_AWR     3,220.0 SYS.I_WRI$_OPTSTAT_HH_OBJ_ICOL_ST                    INDEX
NON_AWR     2,905.0 SYS.WRI$_OPTSTAT_HISTHEAD_HISTORY                TABLE
NON_AWR     1,930.0 SYS.I_WRI$_OPTSTAT_HH_ST                                          INDEX
NON_AWR       448.0 SYS.I_WRI$_OPTSTAT_H_OBJ#_ICOL#_ST                   INDEX
NON_AWR       296.0 SYS.WRI$_OPTSTAT_HISTGRM_HISTORY                    TABLE
NON_AWR       232.0 SYS.I_WRI$_OPTSTAT_H_ST                                               INDEX
NON_AWR       168.0 SYS.I_WRI$_OPTSTAT_TAB_OBJ#_ST                             INDEX
NON_AWR       141.0 SYS.SYS_LOB0000006306C00038$$                               LOBSEGMENT
NON_AWR       104.0 SYS.I_WRI$_OPTSTAT_TAB_ST                                          INDEX


To resolve this:

1. Turn off the Autoextend on the SYSAUX at the earliest to ensure that the tablespace doesn’t grow out of bounds and finally become complete unmanageable.

2. Manually purge old statistics using DBMS_STATS.purge_stats as below

Find out your present retention value using the below statement
SQL> select dbms_stats.get_stats_history_retention from dual;

GET_STATS_HISTORY_RETENTION
---------------------------
                         31

Find out the oldest statistics history using below statement(Shows available stats that have not been purged):
 

SQL> select dbms_stats.get_stats_history_availability from dual;

GET_STATS_HISTORY_AVAILABILITY
---------------------------------------------------------------------------
05-MAR-14 05.31.04.053232000 AM +05:30

Set retention of old stats to less number of days. I set here it to 10 days as below.

SQL> exec dbms_stats.alter_stats_history_retention(10);

PL/SQL procedure successfully completed.

SQL> select dbms_stats.get_stats_history_retention from dual;

GET_STATS_HISTORY_RETENTION
---------------------------
                         10
Purge stats older than 10 days. Best to do this in stages if there is a lot of data (sysdate-10) since it consumes more resources. Do this during less activity on the database. This purge will delete data from WRI$ tables.

Below command will purge stats which are older than 10 days.

SQL> exec dbms_stats.purge_stats(sysdate-10);

PL/SQL procedure successfully completed.

Below command shows available stats that have not been purged

SQL> select dbms_stats.get_stats_history_availability from dual;

GET_STATS_HISTORY_AVAILABILITY
---------------------------------------------------------------------------
30-MAR-14 09.46.46.000000000 AM +05:30

Once purge is done, reorg these tables to release space to the database. Refer ID 1271178.1 for more details.


Saturday 22 February 2014

Impdp does not created user/schema

Until  now my understanding for EXPDP/IMPDP was that if the user performing import has 'IMPORT FULL DATABASE' privilege, it'll create the users/schemas in the target database. I needed to export (expdp) schema from one machine and import (impdp) it to another machine. I just wanted  impdp to create schema on target database.

While doing  import  i encountered error
$ impdp system/oracle123 directory=TEST_DIR dumpfile=test.dmp logfile=impdptest.log
 .......
Starting "SYSTEM"."SYS_IMPORT_FULL_01":  system/******** directory=TEST_DIR dumpfile=USR_TEST.dmp logfile=impdpUSR_TEST.log
Processing object type SCHEMA_EXPORT/PRE_SCHEMA/PROCACT_SCHEMA
ORA-39083: Object type PROCACT_SCHEMA failed to create with error:
ORA-31625: Schema USR_TEST is needed to import this object, but is unaccessible
ORA-01435: user does not exist
Failing sql is:
BEGIN
sys.dbms_logrep_imp.instantiate_schema(schema_name=>SYS_CONTEXT('USERENV','CURRENT_SCHEMA'), export_db_name=>'XXX.YYY.COM', inst_scn=>'7788478540892');COMMIT; END;
Processing object type SCHEMA_EXPORT/TABLE/TABLE
ORA-39083: Object type TABLE:"USR_TEST"."TABLE1" failed to create with error:
ORA-01918: user 'USR_TEST' does not exist
Failing sql is:
CREATE TABLE "USR_TEST"."TABLE1" ("COLUMN1" VARCHAR2(20 BYTE) NOT NULL ENABLE, "COLUMN2" VARCHAR2(20 BYTE), "COLUMN3" VARCHAR2(20 BYTE)) SEGMENT CREATION IMMEDIATE PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAU
Processing object type SCHEMA_EXPORT/TABLE/INDEX/INDEX
Processing object type SCHEMA_EXPORT/TABLE/CONSTRAINT/CONSTRAINT
Job "SYSTEM"."SYS_IMPORT_FULL_01" completed with 2 error(s).
$

After reading some documents,blogs I discovered  that If  the schema you are importing to does not already exist, the import operation creates it, provided the dump file set contains the necessary CREATE USER metadata and you are importing with enough privileges.

Meaning the oracle user that exported the schema, should have had CREATE USER privilege.Export was done with user (USR_TEST) was a basic user and not DBA/create-user-privileged. 
Below query given result as.
SQL>  select  from  ROLE_SYS_PRIVS  where  PRIVILEGE = ’CREATE USER’ ;
ROLE                                              PRIVILEGE                     ADM
----------------------------           --------------------              ---
DBA                                               CREATE USER                 YES
IMP_FULL_DATABASE           CREATE USER                  NO
2 rows selected.
It means EXP_FULL_DATABAS role does not have create user privilege.

I did 'GRANT CREATE USER TO USR_TEST' here and  ran the export again and this time some additional "object types" were processed.
 when USR_TEST user didn't have 'CREATE USER' privilege:
 $ expdp USR_TEST/USR_TEST schemas=USR_TEST content=METADATA_ONLY directory=TEST_DIR dumpfile=USR_TEST.dmp logfile=expdpUSR_TEST.log
.......
Starting "USR_TEST"."SYS_EXPORT_SCHEMA_01":  USR_TEST/******** schemas=USR_TEST content=METADATA_ONLY directory=TEST_DIR dumpfile=USR_TEST.dmp logfile=expdpUSR_TEST.log
Processing object type SCHEMA_EXPORT/PRE_SCHEMA/PROCACT_SCHEMA
Processing object type SCHEMA_EXPORT/TABLE/TABLE
Processing object type SCHEMA_EXPORT/TABLE/COMMENT
Processing object type SCHEMA_EXPORT/TABLE/INDEX/INDEX
Processing object type SCHEMA_EXPORT/TABLE/CONSTRAINT/CONSTRAINT
Processing object type SCHEMA_EXPORT/TABLE/INDEX/STATISTICS/INDEX_STATISTICS
Master table "USR_TEST"."SYS_EXPORT_SCHEMA_01" successfully loaded/unloaded
******************************************************************************
.......


when USR_TEST user  have 'CREATE USER' privilege:
 $ expdp USR_TEST/USR_TEST schemas=USR_TEST content=METADATA_ONLY directory=TEST_DIR dumpfile=USR_TEST.dmp logfile=expdpUSR_TEST.log
.......
Starting "USR_TEST"."SYS_EXPORT_SCHEMA_01":  USR_TEST/******** schemas=USR_TEST content=METADATA_ONLY directory=TEST_DIR dumpfile=USR_TEST.dmp logfile=expdpUSR_TEST.log
Processing object type SCHEMA_EXPORT/USER
Processing object type SCHEMA_EXPORT/SYSTEM_GRANT
Processing object type SCHEMA_EXPORT/ROLE_GRANT
Processing object type SCHEMA_EXPORT/DEFAULT_ROLE
Processing object type SCHEMA_EXPORT/PRE_SCHEMA/PROCACT_SCHEMA
Processing object type SCHEMA_EXPORT/TABLE/TABLE
Processing object type SCHEMA_EXPORT/TABLE/COMMENT
Processing object type SCHEMA_EXPORT/TABLE/INDEX/INDEX
Processing object type SCHEMA_EXPORT/TABLE/CONSTRAINT/CONSTRAINT
Processing object type SCHEMA_EXPORT/TABLE/INDEX/STATISTICS/INDEX_STATISTICS
Master table "USR_TEST"."SYS_EXPORT_SCHEMA_01" successfully loaded/unloaded
******************************************************************************
.......

Note the Processing object type SCHEMA_EXPORT/USER, SCHEMA_EXPORT/SYSTEM_GRANT, SCHEMA_EXPORT/ROLE_GRANT, SCHEMA_EXPORT/DEFAULT_ROLE.

To avoid such situations always try to take the export using SYSTEM user.

Identify the Tablespace names from EXPDP dump file


 I got  request from development team to import some old data in UAT region.The expdp dump file received from backup team was without  log file and i have no access to the export file's source DB. I wanted to import that dumpfile into UAT DB and i do not know the tablespace names required to do so.

Solution:
Use the sqlfile option present in impdp utility. This option will write all the SQL DDL to a specified file instead of executing them.

$ impdp scott/tiger directory=exp_dir dumpfile=scott.dmp sqlfile=script.sql

Import: Release 11.1.0.7.0 - 64bit Production on Tuesday, 20 February, 2014 21:34:36

Copyright (c) 2003, 2007, Oracle.  All rights reserved.

Connected to: Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
Master table "SCOTT"."SYS_SQL_FILE_FULL_01" successfully loaded/unloaded
Starting "SCOTT"."SYS_SQL_FILE_FULL_01":  scott/******** directory=exp_dir dumpfile=scott.dmp sqlfile=script.sql
Processing object type SCHEMA_EXPORT/USER
Processing object type SCHEMA_EXPORT/SYSTEM_GRANT
Processing object type SCHEMA_EXPORT/ROLE_GRANT
Processing object type SCHEMA_EXPORT/DEFAULT_ROLE
Processing object type SCHEMA_EXPORT/PRE_SCHEMA/PROCACT_SCHEMA
Processing object type SCHEMA_EXPORT/SEQUENCE/SEQUENCE
Processing object type SCHEMA_EXPORT/TABLE/TABLE
Processing object type SCHEMA_EXPORT/TABLE/INDEX/INDEX
Processing object type SCHEMA_EXPORT/TABLE/CONSTRAINT/CONSTRAINT
Processing object type SCHEMA_EXPORT/TABLE/INDEX/STATISTICS/INDEX_STATISTICS
Processing object type SCHEMA_EXPORT/PROCEDURE/PROCEDURE
Processing object type SCHEMA_EXPORT/PROCEDURE/ALTER_PROCEDURE
Processing object type SCHEMA_EXPORT/TABLE/TRIGGER
Processing object type SCHEMA_EXPORT/TABLE/STATISTICS/TABLE_STATISTICS
Job "SCOTT"."SYS_SQL_FILE_FULL_01" successfully completed at 21:34:53

The content of the scripts.sql file would be like this.
-- CONNECT SCOTT
ALTER SESSION SET EDITION = "ORA$BASE";
-- new object type path: SCHEMA_EXPORT/USER
-- CONNECT SYSTEM
ALTER SESSION SET EDITION = "ORA$BASE";
 CREATE USER "SCOTT" IDENTIFIED BY VALUES 'S:D846EA3EB87287A3AED08AF38EB0B4F640F49A9A4A972108BF3917B769;DB1B37F84BDF15E6'
      DEFAULT TABLESPACE "USERS"
      TEMPORARY TABLESPACE "TEMP";

-- new object type path: SCHEMA_EXPORT/SYSTEM_GRANT
GRANT UNLIMITED TABLESPACE TO "SCOTT";

-- new object type path: SCHEMA_EXPORT/ROLE_GRANT
 GRANT "DBA" TO "SCOTT";

-- new object type path: SCHEMA_EXPORT/DEFAULT_ROLE
 ALTER USER "SCOTT" DEFAULT ROLE ALL;

-- new object type path: SCHEMA_EXPORT/PRE_SCHEMA/PROCACT_SCHEMA
-- CONNECT SCOTT
ALTER SESSION SET EDITION = "ORA$BASE";

BEGIN
sys.dbms_logrep_imp.instantiate_schema(schema_name=>SYS_CONTEXT('USERENV','CURRENT_SCHEMA'), export_db_name=>'PROD9.DIAMOND.COM', inst_scn=>
'11626845804212');
COMMIT;
END;
/
 .
.
.
.
.
.


After finding all the required tablespaces i used REMAP_TABLESPACE  and then import the dump file .
One can manually create same  tablespaces and import the dump file. 


Wednesday 29 January 2014

ORA-01031: insufficient privileges to sys@standby as sysdba


The ORA-01031 is very generic error and normally users will receive this error when users don’t have appropriate privilege.

$oerr ora 01031
01031, 00000, "insufficient privileges"
// *Cause: An attempt was made to change the current username or password
//         without the appropriate privilege. This error also occurs if
//         attempting to install a database without the necessary operating
//         system privileges.
//         When Trusted Oracle is configure in DBMS MAC, this error may occur
//         if the user was granted the necessary privilege at a higher label
//         than the current login.
// *Action: Ask the database administrator to perform the operation or grant
//          the required privileges.
//          For Trusted Oracle users getting this error although granted the
//          the appropriate privilege at a higher label, ask the database
//          administrator to regrant the privilege at the appropriate label.

On standby
$ sqlplus
Enter user-name: /as sysdba

Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL>


From Primary or Standby
$ sqlplus
 

Enter user-name: sys@standby as sysdba
Enter password:
ERROR:
ORA-01031: insufficient privileges


Error in alert log of PRIMARY database

Error 1034 received logging on to the standby
PING[ARC0]: Heartbeat failed to connect to standby 'STANDBY'. Error is 1034.
Error 1034 received logging on to the standby
FAL[server, ARC2]: Error 1034 creating remote archivelog file 'STANDBY'

 Metalink notes for insufficient privileges  as sysdba
OERR: ORA 1031 "insufficient privileges" [ID 18622.1]
Troubleshooting ORA-1031: Insufficient Privileges While Connecting As SYSDBA [ID 730067.1]

But

Original problem in my case  was with listener file. Instance name is crated in small letter but in listener.ora sid given in CAPS it caused the problem. After changing sid in listner.ora it is working fine.

Saturday 25 January 2014

Creating Redo Log Groups and Members

Create all required groups and members of redo log files during database creation. However, there are situations where you might want to create additional groups or members.

Creating Redo Log Groups
To create new redo log groups and members, you must have the ALTER DATABASE system privilege.
To create a new group of redo log files, use the SQL statement ALTER DATABASE with the ADD LOGFILE clause.

The following statement adds a new group of redo logs to the database:
 ALTER DATABASE
  ADD LOGFILE ('/oracle/dbs/log1c.rdo', '/oracle/dbs/log2c.rdo') SIZE 500K;

You can also specify the number that identifies the group using the GROUP clause:
ALTER DATABASE
  ADD LOGFILE GROUP 10 ('/oracle/dbs/log1c.rdo', '/oracle/dbs/log2c.rdo')
      SIZE 500K;

Using group numbers can make administering redo log groups easier. However, the group number must be between 1 and MAXLOGFILES.

In some cases, it might not be necessary to create a complete group of redo log files. A group could already exist, but not be complete because one or more members of the group were dropped (for example, because of a disk failure). In this case, you can add new members to an existing group.

Creating Redo Log Members
To create new redo log members for an existing group, use the SQL statement ALTER DATABASE with the ADD LOGFILE MEMBER clause.
The following statement adds a new redo log member to redo log group number 2:

ALTER DATABASE ADD LOGFILE MEMBER '/oracle/dbs/log2b.rdo' TO GROUP 2;

Notice that filenames must be specified, but sizes need not be. The size of the new members is determined from the size of the existing members of the group.
When using the ALTER DATABASE statement, you can alternatively identify the target group by specifying all of the other members of the group in the TO clause, as shown in the following example:

ALTER DATABASE ADD LOGFILE MEMBER '/oracle/dbs/log2c.rdo'
    TO ('/oracle/dbs/log2a.rdo', '/oracle/dbs/log2b.rdo');

Note:
Fully specify the filenames of new log members to indicate where the operating system files should be created. Otherwise, the files will be created in either the default or current directory of the database server, depending upon your operating system. You may also note that the status of the new log member is shown as INVALID. This is normal and it will change to active (blank) when it is first used.

Multiplex & Move Oracle control files to different directory


1, shutdown database.
shutdown immediate;
2, edit Oracle init.ora file, e.g., C:\Oracle\10g\database\inittest.ora, find the line with control file location, change the location from old directory to new directory, e.g.:

         OLD:
         control_files=("H:\Oradata\test\control01.ctl")

         NEW:
         control_files=("I:\Oradata\test\control01.ctl",  "J:\Oradata\test\control02.ctl", "K:\Oradata\test\control03.ctl")

save init.ora file.

3, create spfile from pfile:
create spfile from pfile;
4, Copy control files from old directory to new directory

    copy H:\Oradata\test\control01.ctl I:\Oradata\test\control01.ctl
    copy H:\Oradata\test\control01.ctl J:\Oradata\test\ control02.ctl
    copy H:\Oradata\test\control01.ctl K:\Oradata\test\control03.ctl

5, startup database.
SQL> startup
ORACLE instance started.

Total System Global Area 1426063360 bytes
Fixed Size 2004264 bytes
Variable Size 352324312 bytes
Database Buffers 1056964608 bytes
Redo Buffers 14770176 bytes
Database mounted.
Database opened.
SQL>

Saturday 18 January 2014

Automate AWR Report Generation


By default snapshots of the relevant data are taken every hour and retained for 7 days. Most of the times database running in default AWR settings. DBA's generates the awr report when something  happened in their database or periodically to check if anything is wrong in databases

Some times databases are running smooth without any problems. Due to the default retention of AWR snapshot setting we may loose some good information about database.When problem occurs in the database we may need to compare the bad time report (when problem occurred) vs good time report (when db running smooth). In this case we don't have any information about database when running without any problem or we don't have same period snapshot AWR report to compare it with current reports.

To avoid this situation DBA can automate the AWR reports generation using below script.
It automatically generates the awr report of last one hour and no manual intervention is required by DBAs onece it is schedule in cronjob

Crontab Entry

05 * * * * sh /oracle/AWR/generate_awr.sh ORCL  >> /oracle/AWR/awr_rpt.log

Cronjob to be executed every hour at 05 mins on daily basis  and shell output is redirected to log file

SCRIPT STARTS HERE
##############################################################################
1 ) generate_awr.sh

#------------------------------------------------------------------------------
#!/usr/bin/ksh
# File: generate_awr.sh
# Description:
# shell script to run under the UNIX "cron" utility to automatically generate Oracle "AWR" reports in HTML   against the database accessed via passed parameter
# Usage :
# sh generate_awr.sh oracle_sid
# Parameters:
#  One parameter to be  passed. Oracle_sid to be passed as parameter.
#  Environment variables are captured from /etc/oratab entry.

dbSid=${1}
export oraSid=${dbSid}
#echo $oraSid
export ORACLE_SID=`grep "$oraSid:" /etc/oratab|cut -d: -f1 -s`
export ORACLE_HOME=`grep "$oraSid:" /etc/oratab|cut -d: -f2 -s`
export ORAENV_ASK=NO
#. oraenv ${dbSid}
unset TWO_TASK
export PATH=$PATH:$ORACLE_HOME/bin

#echo $ORACLE_SID
#echo $ORACLE_HOME
#echo $PATH

sqlplus -S " / as sysdba" @/oracle/AWR/create_awr_report_for_database.sql

# Finish
#------------------------------------------------------------------------------



2) create_awr_report_for_database.sql

/* ---------------------------------------------------------------------------
Original script byhttp://damir-vadas.blogspot.in/2009/11/automated-awr-reports-in-oracle-10g11g.html

 Filename: create_awr_report_for_database.sql
 Purpose : In directory defined with v_dir, create awr reports for last one hour snapshots, so put in crontab  to run at every hour on daily basis

 Remarks : Run as privileged user

#  If No report generated in report folder (v_dir) create directory manually once before running the script.
 --------------------------------------------------------------------------- */
set serveroutput on
set linesize 166
set pagesize 600
set trimout on

DECLARE
   CURSOR c_instance
   IS
        SELECT   instance_number, instance_name
          FROM   gv$instance
      ORDER BY   1;

   c_dir CONSTANT   VARCHAR2 (256) := 'oracle/AWR';
   v_dir            VARCHAR2 (256) := 'oracle/AWR/daily_awr';
   v_dbid           v$database.dbid%TYPE;
   v_dbname         v$database.name%TYPE;
   v_inst_num       v$instance.instance_number%TYPE := 1;
   v_begin          NUMBER;
   v_end            NUMBER;
   v_start_date     VARCHAR2 (20);
   v_end_date       VARCHAR2 (20);
   v_options        NUMBER := 8;        -- 0=no options, 8=enable addm feature
   v_file           UTL_FILE.file_type;
   v_file_name      VARCHAR (50);
BEGIN
   -- get database id
   SELECT   dbid, name
     INTO   v_dbid, v_dbname
     FROM   v$database;

   -- get end snapshot id
   SELECT   MAX (snap_id)
     INTO   v_end
     FROM   dba_hist_snapshot
     WHERE  TO_CHAR (END_INTERVAL_TIME, 'yyyy/mm/dd hh24') <= to_char(sysdate,'yyyy/mm/dd hh24');

   DBMS_OUTPUT.put_line ('end snap_id ' || v_end);

   -- get start snapshot id
   SELECT   MAX (snap_id)
     INTO   v_begin
     FROM   dba_hist_snapshot
    WHERE   snap_id < v_end;

   DBMS_OUTPUT.put_line ('begin snap_id ' || v_begin);

   SELECT   TO_CHAR (END_INTERVAL_TIME, 'YYMMDD_HH24MI')
     INTO   v_start_date
     FROM   dba_hist_snapshot
    WHERE   snap_id = v_begin AND instance_number = v_inst_num;

   DBMS_OUTPUT.put_line ('v_start_date ' || v_start_date);

   SELECT   TO_CHAR (END_INTERVAL_TIME, 'HH24MI')
     INTO   v_end_date
     FROM   dba_hist_snapshot
    WHERE   snap_id = v_end AND instance_number = v_inst_num;

   DBMS_OUTPUT.put_line ('v_end_date ' || v_end_date);

   -- Thanx to Yu Denis Sun - we must have directory defined as v_dir value!
execute immediate('create or replace directory awrdir as '''||v_dir||'''');

   -- let's go to real work...write awrs to files...
   FOR v_instance IN c_instance
   LOOP
      DBMS_OUTPUT.put_line (
         'v_instance.instance_name:' || v_instance.instance_name
      );
      v_file :=
         UTL_FILE.fopen (
            'AWRDIR',
               'awr_'
            || v_instance.instance_name
            || '_'
            || v_instance.instance_number
            || '_'
            || v_start_date
            || '_'
            || v_end_date
            || '.html',
            'w',
            32767
         );

      FOR c_report
      IN (SELECT   output
            FROM   TABLE(DBMS_WORKLOAD_REPOSITORY.awr_report_html (
                            v_dbid,
                            v_instance.instance_number,
                            v_begin,
                            v_end,
                            v_options
                         )))
      LOOP
         UTL_FILE.PUT_LINE (v_file, c_report.output);
      END LOOP;

      UTL_FILE.fclose (v_file);
   END LOOP;

EXECUTE IMMEDIATE ('drop directory AWRDIR');
EXCEPTION
   WHEN OTHERS
   THEN
      DBMS_OUTPUT.PUT_LINE (SQLERRM);

      IF UTL_FILE.is_open (v_file)
      THEN
         UTL_FILE.fclose (v_file);
      END IF;

      BEGIN
    EXECUTE IMMEDIATE ('drop directory AWRDIR');
      EXCEPTION
         WHEN OTHERS
         THEN
            NULL;
      END;
END;
/
exit;

  ---------------------------------------------------------------------------





Total Pageviews