Quantcast
Channel: Andrew's Oracle Blog
Viewing all 330 articles
Browse latest View live

A Simple Introduction to ADDM and AWR

$
0
0
ADDM was introduced in Oracle 10 and stands for Automatic Database Diagnostic Monitor. You can use it to help solve performance problems. I was looking through some old copies of Oracle Magazine, found an article about it, written by Kimberly Floss in May/June 2004, and decided to give it a try. The article provided some SQL to produce an ADDM report so I ran it against an Oracle 12 database which nobody was using:

SQL> select dbms_advisor.get_task_report
  2  (task_name, 'TEXT', 'ALL')
  3  as addm_report
  4  from dba_advisor_tasks
  5  where task_id=
  6  (select max(t.task_id)
  7   from dba_advisor_tasks t,
  8     dba_advisor_log l
  9   where t.task_id = l.task_id
 10  and t.advisor_name = 'ADDM'
 11  and l.status = 'COMPLETED')
 12  /
 
ADDM_REPORT                                                                     
--------------------------------------------------------------------------------
          ADDM Report for Task 'ADDM:1254537384_1_154'                         
          --------------------------------------------                         
                                                                                
Analysis Period                                                                
---------------                                                                 
AWR snapshot range from 153 to 154.                                            
Time period starts at 02-APR-15 18.00.56                                       
Time period ends at 02-APR-15 19.00.11                                          
                                                                                
Analysis Target                                                                
---------------                                                                 
Database 'ORCL1' with DB ID 1254537384.                                        
Database version 12.1.0.1.0.                                                   
ADDM performed an analysis of instance orcl1, numbered 1 and hosted at         
WIN-HUVS4H99T56.                                                               
                                                                                
Activity During the Analysis Period                                            
-----------------------------------                                            
Total database time was 0 seconds.                                             
The average number of active sessions was 0.                                   
                                                                                
                                                                                
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
                                                                                
There are no findings to report.                                               
                                                                                
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
                                                                                
          Additional Information                                               
          ----------------------                                               
                                                                                
Miscellaneous Information                                                      
-------------------------                                                      
There was no significant database activity to run the ADDM.                    
                                                                                
The database's maintenance windows were active during 99% of the analysis      
period.                                                                        
                                                                                
                                                                                
 
SQL> 

This said that there was nothing to report, as you might expect. The following lines refer to an AWR snapshot:

AWR snapshot range from 153 to 154.
Time period starts at 02-APR-15 18.00.56 
Time period ends at 02-APR-15 19.00.11 

AWR stands for Automatic Workload Repository, which was also introduced in Oracle 10. A snapshot of this is taken every hour by default and ADDM uses these snapshots to produce its reports.
 
In the example above, the ADDM report had no recommendations but, in the normal course of events, you will be running ADDM on databases with problems. In this case, you might see output like this, which came from a Windows server trying to host 6 good-sized Oracle 11 databases with only 12 gigabytes of RAM:                                         
 
          Findings and Recommendations
          ----------------------------
 
Finding 1: Virtual Memory Paging
Impact is .22 active sessions, 100% of total activity.
------------------------------------------------------
Significant virtual memory paging was detected on the host operating system.
 
   Recommendation 1: Host Configuration
   Estimated benefit is .22 active sessions, 100% of total activity.
   -----------------------------------------------------------------
   Action
      Host operating system was experiencing significant paging but no
      particular root cause could be detected. Investigate processes that do
      not belong to this instance running on the host that are consuming
      significant amount of virtual memory. Also consider adding more physical
      memory to the host. 

The next example came from a third-party application which was doing lots of COMMIT’s (sometimes up to 1000 each second): 

Finding 3: Commits and Rollbacks
Impact is .47 active sessions, 34.34% of total activity.
--------------------------------------------------------
Waits on event "log file sync" while performing COMMIT and ROLLBACK operations
were consuming significant database time.
 
   Recommendation 1: Application Analysis
   Estimated benefit is .47 active sessions, 34.34% of total activity.
   -------------------------------------------------------------------
   Action
      Investigate application logic for possible reduction in the number of
      COMMIT operations by increasing the size of transactions.
   Rationale
      The application was performing 9966 transactions per minute with an
      average redo size of 1240 bytes per transaction.
 
   Recommendation 2: Host Configuration
   Estimated benefit is .47 active sessions, 34.34% of total activity.
   -------------------------------------------------------------------
   Action
      Investigate the possibility of improving the performance of I/O to the
      online redo log files.
   Rationale
      The average size of writes to the online redo log files was 3 K and the
      average time per write was 10 milliseconds.
   Rationale
      The total I/O throughput on redo log files was 217 K per second for
      reads and 446 K per second for writes.
   Rationale
      The redo log I/O throughput was divided as follows: 0% by RMAN and
      recovery, 67% by Log Writer, 0% by Archiver, 0% by Streams AQ and 32% by
      all other activity.
 
   Symptoms That Led to the Finding:
   ---------------------------------
      Wait class "Commit" was consuming significant database time.
      Impact is .47 active sessions, 34.34% of total activity. 

You might take quite a while to work out problems like these but, by using ADDM, you can diagnose them quickly. I will look at further examples in future posts.

The Right and Wrong Ways to Add a NOT NULL Constraint

$
0
0
I tested these examples in an Oracle 11.2 database. The first one shows how to add a NOT NULL constraint retrospectively. You start by creating a table:

SQL> create table andrew (col1 varchar2(1))
  2  /
 
Table created.
 
SQL>

Then at some point in the future, you add a NOT NULL constraint like this:

SQL> alter table andrew modify (col1 not null)
  2  /
 
Table altered.
 
SQL>

Doing it this way, the constraint is obvious when you describe the table:

SQL> desc andrew
Name                       Null?    Type
-------------------------- -------- ------------------
COL1                       NOT NULL VARCHAR2(1)
 
SQL>

… and, if you try to add a null value, the error message is self-explanatory:

SQL> insert into andrew values (null)
  2  /
insert into andrew values (null)
                           *
ERROR at line 1:
ORA-01400: cannot insert NULL into ("ORACLE"."ANDREW"."COL1")
 
SQL> 

The second example, which I saw recently, shows how NOT to do it. You start, as before, by creating a table:

SQL> create table fred (col1 varchar2(1))
  2  /
 
Table created.
 
SQL>

… then you add a CHECK constraint as follows:

SQL> alter table fred
  2  add constraint con1
  3  check (col1 is not null)
  4  /
 
Table altered.
 
SQL>

You cannot see this constraint when you describe the table:

SQL> desc fred
Name                       Null?    Type
-------------------------- -------- ------------------
COL1                                VARCHAR2(1)
 
SQL>

… and when you try to add a null value, the error message is not very helpful:

SQL> insert into fred values (null)
  2  /
insert into fred values (null)
*
ERROR at line 1:
ORA-02290: check constraint (ORACLE.CON1) violated
 
SQL>

ORA-01075

$
0
0
I tried to log on to an Oracle 11.2 test database, which the developers could no longer use, and saw the following error:

MDMDEV1 /export/home/oracle > sqlplus / as sysdba
 
SQL*Plus: Release 11.2.0.2.0 Production on Fri Mar 28 09:41:24 2014
 
Copyright (c) 1982, 2010, Oracle.  All rights reserved.
 
ERROR:
ORA-01075: you are currently logged on
 
Enter user-name:

I looked in the alert log and saw several of the following messages:

