h1

What does the SQL92_SECURITY parameter actually do?

November 23, 2009

Whilst looking at our Grid Control I noticed that we had a few policy violations in the security configuration stating that SQL92_SECURITY=FALSE. These were against some of our older databases as we set it to true on all new builds. I thought I knew what this parameter did but had a look around and determined the following :-

It stops anyone being able to update or delete rows from a table owned by another user if you were using a where clause and did not have select on that table. Fair enough I thought, it sounds like it is some form of ANSI 92 standard and it is all a bit meaningless. I could not see what the issue was but I was intrigued as to why it was an Oracle security recommendation.

I set up the following test case on both a 10G and 11G database where SQL92_SECURITY was set to TRUE. Very simple but I had no failures other than the select statement which had insufficient privileges.

create user usera identified by usera;
create user userb identified by userb;

grant create session,create table to usera;
grant create session to userb;
alter user usera quota unlimited on users;
alter user userb quota unlimited on users;
show parameter sql92_security
connect usera/usera
create table tab1 as select * from all_objects where rownum <101;
select count(*) from tab1;
grant update,delete on tab1 to userb;

connect userb/userb
update usera.tab1 set object_type = 'WAS PACK' where object_type='PACKAGE';
commit;
select distinct status from usera.tab1;
prompt fails as no select privilege on usera.tab1
prompt SQL92 set to true and yet update is allowed ??
prompt now let's try a delete
delete from usera.tab1 where rownum <21;

prompt delete with a where clause works as well

select count(*) from
prompt end of case study

So what is all that about, where was I going wrong and why were my updates and deletes allowed when they shouldn’t have been.

This parameter is meant to prevent you from deleting a table when you specify a condition based on table’s columns. Conditions that are not checking the values stored in the table are allowed(rownum < X, etc.)

In my testcase I deleted the table rows without a condition which read one of the the tables columns. If instead of executing delete from usera.tab1 where rownum =21 I had executed delete from usera.tab1 where object_name = ‘TEST’; I would get an error.

The purpose of this parameter is to allow a user one to delete table data without giving them the possibility of guessing what values are stored in that table. Imagine that there is a table with contacts and I only have delete rights on that table. If I am able to delete the table with a condition based on table columns I can find out via multiple attempts the contents of the table. I can for example find out whether ‘John Smith’ is a contact or not :

SQL> delete from contacts where contact_first_name='John' and contact_family_name='Smith'; 

1 row deleted
SQL> rollback;
Rollback complete.

Since the row was deleted I know now that John Smith is a contact. Then I do a rollback of the transaction and the table is as it was before the delete. If the parameter is set to TRUE I cannot make use of this trick and I can only delete the rows blindly. I will be able to delete without knowing what I am going to delete.

Once I understood what could be done I understood the reason for the init.ora parameter to be enabled. However there is very little information out on the web which explains the reasons and that is why I think the parameter can be misunderstood.

Prior to enabling it on a database that is in use I would check that nobody had update or delete privileges ona table that they did not own where they did not have select privilege.

select *
from dba_tab_privs a
where privilege in ('UPDATE','DELETE')
and not exists (select null
                from   dba_tab_privs b
                where  privilege = 'SELECT'
                and    a.grantor = b.grantor
                and    a.grantee = b.grantee
                and    a.table_name = b.table_name);
h1

Maxing out CPUs – script

November 19, 2009

I have long subscribed to the  ORACLE-L mailing list  and I find it a great source of ideas and views on the management of Oracle databases. As a sidenote for anybody who used it in the past it seems to be much stronger now as a community than previously where there was too much RTFM and other flaming type responses.

In the last couple of days there has been a thread running entitled Stress my CPU’s started by Lee Robertson where he was asking for a way to ‘hammer the CPU’s on the box as we want to test dynamically allocating CPU’s from another partition to handle the increased workload’.

The strength of the list is that there were a number of quality responses but my hat goes off to Tom Dale for producing this gem

set serveroutput on

declare

l_job_out integer;

l_what dba_jobs.what%type;

l_cpus_to_hog CONSTANT integer :=4;

l_loop_count varchar2(10) := '500000000'; begin

/*

** Create some jobs to load the CPU

*/

for l_job in 1..l_cpus_to_hog loop

dbms_job.submit(

job => l_job_out

, what => 'declare a number := 1; begin for i in 1..'||l_loop_count||' loop a := ( a + i )/11; end loop; end;'

);

commit;

dbms_output.put_line( 'job - '|| l_job_out );

select what into l_what from dba_jobs where job = l_job_out;

dbms_output.put_line( 'what - '|| l_what );

end loop;

end;

/

Short, sweet and very effective. I will certainly be using it when I want to look at using resource management.

PS,  if you want to stop the jobs running, although they do finish in a few minutes using the default value of 500 million iterations, then use the following dynamic sql.

select 'execute dbms_job.remove('||job||');' from user_jobs where what like 'declare a number := 1%';

 

h1

Problems with SGA being a multiple of 4Gb (and high cpu count)

November 13, 2009

 We had a server  – HPUX IA64 – 11.1.0.6 where we increased the number of CPUs to 32 and upped memory to 96Gb. After some performance testing we tried to set the parameters as follows

 alter system set sga_target=20G scope=spfile sid=’*';

alter system set sga_max_size=20G scope=spfile sid=’*';

alter system set shared_pool_size=800M scope=spfile sid=’*';

alter system set shared_pool_reserved_size=80M scope=spfile sid=’*';

alter system set pga_aggregate_target=4G scope=spfile sid=’*';

We couldn’t start the database because of lack of memory and we saw ORA-04030 errors

 ORA-04030: out of process memory when trying to allocate 840 bytes (kgsp-heap,kglss)

 However setting sga_target to 21G allowed the database to start.

 We found a note on Metalink suggesting that SGA_TARGET did not like being set to multiples of 4G which seemed to be proved in the above example. However that is an easily disprovable statement  as I am sure we all have databases with SGA_TARGET = 4,8,12G.

 On further analysis and discussions with Oracle we came up with the following information. Firstly the issue is associated with a high number of CPUs and it is a bit difficult for us to test as we don’t any servers we can test on with 32 or more CPUs

 Bug 6624011 – ORA-4030 / ORA-4031 on startup with > 4Gb (and large amount of CPU’s)

This is generic to all platforms and fixed in 11.1.0.7

current workaround is to set the SGA_TARGET to 19G.

Bug 8813366 – ORA-4031 ERRORS DUE TO EXCESSIVE GRANULE SIZE IN 11G

This is generic to all platforms and applicable to 11.1.0.6 and 11.1.0.7

It has the following symptons

 - Memory_target is used and set to a high value (8GB for example).
- The shared pool is divided in subpools due to high number of CPUs.
- ORA-4031 trace file  shows several subpools with no memory allocated.

 

Once we have upgraded Production to 11.1.0.7 another attempt to start up the DB with a multiple of 4G should be made.