Fri Mar 28 09:36:46 2014
Use ADRCI or Support Workbench to package the incident.
See Note 411.1 at My Oracle Support for error and packaging details.
Errors in file /oracle/app/oracle/product/diag/rdbms/mdmdev1/MDMDEV1/trace/MDMDEV1_smon_522.trc:
ORA-00604: error occurred at recursive SQL level 1
ORA-04031: unable to allocate 3896 bytes of shared memory ("shared pool","select count(*) from edition$","sga heap(1,0)","kglsim object batch")

I closed the database like this:

MDMDEV1 /export/home/oracle > sqlplus -prelim
 
SQL*Plus: Release 11.2.0.2.0 Production on Fri Mar 28 09:45:45 2014
 
Copyright (c) 1982, 2010, Oracle.  All rights reserved.
 
Enter user-name: / as sysdba
SQL> shutdown abort
ORACLE instance shut down.
SQL>

Then I opened the database again:

MDMDEV1 /export/home/oracle > sqlplus / as sysdba
 
SQL*Plus: Release 11.2.0.2.0 Production on Fri Mar 28 09:49:39 2014
 
Copyright (c) 1982, 2010, Oracle.  All rights reserved.
 
Connected to an idle instance.
 
SQL> startup
ORA-32004: obsolete or deprecated parameter(s) specified for RDBMS instance
ORACLE instance started.
 
Total System Global Area  534462464 bytes
Fixed Size                  2225832 bytes
Variable Size             390072664 bytes
Database Buffers          134217728 bytes
Redo Buffers                7946240 bytes
Database mounted.
Database opened.
SQL> 

... and the developers could login again.

ORA-39095

$
0
0
I kicked off an expdp with the following parameters. I set the filesize parameter but forgot to set the dumpfile parameter to match:

content=all
directory=data_pump_dir
dumpfile=andrew.dmp
exclude=table:"='DOCUMENTIMAGE'"
filesize=1000000000
full=y          
logfile=andrew.log

The job produced 1 file with the filesize I had specified:

D:\oracle\11.2.0\admin\AKTPROD\dpdump>dir andrew.dmp
Volume in drive D is Datas
Volume Serial Number is ECE8-9011
 
Directory of D:\oracle\11.2.0\admin\AKTPROD\dpdump
 
05/15/2015  12:20 PM       999,997,440 ANDREW.DMP
               1 File(s)    999,997,440 bytes
               0 Dir(s)  414,961,401,856 bytes free
 
D:\oracle\11.2.0\admin\AKTPROD\dpdump>

Then it failed with an ORA-39095:

ORA-39095: Dump file space has been exhausted: Unable to allocate 4096 bytes
Job "SYSTEM"."SYS_EXPORT_FULL_01" stopped due to fatal error at 12:20:13

I changed the dumpfile parameter as follows and reran the expdp:

content=all
directory=data_pump_dir
dumpfile=andrew%u.dmp
exclude=table:"='DOCUMENTIMAGE'"
filesize=1000000000
full=y
logfile=andrew.log

The %u was replaced by the numbers 01 through 99 inclusive as required and the expdp worked, producing 88 files:

D:\oracle\11.2.0\admin\AKTPROD\dpdump>dir andrew*.dmp
Volume in drive D is Datas
Volume Serial Number is ECE8-9011
 
Directory of D:\oracle\11.2.0\admin\AKTPROD\dpdump
 
05/15/2015  01:07 PM       999,997,440 ANDREW01.DMP
05/15/2015  12:59 PM       999,997,440 ANDREW02.DMP
05/15/2015  01:01 PM       999,997,440 ANDREW03.DMP
05/15/2015  01:01 PM       999,997,440 ANDREW04.DMP
05/15/2015  01:01 PM       999,997,440 ANDREW05.DMP
05/15/2015  01:02 PM       999,997,440 ANDREW06.DMP
05/15/2015  01:02 PM       999,997,440 ANDREW07.DMP
05/15/2015  01:02 PM       999,997,440 ANDREW08.DMP
05/15/2015  01:02 PM       999,997,440 ANDREW09.DMP
05/15/2015  01:03 PM       999,997,440 ANDREW10.DMP
Etc.
05/15/2015  01:32 PM       999,997,440 ANDREW80.DMP
05/15/2015  01:33 PM       999,997,440 ANDREW81.DMP
05/15/2015  01:33 PM       999,997,440 ANDREW82.DMP
05/15/2015  01:33 PM       999,997,440 ANDREW83.DMP
05/15/2015  01:34 PM       999,997,440 ANDREW84.DMP
05/15/2015  01:34 PM       999,997,440 ANDREW85.DMP
05/15/2015  01:35 PM       999,997,440 ANDREW86.DMP
05/15/2015  01:36 PM       999,997,440 ANDREW87.DMP
05/15/2015  01:38 PM       829,038,592 ANDREW88.DMP
              88 File(s) 87,828,815,872 bytes
               0 Dir(s)  326,559,186,944 bytes free
 
D:\oracle\11.2.0\admin\AKTPROD\dpdump>

I will try to look at what happens if you need more than 99 files in a future post.

PL/SQL lock timer

$
0
0
I was looking through V$SYSTEM_EVENT on an Oracle 11.2 production database (as you do) and I noticed that it had waited for exactly 1 second on the PL/SQL lock timer event. Apparently this is the amount of time a database has been waiting for sessions which have been told to sleep by their application. I decided to check this out so I started a new session, slept for 6.7 seconds then looked to see how long my session had been waiting on this event:

SQL> conn /
Connected.
SQL> exec dbms_lock.sleep(6.7);
 
PL/SQL procedure successfully completed.
 
SQL> select time_waited/100
  2  from v$session_event
  3  where event = 'PL/SQL lock timer'
  4  and sid = (select distinct sid from v$mystat)
  5  /
 
TIME_WAITED/100
---------------
           6.71
 
SQL>
 

Oracle Pipes (Part 1)

$
0
0
Oracle pipes use the DBMS_PIPE package to allow one session to communicate with another. I decided to try this out in an Oracle 11.1 database. Pipes can be public or private. This example only looks at public pipes. First I created a user called ANDREW. I gave it SELECT ANY DICTIONARY so that it could look at V$DB_PIPES and I allowed it to execute DBMS_PIPE so that it would be able to create a pipe: 

SQL> conn / as sysdba
Connected.
SQL> create user andrew identified by reid
  2  /
 
User created.
 
SQL> grant create session to andrew
  2  /
 
Grant succeeded.
 
SQL> grant select any dictionary to andrew
  2  /
 
Grant succeeded.
 
SQL> grant execute on sys.dbms_pipe to andrew
  2  /
 
Grant succeeded.
 
SQL> 

Then I logged in as the user and queried V$DB_PIPES to ensure there were no pipes in the database to begin with: 

SQL> conn andrew/reid
Connected.
SQL> col name format a20
SQL> select * from v$db_pipes
  2  /
 
no rows selected
 
SQL>
 
I used DBMS_PIPE.PACK_MESSAGE to create a message then I used DBMS_PIPE.SEND_MESSAGE to send it down a pipe, which I called ANDREWS_PIPE. If you do it this way, Oracle creates the pipe implicitly with the name you provide: 

SQL> declare
  2   result number;
  3  begin
  4   dbms_pipe.pack_message('Andrew was here');
  5   result := dbms_pipe.send_message('andrews_pipe');
  6  end;
  7  /
 
PL/SQL procedure successfully completed.
 
SQL> 

I queried V$DB_PIPES again and saw that Oracle had created the pipe: 

SQL> select * from v$db_pipes
  2  /
 
   OWNERID NAME                 TYPE     PIPE_SIZE
---------- -------------------- ------- ----------
           ANDREWS_PIPE         PUBLIC        1621
 