However, the startup may fail with ORA-04031 unable to allocate 56 bytes of shared memory. This is documented in Metalink Note 831770.1 and fixed by applying patch 7441663 on top of 11.1.0.7 (recommended) or using one of the following workarounds:

Start the database having explicitly set:

_ksmg_granule_size=16777216

in the init.ora file.

or

Start the database with a reduced number of subpools in shared pool by explicitly setting:

_kghdsidx_count=2

 Hope this is useful heads up to anybody who has a similar issue

h1

Automatically running sql_advisor tasks from ADDM reports

November 12, 2009

STOP PRESS – 17 Nov 2009  – updated with latest code which works against both 10g and 11g databases

 I am attaching scripts which I wrote a while ago to automatically pick any sql_ids reported in the latest ADDM and then run sql_advisor to report on any tuning advice. I am not suggesting that the information they provide is not available from EM or indeed every task reported needs resolving but it can be a good heads-up on a system you don’t know very well.

These are enabled every hour (can be less depending upon your snapshot interval) and they create a daily file which can be easily reviewed.

I find the real benefit is not on production databases but on dev and test databases that are being used for development prior to production implementation. This is for two reasons, firstly I hope that the team has a good handle on what is happening in production and are aware of issues and secondly we are most likely  to be able to add most value and benefit in development environments before the code is made live.

A couple of ‘issuettes’. The output from the ADDM report is different between 10g and 11g so I have amended the awk file to cater for both versions. I have been having an ongoing problem with tghe sql_advisor tuning task timing out on some systems and consequently leaving the task created for the next run. I have therefore amended the loop to drop the task at several points which looks untidy in the output file bit does seem to resolve the problem. 

I hoped to attach a zip file containing 4 scripts but cannot see how to do it without a plug-in which is a problem on my works PC. so in the meantime I have pasted the code of each of 4 files.

tuning_recommendations.ksh which is the controlling script

#! /bin/ksh
# loop though the file produced from get_addm_report.sql and put the gathered sql-ids into a flat file
# awk the file to get just the SQL_ID
# for each sql_id create a task, execute that task, run the report and then delete the task
#
# The delete tuning task job is run an additional twice because if the tuning task times out then it does not clean up properly
# Better to see a few failures in this job that not run the sql_tuning_advisor at all.
#if [ -d /home/oracle/logs ]
then
   rm  /home/oracle/logs/tmp*.log
   else
   mkdir /home/oracle/logs
   exit