SQL>

I decided that I did not want the pipe any more so I flushed the shared pool:

SQL> conn / as sysdba
Connected.
SQL> alter system flush shared_pool
  2  /
 
System altered.
 
SQL>

I just did this to show that flushing the shared pool by itself does not remove a pipe. To prove this, I queried V$DB_PIPES again and saw that the pipe was still there:

SQL> select * from v$db_pipes
  2  /
 
   OWNERID NAME                 TYPE     PIPE_SIZE
---------- -------------------- ------- ----------
           ANDREWS_PIPE         PUBLIC        1621
 
SQL>

Then I used DBMS_PIPE.PURGE to clear the contents of the pipe:

SQL> exec dbms_pipe.purge('andrews_pipe');
 
PL/SQL procedure successfully completed.
 
SQL>

Once you have done this, an implicitly created pipe can be aged out of the SGA. I queried V$DB_PIPES and saw that the pipe was still there:

SQL> select * from v$db_pipes
  2  /
 
   OWNERID NAME                 TYPE     PIPE_SIZE
---------- -------------------- ------- ----------
           ANDREWS_PIPE         PUBLIC        1621
 
SQL> 

I wanted to finish this test but did not have time for the pipe to be aged out of the SGA so I flushed the shared pool to speed things along: 

SQL> alter system flush shared_pool
  2  /
 
System altered.
 
SQL>

… and when I queried V$DB_PIPES again, the pipe had gone:

SQL> select * from v$db_pipes
  2  /
 
no rows selected
 
SQL>
 
(More to follow…)

ALTER DATABASE ADD SUPPLEMENTAL LOG DATA Hangs

$
0
0
This post demonstrates that if a database has an unfinished transaction and you try to run the above-mentioned command, it will hang. I logged into an Oracle 11 database, started a transaction but did not COMMIT it in the red session below:

PQEDPT1 /export/home/oracle > sqlplus /
 
SQL*Plus: Release 11.1.0.6.0 - Production on Mon Jun 8 14:55:54 2015
 
Copyright (c) 1982, 2007, Oracle.  All rights reserved.
 
 
Connected to:
Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
 
SQL> create table andrew
  2  as select * from dba_tables
  3  where 1=2
  4  /
 
Table created.
 
SQL> insert into andrew
  2  select * from dba_tables
  3  /
 
15251 rows created.
 
I started the blue session below and tried to run an ALTER DATABASE ADD SUPPLEMENTAL LOG DATA command but it did not appear to be doing anything:

PQEDPT1 /export/home/oracle > sqlplus / as sysdba
 
SQL*Plus: Release 11.1.0.6.0 - Production on Mon Jun 8 15:01:47 2015
 
Copyright (c) 1982, 2007, Oracle.  All rights reserved.
 
 
Connected to:
Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
 
SQL> alter database add supplemental log data
  2  /

I started the green session below and saw that the blue session was waiting for events in waitclass Other:

PQEDPT1 /export/home/oracle > sqlplus /
 
SQL*Plus: Release 11.1.0.6.0 - Production on Mon Jun 8 15:23:52 2015
 
Copyright (c) 1982, 2007, Oracle.  All rights reserved.
 
 
Connected to:
Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
 
SQL> select time_waited/100
  2  from v$session_event
  3  where event = 'events in waitclass Other'
  4  and sid =
  5  (select sid from v$session where username = 'SYS')
  6  /
 
TIME_WAITED/100
---------------
        1312.97
 
SQL> /
 
TIME_WAITED/100
---------------
        1321.79
 
SQL> /
 
TIME_WAITED/100
---------------
        1330.59
 
SQL> 

This was not particularly helpful but, fortunately for me, I knew that the blue session was waiting for the red session’s transaction to finish. I returned to it and did a COMMIT:

PQEDPT1 /export/home/oracle > sqlplus /
 
SQL*Plus: Release 11.1.0.6.0 - Production on Mon Jun 8 14:55:54 2015
 
Copyright (c) 1982, 2007, Oracle.  All rights reserved.
 
 
Connected to:
Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
 
SQL> create table andrew
  2  as select * from dba_tables
  3  where 1=2
  4  /
 
Table created.
 
SQL> insert into andrew
  2  select * from dba_tables
  3  /
 
15251 rows created.
 
SQL> commit
  2  /
 
Commit complete.
 
SQL>

… and the blue session’s command completed:

PQEDPT1 /export/home/oracle > sqlplus / as sysdba
 
SQL*Plus: Release 11.1.0.6.0 - Production on Mon Jun 8 15:01:47 2015
 
Copyright (c) 1982, 2007, Oracle.  All rights reserved.
 
 
Connected to:
Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
 
SQL> alter database add supplemental log data
  2  /
 
Database altered.
 
SQL>

ORA-12838

$
0
0
If you do an INSERT /* APPEND */, you cannot query the table afterwards until you have done a COMMIT. If you try to do so, Oracle gives you an ORA-12838. You can see what I mean in the example below, which I tested on Oracle 11.2:

SQL> create table tab1
  2  as select * from dba_tables
  3  where 1 = 2
  4  /
 
Table created.
 
SQL> insert /*+ append */ into tab1
  2  select * from dba_tables
  3  /
 
3166 rows created.
 
SQL> select count(*) from tab1
  2  /
select count(*) from tab1
                     *
ERROR at line 1:
ORA-12838: cannot read/modify an object after
modifying it in parallel
 
SQL> commit
  2  /
 
Commit complete.
 
SQL> select count(*) from tab1
  2  /
 
  COUNT(*)
----------
      3166
 

INSERT /*+ APPEND */

$
0
0
This example demonstrates that an INSERT /*+ APPEND */ does not put rows into free space within a table, it adds them at the end instead. It also shows that Oracle inserts these rows using a DIRECT PATH mechanism. I tested it on Oracle 11.2. First I created an empty table:

SQL> conn /
Connected.
SQL> create table tab1
  2  as select * from dba_tables
  3  where 1 = 2
  4  /
 
Table created.
 
SQL>

Then I added the contents of DBA_TABLES 50 times. I did this using a normal INSERT statement:

SQL> begin
  2  for x in 1..50 loop
  3  insert into tab1
  4  select * from dba_tables;
  5  commit;
  6  end loop;
  7  end;
  8  /
 
PL/SQL procedure successfully completed.
 
SQL>

I deleted all the rows so the table would contain nothing but free space. Then I checked how big it was:

SQL> delete tab1
  2  /
 
158150 rows deleted.
 
SQL> select bytes from user_segments
  2  where segment_name = 'TAB1'
  3  /
 
     BYTES
----------
  46137344
 
SQL>

I started a new session to zeroise my statistics then I reinserted the same data. This time I used an INSERT /*+ APPEND */ so that Oracle would add the rows to the end of the table, instead of putting them in the free space I had just created:

SQL> conn /
Connected.
SQL> begin
  2  for x in 1..50 loop
  3  insert /*+ append */ into tab1
  4  select * from dba_tables;
  5  commit;
  6  end loop;
  7  end;
  8  /
 
PL/SQL procedure successfully completed.
 
SQL>

I checked the session’s wait events and they showed that a DIRECT PATH WRITE had been chosen:

SQL> select event, time_waited/100
  2  from v$session_event
  3  where sid = (select distinct sid from v$mystat)
  4  order by 1
  5  /
 
EVENT                               TIME_WAITED/100
----------------------------------- ---------------
Disk file operations I/O                        .02
SQL*Net message from client                     .01
SQL*Net message to client                         0
db file sequential read                         .67
direct path sync                                  0
direct path write                                .4
events in waitclass Other                       .11
log file sync                                     0
 