fi
if [ $# -ne 1 ]
then
    echo "No ORACLE SID  - exiting"
    exit
fi
# execute ORACLE's .profile
#
#. ~/.profile
unset ORAENV_ASK
#
# set up environment variables.
#

ORACLE_SID=$1
. /usr/local/bin/oraenv ${ORACLE_SID}
export ORACLE_HOME=`cat /etc/oratab | grep $ORACLE_SID | awk -F: '{print $2 }`
export PATH=$ORACLE_HOME/bin:$PATH
export ORAENV_ASK=NO
today=`date +%d-%b-%Y`; export today
LOGDIR=$HOME/logs
LOGFILE=$LOGDIR/get_addm_${today}.log
REPORTFILE=$LOGDIR/sql_advisor_report_${ORACLE_SID}_${today}.log

#
#
sqlplus -s /nolog  <<SQLEND
connect / as sysdba
     spool $LOGDIR/tmp_${ORACLE_SID}_1.log
     @/shared/oracle/performance/get_addm_report.sql
     spool off
     exit
SQLEND

<p>&nbsp;</p>

cat $LOGDIR/tmp_${ORACLE_SID}_1.log|awk -f /shared/oracle/performance/tuning_recommendations.awk |awk '!a[$0]++' > $LOGDIR/tmp_${ORACLE_SID}_2.log
cat  $LOGDIR/tmp_${ORACLE_SID}_2.log | awk '$0!~/^$/ {print $0}' > $LOGDIR/tmp_${ORACLE_SID}_3.log

for PLAN in  `cat $LOGDIR/tmp_${ORACLE_SID}_3.log`
do
sqlplus -s /nolog  <<SQLEND >> $REPORTFILE
connect / as sysdba
        begin
        DBMS_SQLTUNE.drop_tuning_task('test_task1');
        end;
        /
     SELECT status FROM USER_ADVISOR_TASKS WHERE task_name = 'test_task1';
     @/shared/oracle/performance/sql_advisor.sql $PLAN
     exit
SQLEND
done

# tidy up the report file
# tidy up reports > 14 days old
find  $LOGDIR -name "sql_advisor_repor*.log" -mtime +14 -print -exec rm -f {} \;

get_addm_report.sql which gets each task from the last snapshot from dba_advisor_tasks

set long  10000000
set pagesize 50000
column get_clob format a80

select dbms_advisor.get_task_report (task_name) as ADDM_report
from dba_advisor_tasks
where task_id = (
        select max(t. task_id)
        from dba_advisor_tasks t, dba_advisor_log l
        where t.task_id = l.task_id
        and t.advisor_name = 'ADDM'
        and l.status = 'COMPLETED');

tuning_recommendations.awk is a short awk script used to process the output from get_addm_report.sql

BEGIN{
#start at the first line
#OUTFILE="$HOME/logs/outfile.log"
}
{
        {
                if (($1=="RATIONALE:") && ($2=="SQL")) #10G ADDM format
                {
                        F1=$6
                }
                if (($1=="Run") && ($2=="SQL") && ($3=="Tuning") && ($4=="Advisor") && ($7=="SQL") && ($10=="SQL_ID")) #11G ADDM format
                {
                        F1=$11
                }

        }
VAR1=substr(F1,2,13)
print VAR1
}
END{
}

sql_advisor.sql runs the sql_advisor package against each task found.

DECLARE
my_task_name   VARCHAR2 (30);
my_sqltext     CLOB;
my_sqlid        varchar2(30);

BEGIN
my_sqlid := '&1';
my_task_name := dbms_sqltune.create_tuning_task (sql_id=> my_sqlid,
       scope         => 'COMPREHENSIVE',
       time_limit    => 300,
       task_name     => 'test_task1',
       description   => 'test_task1'
    );
END;
/

BEGIN
dbms_sqltune.execute_tuning_task (task_name => 'test_task1');
END;
/

SELECT status FROM USER_ADVISOR_TASKS WHERE task_name = 'test_task1';
SET LONG 10000
SET LONGCHUNKSIZE 10000
SET LINESIZE 100
set pages 60
SELECT DBMS_SQLTUNE.REPORT_TUNING_TASK( 'test_task1')
FROM DUAL;
begin
DBMS_SQLTUNE.drop_tuning_task('test_task1');
end;
/

We have a read only NFS mounted disk available on all database servers and the files are placed in there and initiated by a cron entry for each SID on an hourly basis
40 * * * * /shared/oracle/performance/tuning_recommendations.ksh SID >/dev/null 2>&1

Output is created in a folder $HOME/logs and 14 days worth of reports are kept.

A sample output report (only one task shown but certainly on this Peoplesoft database it would show many tasks)

DBMS_SQLTUNE.REPORT_TUNING_TASK('TEST_TASK1')
----------------------------------------------------------------------------------------------------
GENERAL INFORMATION SECTION
-------------------------------------------------------------------------------
Tuning Task Name                  : test_task1
Tuning Task Owner                 : SYS
Scope                             : COMPREHENSIVE
Time Limit(seconds)               : 60
Completion Status                 : COMPLETED
Started at                        : 11/12/2009 07:43:33
Completed at                      : 11/12/2009 07:44:16
Number of Statistic Findings      : 1
Number of Index Findings          : 1

-------------------------------------------------------------------------------
Schema Name: SYSADM
SQL ID     : cy3fmjha2sjnr
SQL Text   : SELECT M.EMPLID, M.EMPL_RCD, M.SCH_PRIM_ALT_IND,
             TO_CHAR(M.DUR,'YYYY-MM-DD'), M.SEQ_NO, M.CHNG_PRIMARY,
             M.SCHEDULE_GRP, M.SETID, M.WRKDAY_ID, M.SHIFT_ID, M.SCHED_HRS,
             M.SCH_CONFIG1, M.SCH_CONFIG2, M.SCH_CONFIG3, M.SCH_CONFIG4,
             TO_CHAR(M.START_DTTM,'YYYY-MM-DD-HH24.MI.SS.&amp;quot;000000&amp;quot;'),
             TO_CHAR(M.END_DTTM,'YYYY-MM-DD-HH24.MI.SS.&amp;quot;000000&amp;quot;'),
             M.SCHED_SOURCE, M.OFFDAY_IND, A.TIMEZONE, A.SCH_CATEGORY From
             PS_SCH_MNG_SCH_TBL M, PS_SCH_ADHOC_DTL A Where M.EMPLID = :1 and
             M.EMPL_RCD = :2 and M.SCH_PRIM_ALT_IND = :3 and M.DUR between
             TO_DATE(:4,'YYYY-MM-DD') and TO_DATE(:5,'YYYY-MM-DD') and
             A.EMPLID = M.EMPLID and A.EMPL_RCD = M.EMPL_RCD and
             A.SCH_PRIM_ALT_IND = M.SCH_PRIM_ALT_IND and A.DUR = M.DUR and
             A.SEQ_NO = M.SEQ_NO and A.SEQNUM = 1 Order By M.DUR Asc,
             M.SCHED_SOURCE Desc, M.SEQ_NO Desc

-------------------------------------------------------------------------------
FINDINGS SECTION (2 findings)
-------------------------------------------------------------------------------

1- Statistics Finding
---------------------
  Optimizer statistics for index &amp;quot;SYSADM&amp;quot;.&amp;quot;PS_SCH_MNG_SCH_TBL&amp;quot; are stale.

  Recommendation
  --------------
  - Consider collecting optimizer statistics for this index.
    execute dbms_stats.gather_index_stats(ownname =&amp;gt; 'SYSADM', indname =&amp;gt;
            'PS_SCH_MNG_SCH_TBL', estimate_percent =&amp;gt;
            DBMS_STATS.AUTO_SAMPLE_SIZE);

  Rationale
  ---------
    The optimizer requires up-to-date statistics for the index in order to
    select a good execution plan.

2- Index Finding (see explain plans section below)
--------------------------------------------------
  The execution plan of this statement can be improved by creating one or more
  indices.

  Recommendation (estimated benefit: 94.67%)
  ------------------------------------------

DBMS_SQLTUNE.REPORT_TUNING_TASK('TEST_TASK1')
----------------------------------------------------------------------------------------------------
  - Consider running the Access Advisor to improve the physical schema design
    or creating the recommended index.
    create index SYSADM.IDX$$_21C0F0001 on
    SYSADM.PS_SCH_ADHOC_DTL(&amp;quot;EMPLID&amp;quot;,&amp;quot;SEQNUM&amp;quot;,&amp;quot;EMPL_RCD&amp;quot;,&amp;quot;SCH_PRIM_ALT_IND&amp;quot;,&amp;quot;DU
    R&amp;quot;);

  - Consider running the Access Advisor to improve the physical schema design
    or creating the recommended index.
    create index SYSADM.IDX$$_21C0F0002 on
    SYSADM.PS_SCH_MNG_SCH_TBL(&amp;quot;EMPLID&amp;quot;,&amp;quot;DUR&amp;quot;);

  Rationale
  ---------
    Creating the recommended indices significantly improves the execution plan
    of this statement. However, it might be preferable to run &amp;quot;Access Advisor&amp;quot;
    using a representative SQL workload as opposed to a single statement. This
    will allow to get comprehensive index recommendations which takes into
    account index maintenance overhead and additional space consumption.

-------------------------------------------------------------------------------
EXPLAIN PLANS SECTION
-------------------------------------------------------------------------------

1- Original
-----------
Plan hash value: 2070933151

----------------------------------------------------------------------------------------------------
------------------------
| Id  | Operation                             | Name               | Rows  | Bytes | Cost (%CPU)| Ti
me     | Pstart| Pstop |
----------------------------------------------------------------------------------------------------
------------------------
|   0 | SELECT STATEMENT                      |                    |     1 |   103 |   387   (1)| 00
:00:01 |       |       |
|*  1 |  FILTER                               |                    |       |       |            |
       |       |       |
|   2 |   SORT ORDER BY                       |                    |     1 |   103 |   387   (1)| 00
:00:01 |       |       |
|   3 |    NESTED LOOPS                       |                    |     1 |   103 |   386   (1)| 00
:00:01 |       |       |
|   4 |     PARTITION RANGE ITERATOR          |                    |    10 |   350 |   371   (1)| 00
:00:01 |   KEY |   KEY |
|   5 |      TABLE ACCESS BY LOCAL INDEX ROWID| PS_SCH_ADHOC_DTL   |    10 |   350 |   371   (1)| 00
:00:01 |   KEY |   KEY |
|*  6 |       INDEX RANGE SCAN                | PS_SCH_ADHOC_DTL   |    10 |       |   369   (1)| 00
:00:01 |   KEY |   KEY |
|   7 |     PARTITION RANGE ITERATOR          |                    |     1 |    68 |     2   (0)| 00
:00:01 |   KEY |   KEY |
|   8 |      TABLE ACCESS BY LOCAL INDEX ROWID| PS_SCH_MNG_SCH_TBL |     1 |    68 |     2   (0)| 00
:00:01 |   KEY |   KEY |
|*  9 |       INDEX UNIQUE SCAN               | PS_SCH_MNG_SCH_TBL |     1 |       |     1   (0)| 00
:00:01 |   KEY |   KEY |
----------------------------------------------------------------------------------------------------
------------------------

Predicate Information (identified by operation id):

DBMS_SQLTUNE.REPORT_TUNING_TASK('TEST_TASK1')
----------------------------------------------------------------------------------------------------
---------------------------------------------------

   1 - filter(TO_DATE(:4,'YYYY-MM-DD')&amp;lt;=TO_DATE(:5,'YYYY-MM-DD'))
   6 - access(&amp;quot;A&amp;quot;.&amp;quot;EMPLID&amp;quot;=:1 AND &amp;quot;A&amp;quot;.&amp;quot;EMPL_RCD&amp;quot;=TO_NUMBER(:2) AND &amp;quot;A&amp;quot;.&amp;quot;SCH_PRIM_ALT_IND&amp;quot;=:3 AND
              &amp;quot;A&amp;quot;.&amp;quot;DUR&amp;quot;&amp;gt;=TO_DATE(:4,'YYYY-MM-DD') AND &amp;quot;A&amp;quot;.&amp;quot;SEQNUM&amp;quot;=1 AND &amp;quot;A&amp;quot;.&amp;quot;DUR&amp;quot;&amp;lt;=TO_DATE(:5,'YYYY
-MM-DD'))
       filter(&amp;quot;A&amp;quot;.&amp;quot;SEQNUM&amp;quot;=1)
   9 - access(&amp;quot;M&amp;quot;.&amp;quot;EMPLID&amp;quot;=:1 AND &amp;quot;M&amp;quot;.&amp;quot;EMPL_RCD&amp;quot;=TO_NUMBER(:2) AND &amp;quot;M&amp;quot;.&amp;quot;SCH_PRIM_ALT_IND&amp;quot;=:3 AND
              &amp;quot;A&amp;quot;.&amp;quot;DUR&amp;quot;=&amp;quot;M&amp;quot;.&amp;quot;DUR&amp;quot; AND &amp;quot;A&amp;quot;.&amp;quot;SEQ_NO&amp;quot;=&amp;quot;M&amp;quot;.&amp;quot;SEQ_NO&amp;quot;)
       filter(&amp;quot;M&amp;quot;.&amp;quot;DUR&amp;quot;&amp;gt;=TO_DATE(:4,'YYYY-MM-DD') AND &amp;quot;M&amp;quot;.&amp;quot;DUR&amp;quot;&amp;lt;=TO_DATE(:5,'YYYY-MM-DD'))

2- Using New Indices
--------------------
Plan hash value: 1209469329

----------------------------------------------------------------------------------------------------
------------------------
| Id  | Operation                             | Name               | Rows  | Bytes | Cost (%CPU)| Ti
me     | Pstart| Pstop |
----------------------------------------------------------------------------------------------------
------------------------
|   0 | SELECT STATEMENT                      |                    |     1 |   103 |    21  (10)| 00
:00:01 |       |       |
|*  1 |  FILTER                               |                    |       |       |            |
       |       |       |
|   2 |   SORT ORDER BY                       |                    |     1 |   103 |    21  (10)| 00
:00:01 |       |       |
|*  3 |    HASH JOIN                          |                    |     1 |   103 |    20   (5)| 00
:00:01 |       |       |
|   4 |     TABLE ACCESS BY GLOBAL INDEX ROWID| PS_SCH_ADHOC_DTL   |    10 |   350 |    10   (0)| 00
:00:01 | ROWID | ROWID |
|*  5 |      INDEX RANGE SCAN                 | IDX$$_21C0F0001    |    10 |       |     4   (0)| 00
:00:01 |       |       |
|*  6 |     TABLE ACCESS BY GLOBAL INDEX ROWID| PS_SCH_MNG_SCH_TBL |    13 |   884 |     9   (0)| 00
:00:01 | ROWID | ROWID |
|*  7 |      INDEX RANGE SCAN                 | IDX$$_21C0F0002    |    13 |       |     3   (0)| 00
:00:01 |       |       |
----------------------------------------------------------------------------------------------------
------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter(TO_DATE(:4,'YYYY-MM-DD')&amp;lt;=TO_DATE(:5,'YYYY-MM-DD'))
   3 - access(&amp;quot;A&amp;quot;.&amp;quot;EMPLID&amp;quot;=&amp;quot;M&amp;quot;.&amp;quot;EMPLID&amp;quot; AND &amp;quot;A&amp;quot;.&amp;quot;EMPL_RCD&amp;quot;=&amp;quot;M&amp;quot;.&amp;quot;EMPL_RCD&amp;quot; AND
              &amp;quot;A&amp;quot;.&amp;quot;SCH_PRIM_ALT_IND&amp;quot;=&amp;quot;M&amp;quot;.&amp;quot;SCH_PRIM_ALT_IND&amp;quot; AND &amp;quot;A&amp;quot;.&amp;quot;DUR&amp;quot;=&amp;quot;M&amp;quot;.&amp;quot;DUR&amp;quot; AND
              SYS_OP_DESCEND(&amp;quot;A&amp;quot;.&amp;quot;DUR&amp;quot;)=SYS_OP_DESCEND(&amp;quot;M&amp;quot;.&amp;quot;DUR&amp;quot;) AND &amp;quot;A&amp;quot;.&amp;quot;SEQ_NO&amp;quot;=&amp;quot;M&amp;quot;.&amp;quot;SEQ_NO&amp;quot;)
   5 - access(&amp;quot;A&amp;quot;.&amp;quot;EMPLID&amp;quot;=:1 AND &amp;quot;A&amp;quot;.&amp;quot;SEQNUM&amp;quot;=1 AND &amp;quot;A&amp;quot;.&amp;quot;EMPL_RCD&amp;quot;=TO_NUMBER(:2) AND &amp;quot;A&amp;quot;.&amp;quot;SCH_PRIM_
ALT_IND&amp;quot;=:3 AND
              &amp;quot;A&amp;quot;.&amp;quot;DUR&amp;quot;&amp;gt;=TO_DATE(:4,'YYYY-MM-DD') AND &amp;quot;A&amp;quot;.&amp;quot;DUR&amp;quot;&amp;lt;=TO_DATE(:5,'YYYY-MM-DD'))
   6 - filter(&amp;quot;M&amp;quot;.&amp;quot;SCH_PRIM_ALT_IND&amp;quot;=:3 AND &amp;quot;M&amp;quot;.&amp;quot;EMPL_RCD&amp;quot;=TO_NUMBER(:2))
   7 - access(&amp;quot;M&amp;quot;.&amp;quot;EMPLID&amp;quot;=:1 AND &amp;quot;M&amp;quot;.&amp;quot;DUR&amp;quot;&amp;gt;=TO_DATE(:4,'YYYY-MM-DD') AND &amp;quot;M&amp;quot;.&amp;quot;DUR&amp;quot;&amp;lt;=TO_DATE(:5,'YYY
Y-MM-DD'))

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

PL/SQL procedure successfully completed.

The routine above works well but I am happy to consider any changes or improvements.

PS If anybody knows how to use a code tag and not have those horrible green wraparound marks please let me know

h1

PSU for 11.1.0.7.1

October 29, 2009

One of the most read entries on this site is about the PSU release for 10.2.0.4 http://jhdba.wordpress.com/2009/07/28/applying-the-10-2-0-4-1-patch-set-update-psu/

On 20th October, 2009 the first PSU for 11.1.0.7 was released. This also incorporates the Oct 2009 CPU as well as a Dataguard Broker patchset bundle. Bug 7628357 – 11.1.0.7 Data Guard Recommended Patch Bundle #1.

 Oracle have maintained consistency with the 10.2.0.4 PSU by retaining the misinformation in the patch instructions. I did originally think that there was no need to update opatch as there was in 10g but I was wrong. Opatch should be upgraded but the PSU  does apply even if it is not upgraded.

Ensure that the latest Opatch version is installed

 

opatch version

Invoking OPatch 11.1.0.6.2

 

OPatch Version: 11.1.0.6.2

 

If it is not 11.1.0.6.7 or later then upgrade

 

cd $ORACLE_HOME

cp /shared/oracle/rdbms_patches/PSU_patches/11.1.0.7/p6880880_111000_HPUX-IA64.zip .

unzip p6880880_111000_HPUX-IA64.zip

rm p6880880_111000_HPUX-IA64.zip

 

opatch version

Invoking OPatch 11.1.0.6.8

 

OPatch Version: 11.1.0.6.8

 

 

Basic steps for a new build server are as follows

1) Install 11.1.0.6 and upgrade to 11.1.0.7

2) ensure opatch is in the path, an Oracle Home is set and the patcheset (8833297) is unzipped

3) Run the pre-check

Following the README notes I would use this command

$cd /shared/oracle/rdbms_patches/PSU_patches/11.1.0.7

$opatch prereq CheckConflictAgainstOHWithDetail -phBaseDir ./8833297

which then fails

Oracle Interim Patch Installer version 11.1.0.6.2
Copyright (c) 2007, Oracle Corporation.  All rights reserved.

PREREQ session

Oracle Home       : /app/oracle/product/11.1.0/db_1
Central Inventory : /app/oraInventory
   from           : /var/opt/oracle/oraInst.loc
OPatch version    : 11.1.0.6.2
OUI version       : 11.1.0.7.0
OUI location      : /app/oracle/product/11.1.0/db_1/oui
Log file location : /app/oracle/product/11.1.0/db_1/cfgtoollogs/opatch/opatch2009-10-28_14-16-33PM.log

Invoking prereq &quot;checkconflictagainstohwithdetail&quot;
&lt;span style=&quot;color: #ff0000;&quot;&gt;The location &quot;./8833297/README.html&quot; is not a directory or a valid patch zip file.
Prereq &quot;checkConflictAgainstOHWithDetail&quot; not executed
PrereqSession failed: Invalid patch location.&lt;/span&gt;

&lt;span style=&quot;color: #ff0000;&quot;&gt;OPatch failed with error code 73

Then use the corrected syntax

opatch prereq CheckConflictAgainstOHWithDetail -ph ./8833297

Invoking OPatch 11.1.0.6.2

Oracle Interim Patch Installer version 11.1.0.6.2
Copyright (c) 2007, Oracle Corporation.  All rights reserved.

PREREQ session

Oracle Home       : /app/oracle/product/11.1.0/db_1
Central Inventory : /app/oraInventory
   from           : /var/opt/oracle/oraInst.loc
OPatch version    : 11.1.0.6.2
OUI version       : 11.1.0.7.0
OUI location      : /app/oracle/product/11.1.0/db_1/oui
Log file location : /app/oracle/product/11.1.0/db_1/cfgtoollogs/opatch/opatch2009-10-28_14-16-57PM.log

Invoking prereq &quot;checkconflictagainstohwithdetail&quot;

Prereq &quot;checkConflictAgainstOHWithDetail&quot; passed.

OPatch succeeded.  

This is very quick, less than one minute

4) Now apply the PSU

$cd 8833297
$opatch apply

The patchset took 28 minutes to apply

Afterwards an opatch lsinventory command shows

Oracle Home       : /app/oracle/product/11.1.0/db_1
Central Inventory : /app/oraInventory
   from           : /var/opt/oracle/oraInst.loc
OPatch version    : 11.1.0.6.2
OUI version       : 11.1.0.7.0
OUI location      : /app/oracle/product/11.1.0/db_1/oui
Log file location : /app/oracle/product/11.1.0/db_1/cfgtoollogs/opatch/opatch2009-10-28_15-55-41PM.log

Lsinventory Output file location : /app/oracle/product/11.1.0/db_1/cfgtoollogs/opatch/lsinv/lsinventory2009-10-28_15-55-41PM.txt

--------------------------------------------------------------------------------
Installed Top-level Products (2):

Oracle Database 11g                                                  11.1.0.6.0
Oracle Database 11g Patch Set 1                                      11.1.0.7.0
There are 2 products installed in this Oracle Home.
Interim patches (1) :

Patch  8833297      : applied on Wed Oct 28 14:54:39 GMT 2009
   Created on 7 Oct 2009, 23:52:06 hrs PST8PDT
   Bugs fixed:
     6870937, 7627743, 7652888, 7299153, 8242410, 6059178, 8563946, 6955744
     7497788, 6840740, 8244217, 8702276, 6981690, 8450529, 7432556, 7719143
     7523787, 8251486, 8367827, 7613481, 8341623, 7515145, 7348847, 8416414
     8250643, 8284633, 8230457, 8563948, 6900214, 7044551, 7318049, 8940197
     7013124, 7432514, 7393258, 7553884, 7639121, 8563944, 8860821, 7606362
     7426959, 7330434, 7708340, 7352414, 6452375, 7356443, 7341598, 8213302
     7196532, 7446163, 8409848, 8236851, 8342506, 7593835, 7340448, 7309458
     8290478, 8391256, 7462112, 7013817, 8499600, 7411865, 7331867, 7527650
     6977167, 8855565, 6501490, 6598432, 7524944, 7706138, 6941717, 8402555
     7494333, 7586451, 8402551, 7499353, 8408887, 7496908, 7511040, 7719148
     7311601, 7497640, 7373196, 7424804, 7452373, 7597354, 6882739, 7366290
     8543737, 6851669, 7318276, 8284438, 8324760, 7420394, 7834195, 7350127
     7475055, 8563942, 7122161, 8361398, 7451927, 7705669, 7676737, 8301559
     8224083, 8658581, 8211920, 8462173, 7206858, 8563945, 8855553, 8402637
     8257122, 8199266, 7454752, 7516536, 7345904, 8352304, 7416901, 7426336
     8352309, 6812439, 7219752, 8534338, 8542307, 8413059, 7572069, 7436280
     7432601, 7311909, 7506785, 7460818, 7276960, 8855559, 7013835, 7378322
     8402548, 7189645, 8563947, 8306933, 7477246, 7263842, 7480809, 8855575
     8433270, 7556778, 8836375, 7330611, 8339352, 7225720, 8563943, 7036453
     7628387, 8419383, 6970731, 7719668, 7203349, 8402562, 7680907, 7438445
     8855577, 8243648, 7630416, 6851110, 6980597, 6618461, 7357609, 8855570
     8369094, 8318050, 8306934, 7434194, 8833297, 7486595, 7716219, 8362693
     6599920, 7628866, 7183523, 7412296, 7135702, 7720494, 7436152, 7175513
     7602341, 6679303, 8339404, 7393804, 8856696, 7650993, 6980601, 7830065
     7462709, 8563941, 8226397, 7515779

Note that if you already have databases built then you need to run a catbundle script and check for invalid objects. Check the documentation for full details that but a quick summary is to run
cd $ORACLE_HOME/rdbms/admin
sqlplus /nolog
SQL CONNECT / AS SYSDBA
SQL STARTUP
SQL @catbundle.sql psu apply
SQL QUIT

h1

Oracle Performance Management with Gaja Vaidyanatha

October 21, 2009

I attended this 2 day workshop ,held in London, last week.

I already owned both of Gaja’s book, Tales of the Oak Table and 101 Performance Tuning so I was reasonably familiar with  his background.

The course started of badly as Gaja was late arriving due to travel delays and so we did not kick off until 11:30 which was either 1.5 or 2 hours depending on whom you asked. He hit the ground running with a quick introduction and then a round the room ‘what do you want to get from this’ session.

The sessions covered everything set out in the advertising blurb, namely architecture, tracing, use of the OWI interface and a planned methodology for dealing with problems. One key point , apart from the availability of RAT in 11g was that the newer release did not add much to what Oracle 10g already provided with regard to performance tuning. 

The key methodology thoughts were to clearly define a goal, run a simple diagnostic routine and then repeat. With regard to SQL optimisation the 2 things to remeber were

  1. Reducing logical I/O is primary in any performance tuning engagement
  2. Hand in hand reducing elapsed time is equally important

The repeatable process is to find ‘interesting’ PIDS from glance or top, map them to a SPID (SID and SERIAL#) to find a session then run a 10046 trace and find the most expensive step (often the  most indented call).

Fix the code (one change at a time) and repeat.  If a 10046 trace does not help then get down to the OS level and look at how resources are being used.

That all sounds pretty simple and indeed it is.  I could write more about the methodology but I am concious that it is someone’s livelyhood and not to say too much.

Without sounding too knowledgeable or clever I was aware of most of the content that was discussed in the 2 days. Where I gained real benefits was in the storage aspects that Gaja covered very well and offered real insights into CPU, hyper threading, HBA usage and loading and suchlike. Various RAID levels were well covered and we had  a very good discussion on the value of placing redo logs on RAID 1+0 and suchlike.

Most of the second day was taken up with running through some real world examples, some where the problem was obvious, others where I had no clue at all. Several people had brought in 10046 traces and AWR snapshots and we all gained real insight as Gaja looked at them for the first time and showed us the key points worthy of investigation.

All in all a very worthwhile 2 days. The target audience needs to have a reasonable Oracle knowledge beforehand as a couple of students were saying that they had found it very difficult to follow. Oh and be prepared for long days as on day one Gaja was still talking strongly upto 18:00 despite being deadbeat from travelling and the second day went on up to 17:00.

Executive summary. Highly recommended

h1

Configuring Dataguard Broker in 11G

October 12, 2009

DataGuard Broken?

A guest blog from colleague Simon Ryan

Last year we did some sandpit work on implementing DataGuard.  This was 10g on a Windows platform.  When it came to the broker we didn’t have much luck.  At the UKOUG Michael Moller referred to the Broker as DataGuard Broken (DataGuard 11g New Features).  From the audience reaction this seemed to be a popular perception.

Since then we’ve successfully implemented DataGuard on most of our Production databases (both 10g and 11g) on HP-UX.  However, we’ve still not embraced the Broker!  The ‘broken’ tag still taints its reputation.  A recent visit by Oracle attempted to assure us that the Broker with 11g is much improved.

The following is a basic guide to implementing the broker and our findings:

Our Setup

o       Primary – Two node RAC Cluster (XXXPRD1A)

o       Physical Standby – Single node (XXXPRD1B)

o       HP-UX 11.31 Itanium

o       Database using ASM (both 11.1.0.7).

o       DataGuard running in Max Availability with Real Time Apply.

Configuration

Add the following entries to tnsnames.ora on all instances:

 

XXXPRD1A_DGMGRL =

   (DESCRIPTION=

     (ADDRESS=(PROTOCOL=tcp)(HOST=xxxem03-vip)(PORT=1526))

     (CONNECT_DATA=

       (SERVICE_NAME=XXXPRD1A_DGMGRL)

     )

    )

 

XXXPRD2A_DGMGRL =

   (DESCRIPTION=

     (ADDRESS=(PROTOCOL=tcp)(HOST=xxxem04-vip)(PORT=1526))

     (CONNECT_DATA=

       (SERVICE_NAME=XXXPRD2A_DGMGRL)

     )

    )

 

XXXPRD1B_DGMGRL =

   (DESCRIPTION=

     (ADDRESS=(PROTOCOL=tcp)(HOST=xxxem01-vip)(PORT=1526))

     (CONNECT_DATA=

       (SERVICE_NAME=XXXPRD1B_DGMGRL)

     )

    )

 

Add the following entry to SID_LIST of your listener in listener.ora on all instances:

 

 (SID_DESC = 

      (ORACLE_HOME = /app/oracle/product/11.1.0/db_1)

      (SID_NAME = XXXPRDxx)

      (GLOBAL_DBNAME = XXXPRDxx_DGMGRL)

    )

 Stop/start listener.

 Test you can now connect:

 

 sqlplus sys@XXXPRD2A_dgmgrl as sysdba

  

Make the following parameter changes:

 

 XXXPRD1A:
<pre>
 

alter system set dg_broker_start=true scope=spfile;

alter system set dg_broker_config_file1='+DATA/XXXPRD1A/broker1.dat' scope=spfile;

alter system set dg_broker_config_file2='+FRA/XXXPRD1A/broker2.dat' scope=spfile;

 XXXPRD1B:

alter system set dg_broker_start=true scope=spfile;

alter system set dg_broker_config_file1='+DATA/XXXPRD1B/broker1.dat' scope=spfile;

alter system set dg_broker_config_file2='+FRA/XXXPRD1B/broker2.dat' scope=spfile; 

 Stop/Start the databases:

 

 Stop XXXPRD1A:
<pre>
 

srvctl stop database -d XXXPRD1A -o immediate

 Stop XXXPRD1B:

shutdown immediate

 Start XXXPRD1B:

startup mount

 Start XXXPRD1A:

srvctl start database -d XXXPRD1A

 

 Check for the broker process:

 

 XXXPRD1A:
<pre>
 

ps –ef | grep ora_dmon_XXXPRD1A

XXXPRD1B:

ps –ef | grep ora_dmon_XXXPRD1B

 

Create DG Broker Configuration:

 

[code lang='xml'] Primary:

dgmgrl

connect sys

<em>enter sys password</em>

 

create configuration XXXPRD1A_DGCONFIG as primary database is “XXXPRD1A” connect identifier is XXXPRD1A;

Configuration "XXXPRD1A_dgconfig" created with primary database "XXXPRD1A"

 

add database “XXXPRD1B” as connect identifier is XXXPRD1B maintained as physical;

Database "XXXPRD1B" added

 

enable configuration;

Enabled.

 

show configuration;

 

Configuration

  Name:                XXXPRD1A_dgconfig

  Enabled:             YES

  Protection Mode:     MaxAvailability

  Databases:

    XXXPRD1A - Primary database

    XXXPRD1B - Physical standby database

 

Fast-Start Failover: DISABLED

 

Current status for "XXXPRD1A_dgconfig":

SUCCESS

 

 Check Broker Files Exist:

Primary and Standby ASM:

Check they are there.

 

Show Database:

 Primary: 

show database verbose “XXXPRD1A”;

 

Database

  Name:            XXXPRD1A

  Role:            PRIMARY

  Enabled:         YES

  Intended State:  TRANSPORT-ON

  Instance(s):

    XXXPRD1A

    XXXPRD2A

 

  Properties:

    DGConnectIdentifier             = 'XXXPRD1A'

    ObserverConnectIdentifier       = ''

    LogXptMode                      = 'SYNC'

    DelayMins                       = '0'

    Binding                         = 'OPTIONAL'

    MaxFailure                      = '0'

    MaxConnections                  = '1'

    ReopenSecs                      = '300'

    NetTimeout                      = '30'

    RedoCompression                 = 'DISABLE'

    LogShipping                     = 'ON'

    PreferredApplyInstance          = ''

    ApplyInstanceTimeout            = '0'

    ApplyParallel                   = 'AUTO'

    StandbyFileManagement           = 'AUTO'

    ArchiveLagTarget                = '0'

    LogArchiveMaxProcesses          = '10'

    LogArchiveMinSucceedDest        = '1'

    DbFileNameConvert               = 'XXXPRD1B, XXXPRD1A'

    LogFileNameConvert              = 'XXXPRD1B, XXXPRD1A'

    FastStartFailoverTarget         = ''

    StatusReport                    = '(monitor)'

    InconsistentProperties          = '(monitor)'

    InconsistentLogXptProps         = '(monitor)'

    SendQEntries                    = '(monitor)'

    LogXptStatus                    = '(monitor)'

    RecvQEntries                    = '(monitor)'

    HostName(*)

    SidName(*)

    StaticConnectIdentifier(*)

    StandbyArchiveLocation(*)

    AlternateLocation(*)

    LogArchiveTrace(*)

    LogArchiveFormat(*)

    LatestLog(*)

    TopWaitEvents(*)

    (*) - Please check specific instance for the property value

 

Current status for "XXXPRD1A":

SUCCESS

 

Standby:

show database verbose “XXXPRD1B”;

 

Database

  Name:            XXXPRD1B

  Role:            PHYSICAL STANDBY

  Enabled:         YES

  Intended State:  APPLY-ON

  Instance(s):

    XXXPRD1B

 

  Properties:

    DGConnectIdentifier             = 'XXXPRD1B'

    ObserverConnectIdentifier       = ''

    LogXptMode                      = 'SYNC'

    DelayMins                       = '0'

    Binding                         = 'OPTIONAL'

    MaxFailure                      = '0'

    MaxConnections                  = '1'

    ReopenSecs                      = '60'

    NetTimeout                      = '30'

    RedoCompression                 = 'DISABLE'

    LogShipping                     = 'ON'

    PreferredApplyInstance          = ''

    ApplyInstanceTimeout            = '0'

    ApplyParallel                   = 'AUTO'

    StandbyFileManagement           = 'AUTO'

    ArchiveLagTarget                = '0'

    LogArchiveMaxProcesses          = '10'

    LogArchiveMinSucceedDest        = '1'

    DbFileNameConvert               = 'XXXPRD1A, XXXPRD1B'

    LogFileNameConvert              = 'XXXPRD1A, XXXPRD1B'

    FastStartFailoverTarget         = ''

    StatusReport                    = '(monitor)'

    InconsistentProperties          = '(monitor)'

    InconsistentLogXptProps         = '(monitor)'

    SendQEntries                    = '(monitor)'

    LogXptStatus                    = '(monitor)'

    RecvQEntries                    = '(monitor)'

    HostName                        = 'xxxem01'

    SidName                         = 'XXXPRD1B'

    StaticConnectIdentifier         = '(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=xxxem01)(PORT=1526))(CONNECT_DATA=(SERVICE_NAME=XXXPRD1B_DGMGRL)(INSTANCE_NAME=XXXPRD1B)(SERVER=DEDICATED)))'

    StandbyArchiveLocation          = 'USE_DB_RECOVERY_FILE_DEST'

    AlternateLocation               = ''

    LogArchiveTrace                 = '0'

    LogArchiveFormat                = '%t_%s_%r.dbf'

    LatestLog                       = '(monitor)'

    TopWaitEvents                   = '(monitor)'

 

Current status for "XXXPRD1B":

SUCCESS

 Ensure logs are still being transported and applied

All still works!

 

What does it give us?

  • Improved monitoring in OEM.
  • Simpler administration via DGMGRL or OEM i.e. changing Protection Mode.
  • Easy switchover/failover
    • DGMGRL: switchover to “XXXPRD1A”
    • Click of a button in OEM.
  • Fast-Start Failover (with an observer).

 

Conclusions

The broker configuration was relatively painless and I have successfully performed a switchover via both DGMGRL and OEM.  I’ve also used the various OEM functions without issue too.  I’m uneasy about performing such tasks via OEM but then most DBA’s prefer to be at the helm via the command line rather than clicking a button (that’s too easy!). 

If you plan to use DataGuard Broker then embrace it and make sure you don’t alter parameters behind the covers.  It does that for you and it doesn’t like you meddling!  I also think it’s a good idea to setup DataGuard initially without the broker and then configure it once you’re happy that DataGuard is working.

So what’s made the difference since our experience last year?  UNIX v Windows (maybe), 10g v 11g (probably).  A big factor would also have to be our experience level.  In the last year we’ve increased our DataGuard count from zero to ten so we are therefore much more comfortable in the DataGuard world.

When a sand-pit database becomes available I’d like to try and setup the observer and test Fast-Start Failover.  I’m inclined to remove the ‘broken’ tag but I’ll reserve judgment until I’ve tested the remaining functions.

Simon Ryan

h1

Much faster performance with ASM – a real world example

October 9, 2009

We have a  Peoplesoft database that  manages HR for ~80,000 staff.  Oracle 10.2.03.  Peoplesoft Tools 8.49 PS HR 9 HPUX 11.31 Itanium

There has been long running problems caused by I/O bottlenecks writing down to Hitachi XP SAN disks. We were using filesystem storage and disk_asynch_io was set to false

The root cause of our problem was that the Time and Labour batches contend when they need to acquire exclusive access to write dirty blocks to data files during truncate operations. 

David Kurtz has written about a specific Peoplesoft feature around truncate http://www.go-faster.co.uk/docs.htm#local_write_wait

 We migrated to using ASM disk and achieved significant benefits.

 The testing stages were

1)       Prepare a 2 hour Time and labour batch run which would generate significant throughput

2)       Capture a baseline at 10.2.0.3

3)       Upgrade to 10.2.0.4 and retest

4)       Upgrade to 10.2.0.4 and migrate to ASM (11.1.0.7) and retest

5)       Upgrade to 11.1.0.7 and migrate to ASM (11.1.0.7) and retest

 

Test 3 did not show any difference at all. We were still blocked on disk, which was expected. We probably would have remained at 10.2.0.3 but gone to ASM but there are problems with seeing ASM disk when using 10.2.0.3 (Metalink Note 434500, ORA-15059) so we had the option of applying a fix to get ASM working with 10.2.0.3 or upgrading to 10.2.0.4. We decided that the benefits of getting onto a terminal release and suggestions from Oracle that small changes in the truncate process had been made between 10.2.0.3 and 10.2.0.4 out-weighed the overhead of any application testing that we needed to do.

Test 4 gave us big performance benefits. Test 5 was not as clear cut but we knew some code had to be optimised and we did not have the luxury of time to address the issues. Remaining on 10g minimised the application testing, certainly compared to the testing require to upgrade to 11g.

The benefits can be seen quite clearly in the graph below

asynch_io

This shows a 2 hour period where a constant throughput of T&L jobs were being processed. In parallel a constant online load was being simulated

The black line shows throughput and elapsed time. The run consists of a number of jobs which take 2 hours to complete and batch time is around the 450 - 600 second mark