8 rows selected.
 
SQL>

Finally, I rechecked the size of the table. If the INSERT /*+ APPEND */ had put the rows in the free space, the size would have been unchanged. However, the table was twice as big, proving that the data had been added at the end of the table:

SQL> select bytes from user_segments
  2  where segment_name = 'TAB1'
  3  /
 
     BYTES
----------
100663296
 
SQL>

A Simple Example Using COMPUTE SUM OF in SQL*Plus

$
0
0
I needed some SQL to show the time spent on idle events in an Oracle 11.2 database with a grand total at the end. I wrote this as shown below. The SQL*Plus syntax at the start is taken from the Oracle documentation but I wanted to record it so I would have my own worked example for future use: 

SQL> column dummy noprint;
SQL> compute sum of seconds_waited on dummy;
SQL> break on dummy;
SQL> select null dummy, event idle_event,
  2  round(time_waited/100) seconds_waited
  3  from v$system_event
  4  where wait_class = 'Idle'
  5  and round(time_waited/100) > 0
  6  order by seconds_waited
  7  /
 
IDLE_EVENT                                                       SECONDS_WAITED
---------------------------------------------------------------- --------------
PX Deq: Parse Reply                                                           1
SGA: MMAN sleep for component shrink                                          1
single-task message                                                           5
PX Deq: Execution Msg                                                         7
JOX Jit Process Sleep                                                       108
PL/SQL lock timer                                                           260
PX Idle Wait                                                               6000
jobq slave wait                                                           11025
VKRM Idle                                                                 14400
Streams AQ: waiting for time management or cleanup tasks                  75954
Space Manager: slave idle wait                                            77450
smon timer                                                                77459
pmon timer                                                                77657
Streams AQ: waiting for messages in the queue                             77671
Streams AQ: qmn slave idle wait                                           77729
Streams AQ: qmn coordinator idle wait                                     77740
DIAG idle wait                                                           155195
pipe get                                                                 241269
rdbms ipc message                                                       1319628
SQL*Net message from client                                            10756842
                                                                 --------------
                                                                       13046401
 
20 rows selected.
 
SQL>

Virtual Columns

$
0
0
Oracle 11g allows you to create virtual columns in a table. Values are not stored for these columns, Oracle calculates them at runtime. You can see the expression used to generate the value in the DATA_DEFAULT column of the USER_TAB_COLUMNS view.

As you might expect, you cannot UPDATE virtual columns directly. If you try, you get an ORA-54017.
 
It isn’t quite so obvious but you cannot use a virtual column to generate the value of another virtual column either. If you try, you get an ORA-54012
 
SQL> create table tab1
  2  (col1 number,
  3   col2 number,
  4   col3 number generated always
  5   as (col1 + col2) virtual)
  6  /
 
Table created.
 
SQL> insert into tab1(col1,col2) values(1,2)
  2  /
 
1 row created.
 
SQL> select * from tab1
  2  /
 
      COL1       COL2       COL3
---------- ---------- ----------
         1          2          3
 
SQL> column column_name format a15
SQL> column data_default format a15
SQL> select column_name, data_default
  2  from user_tab_columns
  3  where table_name = 'TAB1'
  4  /
 
COLUMN_NAME     DATA_DEFAULT
--------------- ---------------
COL1
COL2
COL3            "COL1"+"COL2"
 
SQL> update tab1 set col3 = 4
  2  /
update tab1 set col3 = 4
       *
ERROR at line 1:
ORA-54017: UPDATE operation disallowed on virtual
columns
 
SQL> drop table tab1
  2  /
 
Table dropped.
 
SQL> create table tab1
  2  (col1 number,
  3   col2 number,
  4   col3 number generated always
  5   as (col1 + col2) virtual,
  6   col4 number generated always
  7   as (col1 + col3) virtual)
  8  /
col3 number generated always
*
ERROR at line 4:
ORA-54012: virtual column is referenced in a column
expression
 
SQL>

ORA-39001, ORA-39000 and ORA-39142

$
0
0
I exported 3 large tables from an Oracle 11.2.0.4.0 database then tried to import them into an Oracle 11.1.0.6.0 database but the impdp failed as follows:

PQECOG3 /database/DB_exports/andrew > impdp / parfile=params
 
Import: Release 11.1.0.6.0 - 64bit Production on Wednesday, 22 July, 2015 11:37:44
 
Copyright (c) 2003, 2007, Oracle.  All rights reserved.
 
Connected to: Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
ORA-39001: invalid argument value
ORA-39000: bad dump file specification
ORA-39142: incompatible version number 3.1 in dump file "/database/DB_exports/andrew/andrew.dmp"
 
PQECOG3 /database/DB_exports/andrew >

You get these errors when you try to import a dump file produced by a newer version of Oracle. I added the version parameter at the end of the expdp parameter file. Incidentally, in case it isn't obvious, I have called both my parameter files params. However, they are on different servers and contain different parameters:

GBDMVDP1 /cisdpt/gbdmvdp1/datapump > cat params
content=all
directory=datapump
dumpfile=andrew.dmp
logfile=andrew.log
schemas=dmv
include=table:"in('S0141_BPD','D296_1234','D81_894')"
version=11.1.0.6.0
GBDMVDP1 /cisdpt/gbdmvdp1/datapump >

Then I reran the expdp and this produced a dumpfile which would be suitable for an Oracle 11.1.0.6.0 database. When I tried the impdp again, it worked:

PQECOG3 /database/DB_exports/andrew > impdp / parfile=params
 
Import: Release 11.1.0.6.0 - 64bit Production on Wednesday, 22 July, 2015 15:27:55
 
Copyright (c) 2003, 2007, Oracle.  All rights reserved.
 