The same processing is then run with 10.2.0.4 database and ASM. disk_aysnch_io is set to FALSE. The jobs complete 40 minutes faster and elapsed time is around the 300-400 second mark but showing spikes and inconsistent performance

Finally the orange line shows 10.2.0.4 database and ASM. disk_aysnch_io =TRUE. The processing time has now been reduced to just over an hour and the elapsed time is significantly better at an average of 250 seconds and with a very consistent profile.

As with all things in life we have now moved onto the next bottleneck which is the wait flashback buf free caused because we have enabled flashback logging and as the redo log buffer fills up we wait for flashback to be written out. However this is a miniscule issue compared to the original problems.  We have taken flashback off some tablespaces primarily used for PS temporary tables (aka working storage tables) although that does give us an issue when when rebuilding the primary database after a DataGuard failover using flashback logs

I hope this real world example is of use

h1

Managing control files in ASM

September 28, 2009

Just a couple of notes on how to create multiple ASM control files and moving control files toa different diskgroup.

Assuming we already have a ASM control file in the DATA diskgroup and we wish to add one to the FRA diskgroup

 SQL>show parameter control_files
+DATA/SID/controlfile/current.730.698514673
alter system set control_files='+DATA','+FRA' scope=spfile;
shutdown immediate;
startup nomount;
exit
rman target
/restore controlfile from '+DATAHR/MHRPRD1A/CONTROLFILE/current.730.698514673';
alter database mount;
alter database open;
SQL>show parameter control_files
+DATA/SID/controlfile/current.730.698514673, +FRAHR/SID/controlfile/current.766.698514673

 

                                                                           