Connected to: Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
Master table "ELEC_ORACLE"."SYS_IMPORT_FULL_01" successfully loaded/unloaded
Starting "ELEC_ORACLE"."SYS_IMPORT_FULL_01":  /******** parfile=params
Processing object type SCHEMA_EXPORT/TABLE/TABLE
Processing object type SCHEMA_EXPORT/TABLE/TABLE_DATA
. . imported "SRCE"."D296_1234"                          8.964 GB 289960470 rows
. . imported "SRCE"."D81_894"                            8.215 GB 267028514 rows
. . imported "SRCE"."S0141_BPD"                          2.384 GB 25849859 rows
Etc
Etc

ALTER DATABASE BEGIN BACKUP and ALTER DATABASE END BACKUP

$
0
0
I logged into an Oracle 12.1 database, checked it was in ARCHIVELOG mode then ran the ALTER DATABASE BEGIN BACKUP command. This told Oracle I was about to do a hot backup:

C:\Users\Andrew>sqlplus / as sysdba
 
SQL*Plus: Release 12.1.0.1.0 Production on Wed Mar 18 14:45:56 2015
 
Copyright (c) 1982, 2013, Oracle.  All rights reserved.
 
Connected to:
Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options
 
SQL> select log_mode from v$database
  2  /
 
LOG_MODE
------------
ARCHIVELOG
 
SQL> alter database begin backup
  2  /
 
Database altered.
 
SQL>

I copied the database’s datafiles to somewhere safe. I didn’t bother about the control files or the redo log files as I didn’t intend to do anything to them in this example. Clearly, if you try this yourself, you need to work out where the datafiles are beforehand:

C:\app\Administrator\oradata\ORCL1\DATAFILE>copy * Z:\Data\Oracle_Backup
O1_MF_SYSAUX_BDGVW9OT_.DBF
O1_MF_SYSTEM_BDGVZ93W_.DBF
O1_MF_TEMP_BDGW88KG_.TMP
O1_MF_UNDOTBS1_BDGW2MY6_.DBF
O1_MF_USERS_BDGW2LNZ_.DBF
        5 file(s) copied.
 
C:\app\Administrator\oradata\ORCL1\DATAFILE>

I created a MARKER table to prove that the backup and restore had worked as planned:

SQL> create table marker as
  2  select 'Andrew was here' message
  3  from dual
  4  /
 
Table created.
 
SQL>

Then I used the ALTER DATABASE END BACKUP command to tell Oracle the hot backup was finished and closed the database:

SQL> alter database end backup;
 
Database altered.
 
SQL> shutdown
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL>

I deleted the database’s datafiles:

C:\app\Administrator\oradata\ORCL1\DATAFILE>dir
Volume in drive C has no label.
Volume Serial Number is 269C-9AD9
 
Directory of C:\app\Administrator\oradata\ORCL1\DATAFILE
 
27/01/2015  11:05    <DIR>          .
27/01/2015  11:05    <DIR>          ..
18/03/2015  15:09     3,722,452,992 O1_MF_SYSAUX_BDGVW9OT_.DBF
18/03/2015  15:09       964,698,112 O1_MF_SYSTEM_BDGVZ93W_.DBF
18/03/2015  14:27     1,906,319,360 O1_MF_TEMP_BDGW88KG_.TMP
18/03/2015  15:09     1,378,885,632 O1_MF_UNDOTBS1_BDGW2MY6_.DBF
18/03/2015  15:09     4,650,442,752 O1_MF_USERS_BDGW2LNZ_.DBF
               5 File(s) 12,622,798,848 bytes
               2 Dir(s)   6,003,765,248 bytes free
 
C:\app\Administrator\oradata\ORCL1\DATAFILE>del *.*
C:\app\Administrator\oradata\ORCL1\DATAFILE\*.*, Are you sure (Y/N)? y
 
C:\app\Administrator\oradata\ORCL1\DATAFILE>

Then I restored them from the backup which I made earlier. Again, if you are doing this yourself, you need to work out which files have been lost before you can restore them:

Z:\Data\Oracle_Backup>copy *.* C:\app\Administrator\oradata\ORCL1\DATAFILE
O1_MF_SYSAUX_BDGVW9OT_.DBF
O1_MF_SYSTEM_BDGVZ93W_.DBF
O1_MF_TEMP_BDGW88KG_.TMP
O1_MF_UNDOTBS1_BDGW2MY6_.DBF
O1_MF_USERS_BDGW2LNZ_.DBF
        5 file(s) copied.
 
Z:\Data\Oracle_Backup>

Finally, I mounted the database, recovered it, opened it and confirmed that the MARKER table was still there:

Z:\Data\Oracle_Backup>sqlplus / as sysdba
 
SQL*Plus: Release 12.1.0.1.0 Production on Wed Mar 18 15:50:55 2015
 
Copyright (c) 1982, 2013, Oracle.  All rights reserved.
 
Connected to an idle instance.
 
SQL> startup mount
ORACLE instance started.
 
Total System Global Area 1720328192 bytes
Fixed Size                  2403496 bytes
Variable Size            1023411032 bytes
Database Buffers          687865856 bytes
Redo Buffers                6647808 bytes
Database mounted.
SQL> recover database
Media recovery complete.
SQL> alter database open
  2  /
 
Database altered.
 
SQL> select * from marker
  2  /
 
MESSAGE
---------------
Andrew was here
 
SQL>

Re-Creating Datafiles When Backups Are Unavailable

$
0
0
I found an old copy of the Oracle 9i User-Managed Backup and Recovery Guide and read the following:
 
If a datafile is damaged and no backup of the file is available, then you can still recover the datafile if:
 
·         All archived log files written after the creation of the original datafile are available
·         The control file contains the name of the damaged file (that is, the control file is current, or is a backup taken after the damaged datafile was added to the database)
 
I decided to try this out in an Oracle 12.1 database. First I checked that the database was in ARCHIVELOG mode:

SQL> select log_mode from v$database
  2  /
 
LOG_MODE
------------
ARCHIVELOG
 
SQL>

I created a tablespace called ANDREW:

SQL> create tablespace andrew
  2  datafile 'C:\APP\ADMINISTRATOR\ORADATA\ORCL1\DATAFILE\ANDREW.DBF'
  3  size 20m
  4  /
 
Tablespace created.
 
SQL>

I created a table in the tablespace:

SQL> l
  1  create table marker
  2  tablespace andrew as
  3  select 'Andrew was here again' message
  4* from dual
SQL> /
 
Table created.
 
SQL>

I closed the database:

SQL> shutdown
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL>

I deleted the tablespace’s datafile:

C:\app\Administrator\oradata\ORCL1\DATAFILE>dir
Volume in drive C has no label.
Volume Serial Number is 269C-9AD9
 
Directory of C:\app\Administrator\oradata\ORCL1\DATAFILE
 
19/03/2015  18:32    <DIR>          .
19/03/2015  18:32    <DIR>          ..
19/03/2015  18:39        20,979,712 ANDREW.DBF
19/03/2015  18:39     3,722,452,992 O1_MF_SYSAUX_BDGVW9OT_.DBF
19/03/2015  18:39       964,698,112 O1_MF_SYSTEM_BDGVZ93W_.DBF
19/03/2015  11:08     1,906,319,360 O1_MF_TEMP_BDGW88KG_.TMP
19/03/2015  18:39     1,378,885,632 O1_MF_UNDOTBS1_BDGW2MY6_.DBF
19/03/2015  18:39     4,650,442,752 O1_MF_USERS_BDGW2LNZ_.DBF
               6 File(s) 12,643,778,560 bytes
               2 Dir(s)   5,940,617,216 bytes free
 
C:\app\Administrator\oradata\ORCL1\DATAFILE>del andrew.dbf
 
C:\app\Administrator\oradata\ORCL1\DATAFILE>dir
Volume in drive C has no label.
Volume Serial Number is 269C-9AD9
 
Directory of C:\app\Administrator\oradata\ORCL1\DATAFILE
 
19/03/2015  18:42    <DIR>          .
19/03/2015  18:42    <DIR>          ..
19/03/2015  18:39     3,722,452,992 O1_MF_SYSAUX_BDGVW9OT_.DBF
19/03/2015  18:39       964,698,112 O1_MF_SYSTEM_BDGVZ93W_.DBF
19/03/2015  11:08     1,906,319,360 O1_MF_TEMP_BDGW88KG_.TMP
19/03/2015  18:39     1,378,885,632 O1_MF_UNDOTBS1_BDGW2MY6_.DBF
19/03/2015  18:39     4,650,442,752 O1_MF_USERS_BDGW2LNZ_.DBF
               5 File(s) 12,622,798,848 bytes
               2 Dir(s)   5,961,596,928 bytes free
 
C:\app\Administrator\oradata\ORCL1\DATAFILE>

I tried to open the database:

C:\app\Administrator\oradata\ORCL1\DATAFILE>sqlplus / as sysdba
 
SQL*Plus: Release 12.1.0.1.0 Production on Thu Mar 19 18:43:02 2015
 
Copyright (c) 1982, 2013, Oracle.  All rights reserved.
 
Connected to an idle instance.
 
SQL> startup
ORACLE instance started.
 
Total System Global Area 1720328192 bytes
Fixed Size                  2403496 bytes
Variable Size            1023411032 bytes
Database Buffers          687865856 bytes
Redo Buffers                6647808 bytes
Database mounted.
ORA-01157: cannot identify/lock data file 2 - see DBWR trace file
ORA-01110: data file 2:
'C:\APP\ADMINISTRATOR\ORADATA\ORCL1\DATAFILE\ANDREW.DBF'
 
SQL>
 
I created the missing datafile:

SQL> alter database create datafile
  2  'C:\APP\ADMINISTRATOR\ORADATA\ORCL1\DATAFILE\ANDREW.DBF'
  3  /
 
Database altered.
 
SQL>

I recovered the datafile:

SQL> recover datafile 'C:\APP\ADMINISTRATOR\ORADATA\ORCL1\DATAFILE\ANDREW.DBF'
Media recovery complete.
SQL>

I looked for the MARKER table but realized that the database was not open:

SQL> select * from marker
  2  /
select * from marker
              *
ERROR at line 1:
ORA-01219: database or pluggable database not open: queries allowed on fixed
tables or views only
 
SQL>
 
I opened the database:

SQL> alter database open
  2  /
 
Database altered.
 
SQL>

… and the MARKER table was there as before:

SQL> select * from marker
  2  /
 
MESSAGE
---------------------
Andrew was here again
 
SQL> select tablespace_name
  2  from dba_tables
  3  where table_name = 'MARKER'
  4  /
 
TABLESPACE_NAME
------------------------------
ANDREW
 
SQL>
 
The Oracle guide went on to say:
 
Note: You cannot re-create any of the datafiles for the SYSTEM tablespace by using the CREATE DATAFILE clause of the ALTER DATABASE statement because the necessary redo data is not available.
 
I will see what happens if you try to do this in a future post.

A Simple Example With V$BACKUP

$
0
0
I tested this in an Oracle 12.1 database. The V$BACKUP view tells you if a datafile is in hot backup mode. I started off with none of the datafiles in hot backup mode so they were all shown as NOT ACTIVE:

SQL> select file#, status from v$backup
  2  /
 
     FILE# STATUS
---------- ------------------
         1 NOT ACTIVE
         2 NOT ACTIVE
         3 NOT ACTIVE
         5 NOT ACTIVE
         6 NOT ACTIVE
 
SQL>

I put the USERS tablespace into hot backup mode and its datafile changed to ACTIVE in V$BACKUP until I took the tablespace out of hot backup mode:

SQL> alter tablespace users begin backup
  2  /
 
Tablespace altered.
 
SQL> select file_id from dba_data_files
  2  where tablespace_name = 'USERS'
  3  /
 
   FILE_ID
----------
         6
 
SQL> select file#, status from v$backup
  2  /
 
     FILE# STATUS
---------- ------------------
         1 NOT ACTIVE
         2 NOT ACTIVE
         3 NOT ACTIVE
         5 NOT ACTIVE
         6 ACTIVE
 
SQL> alter tablespace users end backup
  2  /
 
Tablespace altered.
 
SQL> select file#, status from v$backup
  2  /
 
     FILE# STATUS
---------- ------------------
         1 NOT ACTIVE
         2 NOT ACTIVE
         3 NOT ACTIVE
         5 NOT ACTIVE
         6 NOT ACTIVE
 
SQL>

… and when I put the whole database into hot backup mode, all the datafiles were shown as ACTIVE:

SQL> alter database begin backup
  2  /
 
Database altered.
 
SQL> select file#, status from v$backup
  2  /
 
     FILE# STATUS
---------- ------------------
         1 ACTIVE
         2 ACTIVE
         3 ACTIVE
         5 ACTIVE
         6 ACTIVE
 
SQL> alter database end backup
  2  /
 
Database altered.
 
SQL> select file#, status from v$backup
  2  /
 
     FILE# STATUS
---------- ------------------
         1 NOT ACTIVE
         2 NOT ACTIVE
         3 NOT ACTIVE
         5 NOT ACTIVE
         6 NOT ACTIVE
 
SQL>

RECOVER DATABASE TEST

$
0
0
I logged into an Oracle 12.1 database and ran the ALTER DATABASE BEGIN BACKUP command. This told Oracle I was about to start a hot backup:

C:\Users\Administrator>sqlplus / as sysdba
 
SQL*Plus: Release 12.1.0.1.0 Production on Thu Mar 26 10:08:51 2015
 
Copyright (c) 1982, 2013, Oracle.  All rights reserved.
 
Connected to:
Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options
 
SQL> alter database begin backup
  2  /
 
Database altered.
 
SQL>

I copied one of the database’s datafiles somewhere safe:

C:\app\Administrator\oradata\ORCL1\DATAFILE>copy O1_MF_USERS_BDGW2LNZ_.DBF z:\data\oracle_backup
        1 file(s) copied.
 
C:\app\Administrator\oradata\ORCL1\DATAFILE>

Then I used the ALTER DATABASE END BACKUP command to tell Oracle the hot backup was finished and closed the database:

SQL> alter database end backup;
 
Database altered.
 
SQL> shutdown
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL>

I deleted the datafile I had backed up:

C:\app\Administrator\oradata\ORCL1\DATAFILE>del O1_MF_USERS_BDGW2LNZ_.DBF
 
C:\app\Administrator\oradata\ORCL1\DATAFILE>

Then I restored it from the backup which I had made earlier:

Z:\Data\Oracle_Backup>copy O1_MF_USERS_BDGW2LNZ_.DBF C:\app\Administrator\oradata\ORCL1\DATAFILE
        1 file(s) copied.
 
Z:\Data\Oracle_Backup>

I mounted the database:

Z:\Data\Oracle_Backup>sqlplus / as sysdba
 
SQL*Plus: Release 12.1.0.1.0 Production on Wed Mar 18 15:50:55 2015
 
Copyright (c) 1982, 2013, Oracle.  All rights reserved.
 
Connected to an idle instance.
 
SQL> startup mount
ORACLE instance started.
 
Total System Global Area 1720328192 bytes
Fixed Size                  2403496 bytes
Variable Size            1023411032 bytes
Database Buffers          687865856 bytes
Redo Buffers                6647808 bytes
Database mounted.
SQL>

I read in some Oracle documentation that if you added the word TEST after a RECOVER command, you could test the recovery you were about to attempt. I decided to try it out but the messages it produced did not seem to tell me whether the recovery would succeed or fail:

SQL> recover database test
ORA-10574: Test recovery did not corrupt any data block
ORA-10573: Test recovery tested redo from change 11524259 to 11525796
ORA-10572: Test recovery canceled due to errors
ORA-10585: Test recovery can not apply redo that may modify control file
 
SQL>

I decided to give it a try anyway and it worked without problem:

SQL> recover database
Media recovery complete.
SQL> alter database open
  2  /
 
Database altered.
 
SQL>

Recursion in Oracle 12

$
0
0
Oracle 12 has a new parameter called PGA_AGGREGATE_LIMIT:

SQL> conn system/manager
Connected.
SQL> l
  1  select value from v$parameter
  2* where name = 'pga_aggregate_limit'
SQL> /
 
VALUE
--------------------
2147483648
 
SQL>

You cannot set it below 2 gigabytes:

SQL> alter system
  2  set pga_aggregate_limit = 1g;
alter system
*
ERROR at line 1:
ORA-02097: parameter cannot be modified because
specified value is invalid
ORA-00093: pga_aggregate_limit must be between 2048M
and 100000G
 
SQL> 

In earlier versions of Oracle, if you let recursive code get out of control, it could use up all the memory on the underlying server. I decided to try this out on Oracle 12:

SQL> create or replace procedure recursion is
  2  begin
  3  recursion();
  4  end;
  5  /
 
Procedure created.
 
SQL> exec recursion();

While this was running, I found I could still use the machine so I took a look in the alert log and saw the following errors at the end:

Thu Feb 12 17:43:34 2015
Errors in file C:\APP\ADMINISTRATOR\diag\rdbms\orcl1\orcl1\trace\orcl1_ora_2796.trc  (incident=19267):
ORA-04036: PGA memory used by the instance exceeds PGA_AGGREGATE_LIMIT
Incident details in: C:\APP\ADMINISTRATOR\diag\rdbms\orcl1\orcl1\incident\incdir_19267\orcl1_ora_2796_i19267.trc
Errors in file C:\APP\ADMINISTRATOR\diag\rdbms\orcl1\orcl1\trace\orcl1_ora_2796.trc  (incident=19268):
ORA-04036: PGA memory used by the instance exceeds PGA_AGGREGATE_LIMIT
ORA-04036: PGA memory used by the instance exceeds PGA_AGGREGATE_LIMIT
Incident details in: C:\APP\ADMINISTRATOR\diag\rdbms\orcl1\orcl1\incident\incdir_19268\orcl1_ora_2796_i19268.trc

When I looked in V$SESSION_EVENT, I saw that there had been a brief wait on the acknowledge over PGA limit event:

SQL> l
  1  select event, time_waited/100
  2  from v$session_event
  3* where sid = 11
SQL> /
 
EVENT                          TIME_WAITED/100
------------------------------ ---------------
acknowledge over PGA limit                7.05
Disk file operations I/O                     0
log buffer space                             0
SQL*Net message to client                    0
SQL*Net message from client             116.29
SQL*Net break/reset to client                0
 
6 rows selected.
 
SQL>

After this, the session was killed:
 
SQL> select status from v$session where sid = 11;
 
STATUS
--------
KILLED
 
SQL>

… and there was a message to this effect in the alert log:

Thu Feb 12 17:52:59 2015
Errors in file C:\APP\ADMINISTRATOR\diag\rdbms\orcl1\orcl1\incident\incdir_19267\orcl1_ora_2796_i19267.trc:
ORA-00028: your session has been killed
ORA-04036: PGA memory used by the instance exceeds PGA_AGGREGATE_LIMIT

The only problem I could see was that no error message was returned to the session running the recursion.

As an extra test, I used SYS to run the recursive procedure:

C:\Users\Administrator>sqlplus / as sysdba
 
SQL*Plus: Release 12.1.0.1.0 Production on Fri Feb 13 09:02:36 2015
 
Copyright (c) 1982, 2013, Oracle.  All rights reserved.
 
Connected to:
Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options
 
SQL> exec system.recursion();

This wrote more serious messages to the alert log:

Fri Feb 13 09:04:39 2015
PGA_AGGREGATE_LIMIT has been exceeded but some processes using the most PGA
memory are not eligible to receive ORA-4036 interrupts.  Further occurrences
of this condition will be written to the trace file of the CKPT process.

The session remained ACTIVE and V$SESSION_EVENT did not know what it was waiting for:

SQL> select sid from v$session
  2  where username = 'SYS';
 
       SID
----------
       237
 
SQL> select status from v$session
  2  where sid = 237;
 
STATUS
--------
ACTIVE
 
SQL> select event, time_waited/100
  2  from v$session_event
  3  where sid = 237
  4  /
 
EVENT                                    TIME_WAITED/100
---------------------------------------- ---------------
Disk file operations I/O                               0
db file sequential read                              .09
SQL*Net message to client                              0
SQL*Net message from client                       101.92
 
SQL>

One Cause of ORA-01092

$
0
0
I saw the following error in a job which had just recreated the control file of a test database after cloning:

SQL>   2    3    4    5    6    7    8    9   10   11   12   13   14   15   16   17   18   19   20   21   22   23   24   25   26   27   28   29   30   31   3
2   33   34   35   36   37   38   39   40   41   42   43   44   45   46   47   48   49   50   51   52   53   54   55   56   57   58   59   60   61   62   63
  64   65   66   67   68   69   70   71   72   73   74   75   76   77   78   79   80   81   82   83   84   85   86   87   88   89   90   91   92   93   94
95   96   97   98   99  100  101  102  103  104  105  106  107  108  109  110  111  112  113  114  115  116  117  118  119  120  121  122  123  124  125  126
  127  128  129  130  131  132  133  134  135  136  137
Control file created.
 
SQL> ALTER DATABASE OPEN RESETLOGS
*
ERROR at line 1:
ORA-01092: ORACLE instance terminated. Disconnection forced
 
SQL>

I looked in the alert log and noticed the errors below:

Wed Apr  1 19:30:46 2015
Errors in file /oracle/app/oracle/product/10.2.0/admin/mrmdpt1/udump/mrmdpt1_ora_8712.trc:
ORA-00600: internal error code, arguments: [25025], [115], [], [], [], [], [], []
Wed Apr  1 19:30:47 2015
Errors in file /oracle/app/oracle/product/10.2.0/admin/mrmdpt1/udump/mrmdpt1_ora_8712.trc:
ORA-00600: internal error code, arguments: [25025], [115], [], [], [], [], [], []
Wed Apr  1 19:30:47 2015
Error 600 happened during db open, shutting down database
USER: terminating instance due to error 600
Instance terminated by USER, pid = 8712
ORA-1092 signalled during: ALTER DATABASE OPEN RESETLOGS...

I checked the SQL which had recreated the control file. I saw that one of the datafiles from the source database was missing. The missing file was called '/agasprd/mrmprod/mrm_tables3/undo_1a.dbf'. I checked its file_id in the source database:

SQL> l
  1  select file_id from dba_data_files
  2  where file_name =
  3* '/agasprd/mrmprod/mrm_tables3/undo_1a.dbf'
SQL> /
 
   FILE_ID
----------
       115
 
SQL>

I noticed that it matched the 2nd parameter after the ORA-00600 (i.e. [115]). If this happens to you, you should correct the SQL so that it includes all the source database’s datafiles then repeat the cloning process from the start.

enq: TM - contention

$
0
0
This example was tested in an Oracle 11.1 database. I created a DEPT (or parent) table, added a couple of departments then made it available to other database users:

SQL> conn andrew/reid
Connected.
SQL> create table dept
  2  (dept_code varchar2(2),
  3   dept_desc varchar2(10))
  4  /
 
Table created.
 
SQL> insert into dept
  2  (dept_code, dept_desc)
  3  values
  4  ('10','IT')
  5  /
 
1 row created.
 
SQL> insert into dept
  2  (dept_code, dept_desc)
  3  values
  4  ('20','Sales')
  5  /
 
1 row created.
 
SQL> select * from dept
  2  /
 
DEPT_CODE  DEPT_DESC
---------- ----------
10         IT
20         Sales
 
SQL> grant all on dept to public
  2  /
 
Grant succeeded.
 
SQL>

I created an EMP (or child) table and tried to cross-check the EMP_DEPT column against the DEPT_CODE column in the DEPT table. This failed with an ORA-02270 as DEPT_CODE in the DEPT table was not unique. This was quite understandable because, if I had joined the EMP and DEPT tables to get the description (DEPT_DESC) for each employee’s department, I needed to be sure that only one value would be returned. I have covered this before but decided it would do no harm to repeat it here. I made the DEPT_CODE column unique in the DEPT table and the problem went away. I added two names to the EMP table with misspelt names (you will see why later). Then I made the table available to other database users:

SQL> create table emp
  2  (emp_name varchar2(10),
  3   emp_dept varchar2(2),
  4   constraint fk1
  5   foreign key(emp_dept)
  6   references dept(dept_code))
  7  /
references dept(dept_code))
                 *
ERROR at line 6:
ORA-02270: no matching unique or primary key for this
column-list
 
SQL> alter table dept
  2  add constraint dept_no_pk
  3  unique(dept_code)
  4  /
 
Table altered.
 
SQL> create table emp
  2  (emp_name varchar2(10),
  3   emp_dept varchar2(2),
  4   constraint fk1
  5   foreign key(emp_dept)
  6   references dept(dept_code))
  7  /
 
Table created.
 
SQL> insert into andrew.emp
  2  (emp_name, emp_dept)
  3  values
  4  ('Dayvid', '10')
  5  /
 
1 row created.
 
SQL> insert into andrew.emp
  2  (emp_name, emp_dept)
  3  values
  4  ('Edwood', '10')
  5  /
 
1 row created.
 
SQL> grant all on emp to public
  2  /
 
Grant succeeded.
 
SQL> 

USERA logged into the database, noticed one of the spelling mistakes, corrected it but did not commit the change:

SQL> conn usera/usera
Connected.
SQL> select * from andrew.emp
  2  /
 
EMP_NAME   EMP_DEPT
---------- ----------
Dayvid     10
Edwood     10
 
SQL> update andrew.emp
  2  set emp_name = 'David'
  3  where emp_name = 'Dayvid'
  4  /
 
1 row updated.
 
SQL> 

USERB logged into the database and tried to change the DEPT_CODE for Sales from 20 to 30 but nothing appeared to happen:

SQL> conn userb/userb
Connected.
SQL> update andrew.dept
  2  set dept_code = '30'
  3  where dept_desc = 'Sales'
  4  / 

USERB reported the problem to a DBA who investigated it as follows:

SQL> conn / as sysdba
Connected.
SQL> select event, state from v$session
  2  where username = 'USERB'
  3  /
 
EVENT                          STATE
------------------------------ -------------------
enq: TM - contention           WAITING
 
SQL>

This showed her that the problem was caused by a foreign key locking issue so she looked at the locks in Enterprise Manager:

 
This showed that the child table was EMP.
 
Eventually, USERA committed his change:

SQL> conn usera/usera
Connected.
SQL> select * from andrew.emp
  2  /
 
EMP_NAME   EMP_DEPT
---------- ----------
Dayvid     10
Edwood     10
 
SQL> update andrew.emp
  2  set emp_name = 'David'
  3  where emp_name = 'Dayvid'
  4  /
 
1 row updated.
 
SQL> commit
  2  /
 
Commit complete.
 
SQL>

And USERB’s transaction finished moments later so he was able to commit it too:

SQL> conn userb/userb
Connected.
SQL> update andrew.dept
  2  set dept_code = '30'
  3  where dept_desc = 'Sales'
  4  /
 
1 row updated.
 
SQL> commit
  2  /
 
Commit complete.
 
SQL>

The DBA looked to see how the EMP (child) table had been created. (I won’t go into how she knew Andrew’s password):

SQL> conn andrew/reid
Connected.
SQL> select dbms_metadata.get_ddl('TABLE','EMP')
  2  from dual
  3  /
 
DBMS_METADATA.GET_DDL('TABLE','EMP')
--------------------------------------------------------------------------------
 
  CREATE TABLE "ANDREW"."EMP"
   (    "EMP_NAME" VARCHAR2(10),
        "EMP_DEPT" VARCHAR2(2),
         CONSTRAINT "FK1" FOREIGN KEY ("EMP_DEPT")
          REFERENCES "ANDREW"."DEPT" ("DEPT_CODE") ENABLE
   ) 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)
  TABLESPACE "USERS"
 
SQL> 

She noticed that the EMP_DEPT column was used for referential integrity checking against the DEPT table. For this to work efficiently, there needs to be an index on this column but Oracle does not enforce this requirement. The DBA looked for indexes on the EMP table but did not find any:

SQL> l
  1  select index_name, column_name, column_position
  2  from dba_ind_columns
  3  where table_owner = 'ANDREW'
  4  and table_name = 'EMP'
  5* order by 1,3
SQL> /
 
no rows selected
 
SQL>

She created the appropriate index:

SQL> l
  1  create index andrew.emp_ind1
  2* on andrew.emp(emp_dept)
SQL> /
 
Index created.
 
SQL> 

USERA noticed the other spelling mistake, corrected it but did not commit the change:

SQL> conn usera/usera
Connected.
SQL> select * from andrew.emp
  2  /
 
EMP_NAME   EMP_DEPT
---------- ----------
David      10
Edwood     10
 
SQL> update andrew.emp
  2  set emp_name = 'Edward'
  3  where emp_name = 'Edwood'
  4  /
 
1 row updated.
 
SQL> 

USERB decided to change the DEPT_CODE for the Sales department to 40 and this time, the update worked immediately:

SQL> conn userb/userb
Connected.
SQL> update andrew.dept
  2  set dept_code = '40'
  3  where dept_desc = 'Sales'
  4  /
 
1 row updated.
 
SQL>

ORA-12801 in utlrp

$
0
0
I tried to run a utlrp in an Oracle 11.1.0.6.0 database and saw the errors below:

ORA-12801: error signaled in parallel query server P035
ORA-00018: maximum number of sessions exceeded
ORA-06512: at "SYS.UTL_RECOMP", line 629
ORA-06512: at line 4

I checked the number of sessions in v$session but there were not very many:

SQL> select count(*) from v$session;
 
  COUNT(*)
----------
        32
 
SQL>

I checked the value of the sessions parameter and it was much higher:

SQL> l
  1  select value from v$parameter
  2* where name = 'sessions'
SQL> /
 
VALUE
----------
87
 
SQL>

I took a look in the utlrp.sql and saw the following line:

@@utlprp.sql 0

I read somewhere that the parameter supplied to utlprp.sql specifies the number of parallel processes to use when doing the recompilations. If it is zero, the value is calculated as cpu_count x parallel_threads_per_cpu. I checked these two parameters:

SQL> l
  1  select name, value
  2  from v$parameter
  3  where name in
  4* ('cpu_count', 'parallel_threads_per_cpu')
SQL> /
 
NAME                           VALUE
------------------------------ ----------
cpu_count                      16
parallel_threads_per_cpu       2
 
SQL>

I traced my session and reran the utlrp.sql. When I looked in the trace file, I saw the following piece of SQL, which I have reformatted slightly:

WITH INST_CPUS AS
(SELECT INST_ID, NVL(TO_NUMBER(VALUE), 1) CPUS
FROM GV$PARAMETER
WHERE NAME = 'cpu_count'),
INST_THREADS AS
(SELECT INST_ID, NVL(TO_NUMBER(VALUE), 1) CPU_THREADS
FROM GV$PARAMETER
WHERE NAME = 'parallel_threads_per_cpu')
SELECT SUM((CASE WHEN CPUS <= 0 THEN 1 ELSE CPUS END)
* (CASE WHEN CPU_THREADS <= 0 THEN 1 ELSE CPU_THREADS END))
FROM INST_CPUS, INST_THREADS
WHERE INST_CPUS.INST_ID = INST_THREADS.INST_ID

So, clearly, cpu_count and parallel_threads_per_cpu are being multiplied together for some reason when you run a utlrp.sql. I changed the line above from:

@@utlprp.sql 0

to

@@utlprp.sql 1

... hoping that this would make the recompilations run one at a time. I ran the utlrp.sql again and it worked.
Viewing all 330 articles
Browse latest View live