Here is an example of how to migrate from one ASM diskgroup to another

Add the new disk discovery path in (if needed), create a diskgroup and add disks

alter system set asm_diskstring='/dev/oracle','/dev/oracle_hr/r*';

create diskgroup DATANEW  external redundancy disk '/dev/oracle_hr/rdisk1','/dev/oracle_hr/rdisk2';

SQL>show parameter control_files

control_files                        string      +DATA10/SID/controlfile/c urrent.796.695384211
alter system set CONTROL_FILES = '+DATANEW' scope=spfile

shutdown
rman target /
startup nomount
restore controlfile  from  '/+DATA/SID/controlfile/current.796.695384211';
alter database mount;
alter database open;
h1

Regressing an Opatch version

September 18, 2009

According to Metalink the only supported  way to regress to the version of Opatch that was installed is to re-install. However Opatch is a self-contained directory and the contents can be copied from another base installation.

Why would I want to regress the Opatch version. Let me explain with the commands I used.

Database version 10.2.0.4 (which gives opatch version 10.2.0.4.3)  

I wanted to install the PSU patch which requires a leter version of opatch (10.2.0.4.7). What I should have done was copy the opatch folder and save ready for a restore. However I didn’t and when the PSU patch failed due to issues with previously applied patches I had trouble applying the April 2009 CPU patch.

I followed these steps to resolve the problem

Secure existing folder and remove contents

cd $ORACLE_HOME

tar cvf OPatch.20090917_local.tar ./OPatch

rm -R OPatch

Logon onto the remote server and tar the OPatch folder up and ftp to the local server. Note use a different name for the tar file so as not to overwrite the tar files that you have just created.

tar cvf OPatch.20090917_remote.tar ./OPatch

Back on the local server unzip the tar file and check the version of opatch

tar xvf OPatch.20090917_remote.tar 

a./OPatch/docs/FAQ 31 blocks
a ./OPatch/docs/Users_Guide.txt 38 blocks
a ./OPatch/docs/Prereq_Users_Guide.txt 25 blocks
a ./OPatch/jlib/opatch.jar 1415 blocks
a ./OPatch/jlib/opatchutil.jar 270 blocks
a ./OPatch/jlib/opatchprereq.jar 242 blocks
a ./OPatch/jlib/opatchactions.jar 142 blocks
a ./OPatch/opatch 14 blocks
a ./OPatch/opatch.pl 6 blocks
a ./OPatch/opatch.ini 1 blocks
a ./OPatch/emdpatch.pl 38 blocks
a ./OPatch/opatchprereqs/oui/knowledgesrc.xml 2 blocks
a ./OPatch/opatchprereqs/opatch/opatch_prereq.xml 60 blocks
a ./OPatch/opatchprereqs/opatch/rulemap.xml 5 blocks
a ./OPatch/opatchprereqs/opatch/runtime_prereq.xml 1 blocks
a ./OPatch/opatchprereqs/prerequisite.properties 1 blocks

opatch version
Invoking OPatch 10.2.0.4.3

OPatch Version: 10.2.0.4.3