Quantcast
Viewing all 330 articles
Browse latest View live

ORA-01749

This was tested on an Oracle 11.2 database. You cannot GRANT or REVOKE object privileges to or from yourself:
 
SQL> show user
USER is "ANDREW"
SQL> grant select on blah to john
  2  /
 
Grant succeeded.
 
SQL> grant select on blah to andrew
  2  /
grant select on blah to andrew
                        *
ERROR at line 1:
ORA-01749: you may not GRANT/REVOKE privileges to/from
yourself
 
SQL> revoke select on blah from john
  2  /
 
Revoke succeeded.
 
SQL> revoke select on blah from andrew
  2  /
revoke select on blah from andrew
                           *
ERROR at line 1:
ORA-01749: you may not GRANT/REVOKE privileges to/from
yourself
 
SQL>

Simple Example with REPLACE

The REPLACE function allows you to change a string of characters to another string of characters and can accept three parameters:
 
(1)    Input column name.
(2)    Old string value.
(3)    New string value.
 
You can see what I mean in the example below, which I tested on Oracle 11.2:
 
SQL> create table directory_name
  2  (location varchar2(30))
  3  /
 
Table created.
 
SQL> insert into directory_name
  2  values('/batch/prod/dir1')
  3  /
 
1 row created.
 
SQL> insert into directory_name
  2  values('/batch/prod/dir2')
  3  /
 
1 row created.
 
SQL> select location from directory_name
  2  /
 
LOCATION
------------------------------
/batch/prod/dir1
/batch/prod/dir2
 
SQL> update directory_name
  2  set location = replace(location,'prod','test')
  3  /
 
2 rows updated.
 
SQL> select location from directory_name
  2  /
 
LOCATION
------------------------------
/batch/test/dir1
/batch/test/dir2
 
SQL>

ORA-00942

These examples were tested on Oracle 11.2. If you get an ORA-00942, this might mean that a table does not exist:
 
SQL> conn / as sysdba
Connected.
SQL> drop user andrew cascade
  2  /
 
User dropped.
 
SQL> drop user john cascade
  2  /
 
User dropped.
 
SQL> grant dba to andrew identified by reid
  2  /
 
Grant succeeded.
 
SQL> conn andrew/reid
Connected.
SQL> select count(*) from blah
  2  /
select count(*) from blah
                     *
ERROR at line 1:
ORA-00942: table or view does not exist
 
SQL> 

If that is the case, creating the table will make the error go away: 

SQL> create table blah (col1 number)
  2  /
 
Table created.
 
SQL> select count(*) from blah
  2  /
 
  COUNT(*)
----------
         0
 
SQL> 

But in the next example, table ANDREW.BLAH exists as we have just created it. The problem is that JOHN does not have permission to look at it: 

SQL> grant create session to john
  2  identified by smith
  3  /
 
Grant succeeded.
 
SQL> conn john/smith
Connected.
SQL> select count(*) from andrew.blah
  2  /
select count(*) from andrew.blah
                            *
ERROR at line 1:
ORA-00942: table or view does not exist
 
SQL> 

When that happens, you have to GRANT appropriate access to make the error disappear: 

SQL> conn andrew/reid
Connected.
SQL> grant select on blah to john
  2  /
 
Grant succeeded.
 
SQL> conn john/smith
Connected.
SQL> select count(*) from andrew.blah
  2  /
 
  COUNT(*)
----------
         0
 
SQL>

log file switch (archiving needed)

I was running a test in Oracle 11.2 and the SQL below, which usually takes around 1 minute, seemed to be running forever:

SQL> begin
  2   for a in 1..8 loop
  3    insert into tab1 select * from tab1;
  4   end loop;
  5  end;
  6  /

I looked up the session's SID in V$SESSION to see if there was a row with wait_time set to zero. This means that the session is currently waiting on the event concerned. I saw a wait event I had not seen before:

SQL> select event, seconds_in_wait
  2  from v$session
  3  where sid = 191
  4  and wait_time = 0
  5  /

EVENT                               SECONDS_IN_WAIT
----------------------------------- ---------------
log file switch (archiving needed)             2596

SQL>

To double check the diagnosis, I waited for 10 seconds:

SQL> exec dbms_lock.sleep(10);

PL/SQL procedure successfully completed.

SQL>

... and when I looked again, the seconds_in_wait had increased by 10 seconds too, proving that the session was spending all its time waiting on this event:

SQL> select event, seconds_in_wait
  2  from v$session
  3  where sid = 191
  4  and wait_time = 0
  5  /

EVENT                               SECONDS_IN_WAIT
----------------------------------- ---------------
log file switch (archiving needed)             2606

SQL>

In most situations, you would have to clear some space from the archive area to allow the log file switch to proceed. However, the test I was running did not need the database to be in ARCHIVELOG mode so I closed the database and mounted it:

SQL> shutdown abort
ORACLE instance shut down.
SQL> startup mount
ORACLE instance started.

Total System Global Area  523108352 bytes
Fixed Size                  1375704 bytes
Variable Size             318767656 bytes
Database Buffers          197132288 bytes
Redo Buffers                5832704 bytes
Database mounted.
SQL>

However, when I tried to put the database in NOARCHIVELOG mode, I saw an error which I had not seen before - 2 new things in 1 day!

SQL> alter database noarchivelog;
alter database noarchivelog
*
ERROR at line 1:
ORA-38774: cannot disable media recovery - flashback
database is enabled

SQL>

Well, I was doing some flahsback testing about a week ago but that is finished for now so I turned it off:

SQL> alter database flashback off
  2  /

Database altered.

SQL>

Then I was able to put the database in NOARCHIVELOG mode and get on with my original test, which I hope to report in a future post:

SQL> alter database noarchivelog
  2  /

Database altered.

SQL> alter database open
  2  /

Database altered.

SQL>

ORA-01430

This was tested on Oracle 11.2. If you try to use a column name twice in the same table, you get an ORA-01430: 

SQL> create table tab1 (col1 number)
  2  /
 
Table created.
 
SQL> alter table tab1 add (col1 number)
  2  /
alter table tab1 add (col1 number)
                      *
ERROR at line 1:
ORA-01430: column being added already exists in table
 
SQL>

Database Links and Case Sensitive Passwords

I connected to an Oracle 11 database:

Oracle 11: sqlplus / as sysdba
 
SQL*Plus: Release 11.2.0.1.0 Production on Wed Apr 23 18:22:40 2014
 
Copyright (c) 1982, 2009, Oracle.  All rights reserved.
 
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
 
SQL>
 
I created a user with a lower case password:
 
SQL> create user user1 identified by pw1
  2  /
 
User created.
 
SQL> grant create session to user1
  2  /
 
Grant succeeded.
 
SQL>
 
Then I did a couple of trial logins to check that the case sensitive password checking was working:
 
SQL> conn user1/pw1
Connected.
SQL> conn user1/PW1
ERROR:
ORA-01017: invalid username/password; logon denied
 
Warning: You are no longer connected to ORACLE.
SQL>
 
I created a user with an upper case password:
 
SQL> conn / as sysdba
Connected.
SQL> create user user2 identified by PW2
  2  /
 
User created.
 
SQL> grant create session to user2
  2  /
 
Grant succeeded.
 
SQL>
 
Then I did two more trial logins to check that the case sensitive password checking was still working:
 
SQL> conn user2/pw2
ERROR:
ORA-01017: invalid username/password; logon denied
 
Warning: You are no longer connected to ORACLE.
SQL> conn user2/PW2
Connected.
SQL>
 
I connected to an Oracle 9 database on a different machine:

Oracle 9: sqlplus "/ as sysdba"
 
SQL*Plus: Release 9.2.0.7.0 - Production on Wed Apr 23 18:34:33 2014
 
Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.
 
Connected to:
Oracle9i Enterprise Edition Release 9.2.0.7.0 - Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.7.0 - Production
 
SQL>
 
Then I connected remotely from there to the Oracle 11 database. The case of the passwords was forwarded to the remote database and the passwords were checked correctly:
 
SQL> conn user1/pw1@busdpt1
Connected.
SQL> conn user1/PW1@busdpt1
ERROR:
ORA-01017: invalid username/password; logon denied
 
Warning: You are no longer connected to ORACLE.
SQL> conn user2/pw1@busdpt1
ERROR:
ORA-01017: invalid username/password; logon denied
 
SQL> conn user2/PW2@busdpt1
Connected.
SQL>
 
Next I created an Oracle 9 user to own some database links:
 
SQL> conn / as sysdba
Connected.
SQL> create user link_owner identified by link_owner
  2  /
 
User created.
 
SQL> grant create session, create database link
  2  to link_owner
  3  /
 
Grant succeeded.
 
SQL>
 
Then I created two database links to the Oracle 11 user with the lower case password.
One link used a lower case password and the other used an upper case password.
Neither of them worked:
 
SQL> conn link_owner/link_owner
Connected.
SQL> create database link link1
  2  connect to user1 identified by pw1
  3  using 'BUSDPT1'
  4  /
 
Database link created.
 
SQL> select * from dual@link1
  2  /
select * from dual@link1
                   *
ERROR at line 1:
ORA-01017: invalid username/password; logon denied
ORA-02063: preceding line from LINK1
 
SQL> create database link link2
  2  connect to user1 identified by PW1
  3  using 'BUSDPT1'
  4  /
 
Database link created.
 
SQL> select * from dual@link2
  2  /
select * from dual@link2
                   *
ERROR at line 1:
ORA-01017: invalid username/password; logon denied
ORA-02063: preceding line from LINK2
 
SQL>
 
Finally I created two database links to the Oracle 11 user with the upper case password.
One link used a lower case password and the other used an upper case password.
They both worked:
 
SQL> create database link link3
  2  connect to user2 identified by pw2
  3  using 'BUSDPT1'
  4  /
 
Database link created.
 
SQL> select * from dual@link3
  2  /
 
D
-
X
 
SQL> create database link link4
  2  connect to user2 identified by PW2
  3  using 'BUSDPT1'
  4  /
 
Database link created.
 
SQL> select * from dual@link4
  2  /
 
D
-
X
 
SQL>
 
This suggests to me that an Oracle 9 database sends database link passwords in upper case only. So if you want to create a link from an Oracle 9 database to an Oracle 11 database, you must connect to a remote user with an upper case password.

In Spanish 

ORA-02019

I had not seen this problem for a long time so, when it happened again recently, it took me a while to see the cause. I therefore decided to record it for future reference. First I created a database link:

ORCL /export/home/oracle/andrew > sqlplus /

SQL*Plus: Release 11.2.0.2.0 Production on Wed Apr 17 11:55:54 2013

Copyright (c) 1982, 2010, Oracle.  All rights reserved.

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

SQL> create database link link1.world
  2  connect to andrew
  3  identified by reid
  4  using 'REMOTEDB'
  5  /

Database link created.

SQL>

… but when I tried to use the link, I got an ORA-02019:

SQL> select * from dual@link1
  2  /
select * from dual@link1
                   *
ERROR at line 1:
ORA-02019: connection description for remote database not found

SQL>

I checked the database’s GLOBAL_NAME:

SQL> l
  1* select * from global_name
SQL> /

GLOBAL_NAME
------------------------------
ORCL

SQL>

I changed it as follows:

SQL> alter database rename global_name to ORCL.WORLD
  2  /

Database altered.

SQL> select * from global_name
  2  /

GLOBAL_NAME
------------------------------
ORCL.WORLD

SQL>

… and the database link worked:

SQL> select * from dual@link1
  2  /

D
-
X

SQL>

Does Having TIMED_STATISTICS on Affect Performance?

I was reading through an Oracle publication called Oracle 9i Database Performance Planning recently and saw the following:

In order to get meaningful database statistics, the TIMED_STATISTICS parameter must be enabled for the database instance. The performance impact of having TIMED_STATISTICS enabled is minimal compared to instance performance. The performance improvements and debugging value of a complete set of statistics make this parameter crucial to effective performance analysis.

I decided to check this out on my son's PC, which has 4 gigabytes of RAM and a 4 core CPU. The PC has Windows Vista and Oracle 11.2 installed.

I ran the first test below with TIMED_STATISTICS turned off. It recorded the start time, created a table, added several rows to it, did a full table scan, dropped the table, recorded the end time then checked what statistics were available:

SQL> conn / as sysdba
Connected.
SQL> alter session set statistics_level = basic
  2  /

Session altered.

SQL> alter session set timed_statistics = false
  2  /

Session altered.

SQL> select to_char(sysdate,'hh24:mi:ss') start_time
  2  from dual
  3  /

START_TIME
----------
18:30:03

SQL> create table tab1 tablespace users
  2  as select * from dba_tables
  3  /

Table created.

SQL> begin
  2   for a in 1..9 loop
  3    insert into tab1 select * from tab1;
  4   end loop;
  5  end;
  6  /

PL/SQL procedure successfully completed.

SQL> select count(*) from tab1 where owner = 'SYS'
  2  /

  COUNT(*)
----------
    489472

SQL> drop table tab1
  2  /

Table dropped.

SQL> select to_char(sysdate,'hh24:mi:ss') end_time
  2  from dual
  3  /

END_TIME
--------
18:30:51

SQL> select a.value/100
  2  from v$mystat a, v$sysstat b
  3  where a.statistic# = b.statistic#
  4  and b.name = 'CPU used by this session'
  5  /

A.VALUE/100
-----------
        .06

SQL> select * from
  2  (select event, time_waited/100 seconds
  3   from v$session_event
  4   where wait_class != 'Idle'
  5   and sid = (select distinct sid from v$mystat)
  6   order by 2 desc)
  7  where rownum < 6
  8  /

EVENT                                          SECONDS
--------------------------------------------- --------
db file sequential read                              0
Disk file operations I/O                             0
SQL*Net message to client                            0

SQL>

It took 48 seconds to run and, as suggested in the Oracle publication, produced no statistics. I repeated the test with TIMED_STATISTICS turned on:

SQL> conn / as sysdba
Connected.
SQL> alter session set statistics_level = typical
  2  /

Session altered.

SQL> alter session set timed_statistics = true
  2  /

Session altered.

SQL> select to_char(sysdate,'hh24:mi:ss') start_time
  2  from dual
  3  /

START_TIME
----------
18:33:00

SQL> create table tab1 tablespace users
  2  as select * from dba_tables
  3  /

Table created.

SQL> begin
  2   for a in 1..9 loop
  3    insert into tab1 select * from tab1;
  4   end loop;
  5  end;
  6  /

PL/SQL procedure successfully completed.

SQL> select count(*) from tab1 where owner = 'SYS'
  2  /

  COUNT(*)
----------
    489472

SQL> drop table tab1
  2  /

Table dropped.

SQL> select to_char(sysdate,'hh24:mi:ss') end_time
  2  from dual
  3  /

END_TIME
--------
18:33:52

SQL> select a.value/100
  2  from v$mystat a, v$sysstat b
  3  where a.statistic# = b.statistic#
  4  and b.name = 'CPU used by this session'
  5  /

A.VALUE/100
-----------
       7.77

SQL> select * from
  2  (select event, time_waited/100 seconds
  3   from v$session_event
  4   where wait_class != 'Idle'
  5   and sid = (select distinct sid from v$mystat)
  6   order by 2 desc)
  7  where rownum < 6
  8  /

EVENT                                          SECONDS
--------------------------------------------- --------
db file scattered read                              19
log file switch (checkpoint incomplete)             10
enq: RO - fast object reuse                          8
log buffer space                                     5
db file sequential read                              2

SQL>

It took 52 seconds to run, which was slightly longer than the first test, but, at the end, I could see that proper statistics had been recorded in views such as V$MYSTAT and V$SESSION_EVENT.

I repeated the two tests four more times and put the results in the table below:

Tests  TIMED_STATISTICS Off   TIMED_STATISTICS On
            (seconds)              (seconds)

 1+2           48                     52
 3+4           50                     55
 5+6           51                     60
 7+8           56                     59
 9+10          56                     50

ORA-01446

This was tested on Oracle 11.2. First I created a table and inserted 2 identical values in it:

SQL> create table tab1 (col1 number)
  2  /
 
Table created.
 
SQL> insert into tab1 values (1)
  2  /
 
1 row created.
 
SQL> insert into tab1 values (1)
  2  /
 
1 row created.

SQL>

Then I looked at the rowids of the values I had inserted:

SQL> select rowid, col1 from tab1
  2  /
 
ROWID                    COL1
------------------ ----------
AAAmpvAAEAAAACLAAA          1
AAAmpvAAEAAAACLAAB          1

SQL>

Next I created a view and checked that it referred back to the underlying table and picked up the correct rowids again: 

SQL> create view view1
  2  as select col1 from tab1
  3  /
 
View created.
 
SQL> select rowid, col1 from view1
  2  /
 
ROWID                    COL1
------------------ ----------
AAAmpvAAEAAAACLAAA          1
AAAmpvAAEAAAACLAAB          1

SQL>

Finally I created a view to show the distinct values in the table. This worked as expected too: 

SQL> create view view2
  2  as select distinct col1 from tab1
  3  /
 
View created.
 
SQL> select col1 from view2
  2  /
 
      COL1
----------
         1

SQL> 

But when I tried to look at the rowids in this view, I got an ORA-01446 instead. The rowids in the table itself gave details of each row's physical location in the database. So when I passed these rows through a DISTINCT into a view, there were two occurrences of the value 1 in the table giving one DISTINCT value in the view. Oracle then did not know which row's rowid to associate with the value displayed: 

SQL> select rowid, col1 from view2
  2  /
select rowid, col1 from view2
       *
ERROR at line 1:
ORA-01446: cannot select ROWID from, or sample, a view
with DISTINCT, GROUP BY, etc.
 
SQL>

SQL92_SECURITY

I tested the examples in this post in two Oracle 11.2 databases. In the first example, Andrew creates a table, inserts a row into it then grants UPDATE privilege on it to Fred, who is then able to work out the value in the table, without changing it permanently, using a series of UPDATE and ROLLBACK statements: 

SQL> conn / as sysdba
Connected.
SQL> select value from v$parameter
  2  where name = 'sql92_security'
  3  /
 
VALUE
------------------------------
FALSE
 
SQL> create user andrew
  2  identified by reid
  3  default tablespace users
  4  quota unlimited on users
  5  /
 
User created.
 
SQL> grant create session, create table
  2  to andrew
  3  /
 
Grant succeeded.
 
SQL> create user fred
  2  identified by bloggs
  3  /
 
User created.
 
SQL> grant create session to fred
  2  /
 
Grant succeeded.
 
SQL> conn andrew/reid
Connected.
SQL> create table tab1 (col1 number)
  2  /
 
Table created.
 
SQL> insert into tab1 values (5)
  2  /
 
1 row created.
 
SQL> grant update on tab1 to fred
  2  /
 
Grant succeeded.
 
SQL> conn fred/bloggs
Connected.
SQL> update andrew.tab1
  2  set col1 = 99
  3  where col1 > 10
  4  /
 
0 rows updated.
 
SQL> update andrew.tab1
  2  set col1 = 99
  3  where col1 > 0
  4  /
 
1 row updated.
 
SQL> rollback
  2  /
 
Rollback complete.
 
SQL> update andrew.tab1
  2  set col1 = 99
  3  where col1 > 5
  4  /
 
0 rows updated.
 
SQL> update andrew.tab1
  2  set col1 = 99
  3  where col1 > 3
  4  /
 
1 row updated.
 
SQL> rollback
  2  /
 
Rollback complete.
 
SQL> update andrew.tab1
  2  set col1 = 99
  3  where col1 > 4
  4  /
 
1 row updated.
 
SQL> rollback
  2  /
 
Rollback complete.
 
SQL> update andrew.tab1
  2  set col1 = 99
  3  where col1 = 5
  4  /
 
1 row updated.
 
SQL> rollback
  2  /
 
Rollback complete.
 
SQL> 

The example is trivial. Working out floating pointing numbers or long character strings in tables containing thousands of rows would take ages using this method. However, by using some clever PL/SQL, it would be possible, given time. This isn’t too much of a problem for me. After all, if a malicious person had UPDATE access to a table of mine, I’m sure he could cause far more damage by simply overwriting my data. But if you don’t like the idea of people guessing values in your tables, then the SQL92_SECURITY initialization parameter could be for you. In the example above, you may have noticed that it was turned off.
 
However, in the second example below, the parameter is turned on. It was run in a different database, as mentioned above, but the users were created in a similar fashion. This time, the UPDATE privilege does not allow Fred to run UPDATE statements with WHERE clauses. To do this, he needs SELECT access as well: 

SQL> conn / as sysdba
Connected.
SQL> select value from v$parameter
  2  where name = 'sql92_security'
  3  /
 
VALUE
------------------------------
TRUE
 
SQL> conn andrew/reid
Connected.
SQL> create table tab1 (col1 number)
  2  /
 
Table created.
 
SQL> insert into tab1 values (1)
  2  /
 
1 row created.
 
SQL> grant update on tab1 to fred
  2  /
 
Grant succeeded.
 
SQL> conn fred/bloggs
Connected.
SQL> update andrew.tab1 set col1 = 2
  2  /
 
1 row updated.
 
SQL> update andrew.tab1 set col1 = 3
  2  where col1 = 2
  3  /
update andrew.tab1 set col1 = 3
              *
ERROR at line 1:
ORA-01031: insufficient privileges
 
SQL> conn andrew/reid
Connected.
SQL> grant select on tab1 to fred
  2  /
 
Grant succeeded.
 
SQL> conn fred/bloggs
Connected.
SQL> update andrew.tab1 set col1 = 3
  2  where col1 = 2
  3  /
 
1 row updated.
 
SQL>

ORA-28010

I wondered what would happen if you tried to do a password expire on an externally identified user so I tried it out on an Oracle 11.2 database. As you might expect, it failed:
 
SQL> alter user system identified externally
  2  /
 
User altered.
 
SQL> alter user system password expire
  2  /
alter user system password expire
*
ERROR at line 1:
ORA-28010: cannot expire external or global accounts
 
SQL>
 
I guess this is because if an externally identified user had to change his password, he would not be externally identified any longer. Also, a user cannot change itself to or from external identification unless it has the ALTER USER privilege.

Invisible Indexes (Part 1)

Oracle introduced INVISIBLE indexes in version 11. The example below creates an INVISIBLE index, makes it VISIBLE then makes it INVISIBLE again. The VISIBILITY column in USER_INDEXES is used to check that each change has worked:

SQL> col visibility format a10
SQL> create table my_table
  2  as select * from dba_tables
  3  /

Table created.

SQL> create index my_index
  2  on my_table(owner)
  3  invisible
  4  /

Index created.

SQL> select visibility
  2  from user_indexes
  3  where index_name = 'MY_INDEX'
  4  /

VISIBILITY
----------
INVISIBLE

SQL> alter index my_index visible
  2  /

Index altered.

SQL> select visibility
  2  from user_indexes
  3  where index_name = 'MY_INDEX'
  4  /

VISIBILITY
----------
VISIBLE

SQL> alter index my_index invisible
  2  /

Index altered.

SQL> select visibility
  2  from user_indexes
  3  where index_name = 'MY_INDEX'
  4  /

VISIBILITY
----------
INVISIBLE

SQL>

********************

When an index is INVISIBLE, it is still updated by DML but it is ignored by the optimizer. You can make an index INVISIBLE and see if this has a detrimental effect on an application’s performance. If it does not then you can consider dropping it.

In the example below, an index is created and used by a SELECT statement.

The index is made INVISIBLE and the SELECT statement is repeated. This time it does not use the index:

SQL> col visibility format a10
SQL> create table my_table
  2  as select * from dba_tables
  3  /

Table created.

SQL> create index my_index
  2  on my_table(owner)
  3  /

Index created.

SQL> set autotrace on
SQL> select count(*) from my_table
  2  where owner = 'SYSTEM'
  3  /

  COUNT(*)
----------
       154


Execution Plan
----------------------------------------------------------
Plan hash value: 4077732364

------------------------------------------------------------------------------
| Id  | Operation         | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |          |     1 |    17 |     1   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE   |          |     1 |    17 |            |          |
|*  2 |   INDEX RANGE SCAN| MY_INDEX |   154 |  2618 |     1   (0)| 00:00:01 |
------------------------------------------------------------------------------

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

   2 - access("OWNER"='SYSTEM')

Note
-----
   - dynamic sampling used for this statement


Statistics
----------------------------------------------------------
         32  recursive calls
          0  db block gets
         68  consistent gets
          1  physical reads
          0  redo size
        523  bytes sent via SQL*Net to client
        523  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

SQL> alter index my_index invisible
  2  /

Index altered.

SQL> select count(*) from my_table
  2  where owner = 'SYSTEM'
  3  /

  COUNT(*)
----------
       154


Execution Plan
----------------------------------------------------------
Plan hash value: 228900979

-------------------------------------------------------------------------------
| Id  | Operation          | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |          |     1 |    17 |     6  (17)| 00:00:01 |
|   1 |  SORT AGGREGATE    |          |     1 |    17 |            |          |
|*  2 |   TABLE ACCESS FULL| MY_TABLE |   152 |  2584 |     6  (17)| 00:00:01 |
-------------------------------------------------------------------------------

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

   2 - filter("OWNER"='SYSTEM')

Note
-----
   - dynamic sampling used for this statement


Statistics
----------------------------------------------------------
        253  recursive calls
          0  db block gets
        164  consistent gets
          0  physical reads
          0  redo size
        523  bytes sent via SQL*Net to client
        523  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          6  sorts (memory)
          0  sorts (disk)
          1  rows processed

SQL>

Invisible Indexes (Part 2)

In Oracle 11.1.0.6.0, you could not run DBMS_STATS against an invisible index or a table with an invisible index. I found 2 workarounds. You could run the old ANALYZE command or you could make the index visible on a temporary basis:

SQL> create table my_table
  2  as select * from dba_tables
  3  /

Table created.

SQL> create index my_index
  2  on my_table(owner) invisible
  3  /

Index created.

SQL> exec dbms_stats.gather_table_stats -
> (user,'my_table',cascade=>true);
BEGIN dbms_stats.gather_table_stats  (user,'my_table',cascade=>true); END;

*
ERROR at line 1:
ORA-00904: : invalid identifier
ORA-06512: at "SYS.DBMS_STATS", line 17806
ORA-06512: at "SYS.DBMS_STATS", line 17827
ORA-06512: at line 1

SQL> exec dbms_stats.gather_index_stats(user,'my_index');
BEGIN dbms_stats.gather_index_stats(user,'my_index'); END;

*
ERROR at line 1:
ORA-00904: : invalid identifier
ORA-06512: at "SYS.DBMS_STATS", line 14037
ORA-06512: at "SYS.DBMS_STATS", line 14060
ORA-06512: at line 1

SQL> analyze table my_table compute statistics
  2  /

Table analyzed.

SQL> analyze index my_index validate structure
  2  /

Index analyzed.

SQL> alter index my_index visible
  2  /

Index altered.

SQL> exec dbms_stats.gather_table_stats -
> (user,'my_table',cascade=>true);

PL/SQL procedure successfully completed.

SQL> exec dbms_stats.gather_index_stats(user,'my_index');

PL/SQL procedure successfully completed.

SQL>

This is bug 6344547. According to Metalink / My Oracle Support, it was fixed in version 11.1.0.7.0. I was unable to check this but did confirm that it was fixed in version 11.2.0.1.0.

********************

The initialisation parameter optimizer_use_invisible_indexes allows the optimizer to use invisible indexes. In the example below, a table is created with an invisible index. A SELECT statement, which would normally use this index, is run against the table but the index is not used because it is invisible. The initialisation parameter is set to true and the SELECT statement is run again. This time it uses the index:

SQL> create table my_table
  2  as select * from dba_tables
  3  /

Table created.

SQL> create index my_index
  2  on my_table(owner) invisible
  3  /

Index created.

SQL> set autotrace on
SQL> select count(*) from my_table
  2  where owner = 'SYSTEM'
  3  /

  COUNT(*)
----------
       154


Execution Plan
----------------------------------------------------------
Plan hash value: 228900979

-------------------------------------------------------------------------------
| Id  | Operation          | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |          |     1 |    17 |     6  (17)| 00:00:01 |
|   1 |  SORT AGGREGATE    |          |     1 |    17 |            |          |
|*  2 |   TABLE ACCESS FULL| MY_TABLE |   143 |  2431 |     6  (17)| 00:00:01 |
-------------------------------------------------------------------------------

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

   2 - filter("OWNER"='SYSTEM')

Note
-----
   - dynamic sampling used for this statement


Statistics
----------------------------------------------------------
         28  recursive calls
          0  db block gets
        133  consistent gets
          0  physical reads
          0  redo size
        523  bytes sent via SQL*Net to client
        523  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

SQL> alter session set optimizer_use_invisible_indexes = true
  2  /

Session altered.

SQL> select count(*) from my_table
  2  where owner = 'SYSTEM'
  3  /

  COUNT(*)
----------
       154


Execution Plan
----------------------------------------------------------
Plan hash value: 4077732364

------------------------------------------------------------------------------
| Id  | Operation         | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |          |     1 |    17 |     1   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE   |          |     1 |    17 |            |          |
|*  2 |   INDEX RANGE SCAN| MY_INDEX |   154 |  2618 |     1   (0)| 00:00:01 |
------------------------------------------------------------------------------

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

   2 - access("OWNER"='SYSTEM')

Note
-----
   - dynamic sampling used for this statement


Statistics
----------------------------------------------------------
          9  recursive calls
          0  db block gets
         68  consistent gets
          1  physical reads
          0  redo size
        523  bytes sent via SQL*Net to client
        523  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

SQL>

ORA-01700 and/or ORA-01711

I tested these on Oracle 11.2. You can grant a privilege like this:

SQL> grant create table to andrew
  2  /
 
Grant succeeded.

SQL>

... but if you try to grant a privilege more than once in the same grant statement, you get an ORA-01711:

SQL> grant create table,
  2  select any table,
  3  create table to andrew
  4  /
create table to andrew
*
ERROR at line 3:
ORA-01711: duplicate privilege listed

SQL>

... and if you try to grant a privilege to the same user more than once in the same grant statement, you get an ORA-01700:

SQL> grant create table to
  2  andrew, fred, andrew
  3  /
andrew, fred, andrew
              *
ERROR at line 2:
ORA-01700: duplicate username in list
 
SQL>


Unusable Indexes

I tested this post on an Oracle 9 database. It shows that if you have an index which is marked as UNUSABLE, truncating the underlying table makes it VALID again.

First I created a table:

SQL> CREATE TABLE ANDREWS_TABLE AS
  2  SELECT * FROM DBA_TABLES
  3  /

Table created.

SQL>

Then I added an index to the table:

SQL> CREATE INDEX ANDREWS_INDEX
  2  ON ANDREWS_TABLE(TABLE_NAME)
  3  /

Index created.

SQL>

... and made it UNUSABLE:

SQL> ALTER INDEX ANDREWS_INDEX UNUSABLE
  2  /

Index altered.

SQL> SELECT STATUS
  2  FROM USER_INDEXES
  3  WHERE INDEX_NAME = 'ANDREWS_INDEX'
  4  /

STATUS
--------
UNUSABLE

SQL>

I truncated the table:

SQL> TRUNCATE TABLE ANDREWS_TABLE
  2  /

Table truncated.

SQL>

... and this made the index valid again:

SQL> SELECT STATUS
  2  FROM USER_INDEXES
  3  WHERE INDEX_NAME = 'ANDREWS_INDEX'
  4  /

STATUS
--------
VALID

SQL>


ORA-12988

Tables in the SYS schema are usually created by Oracle but you can create them yourself. If they are created by Oracle you should not be trying to change them. If they are created by you, you should seriously consider moving them into another schema. Either way, if you try to drop a column from a table owned by SYS, you get an ORA-12988. You can see what I mean in the example below, which I ran in an Oracle 11.2 database:

SQL> conn / as sysdba
Connected.
SQL> show user
USER is "SYS"
SQL> create table tab1
  2  (col1 number,
  3   col2 number)
  4  /
 
Table created.
 
SQL> alter table tab1 drop column col1
  2  /
alter table tab1 drop column col1
*
ERROR at line 1:
ORA-12988: cannot drop column from table owned by SYS
 
SQL>


RMAN Copy Adds Hidden Parameters

Some testers had a problem with an application running against an Oracle 11.2.0.1.0 database. It kept failing with ORA-03114 and/or ORA-24909 messages. The only clues were that production was copied into test around 6 weeks ago, production was OK but test was not. I looked the errors up on the Internet, saw a suggestion that I should compare initialization parameters in both databases and decided to give this a try. I noticed that the test database had some hidden parameters and decided to make a list of them. I found that the following SQL (which I ran again retrospectively after the problem had been fixed) did not work as the underscore was treated as a wild card and all the parameters were listed:
 
SQL> select name, value
  2  from v$parameter
  3  where name like '_%'
  4  order by 1
  5  /
 
NAME                                VALUE
----------------------------------- ---------------
O7_DICTIONARY_ACCESSIBILITY         FALSE
active_instance_count
aq_tm_processes                     0
archive_lag_target                  0
asm_diskgroups
asm_diskstring
asm_power_limit                     1
Etc
Etc
 
So I did it like this instead and found that the database had 124 hidden parameters:
 
SQL> select name, value
  2  from v$parameter
  3  where substr(name,1,1) = '_'
  4  order by 1
  5  /
 
NAME                                VALUE
----------------------------------- ---------------
_aggregation_optimization_settings  0
_always_anti_join                   CHOOSE
_always_semi_join                   CHOOSE
Etc
Etc
_union_rewrite_for_gs               YES_GSET_MVS
_unnest_subquery                    TRUE
_use_column_stats_for_function      TRUE
 
124 rows selected.
 
SQL>
 
There were no hidden parameters in the production database at all:
 
SQL> select name, value
  2  from v$parameter
  3  where substr(name,1,1) = '_'
  4  order by 1
  5  /
 
no rows selected
 
SQL>
 
Looking through the alert log, I found that there were no hidden parameters when the database was opened here:
 
Mon Mar 17 15:54:00 2014
Starting ORACLE instance (normal)
Etc
Etc
System parameters with non-default values:
  processes                = 150
  nls_language             = "ENGLISH"
  nls_territory            = "UNITED KINGDOM"
  memory_target            = 500M
  control_files            = "/database/NLGENUT1/gen_redo1/control01.ctl"
  control_files            = "/database/NLGENUT1/gen_redo2/control02.ctl"
  control_files            = "/database/NLGENUT1/gen_system/control03.ctl"
  db_file_name_convert     = "/agasprd/nlgenprd"
  db_file_name_convert     = "/database/NLGENUT1"
  db_recovery_file_dest    = "/agasprd/flash_recovery_area"
  db_recovery_file_dest_size= 32G
  undo_tablespace          = "UNDOTBS1"
  remote_login_passwordfile= "EXCLUSIVE"
  db_name                  = "NLGENUT1"
  open_cursors             = 300
  os_authent_prefix        = ""
Mon Mar 17 15:54:02 2014
 
… but they all appeared when the database was opened less than an hour later:
 
Mon Mar 17 16:47:29 2014
Starting ORACLE instance (normal)
Etc
Etc
System parameters with non-default values:
  processes                = 150
  _ksb_restart_policy_times= "0"
  _ksb_restart_policy_times= "60"
  _ksb_restart_policy_times= "120"
  _ksb_restart_policy_times= "240"
Etc
Etc
  _optimizer_mode_force    = TRUE
  _always_anti_join        = "CHOOSE"
  _optimizer_null_aware_antijoin= TRUE
  _partition_view_enabled  = TRUE
  _b_tree_bitmap_plans     = TRUE
  _cpu_to_io               = 0
  _optimizer_extended_cursor_sharing= "UDO"
  _optimizer_extended_cursor_sharing_rel= "SIMPLE"
  _optimizer_adaptive_cursor_sharing= TRUE
  _optimizer_cost_model    = "CHOOSE"
  _optimizer_undo_cost_change= "11.2.0.1"
  _optimizer_system_stats_usage= TRUE
  _new_sort_cost_estimate  = TRUE
  _complex_view_merging    = TRUE
  _unnest_subquery         = TRUE
Etc
Etc
 
I looked back to see what I was doing at that time and saw that I was using RMAN to copy production into test. Then I looked at Metalink and decided that bug 9752597 / base bug 10061364 had probably caused my problem (as usual, click on the image to enlarge it and bring it into focus):


 I removed the hidden parameters from the test database and passed it back to the testers.


ORA-32771 and ORA-32772

Bigfile tablespaces were introduced, and this example was run, in Oracle 10. They have only one datafile. Usually, this will be very large, although this is not the case in the example below:
 
SQL> create bigfile tablespace andrew
  2  datafile '/tmp/andrew.dbf' size 10m
  3  /
 
Tablespace created.
 
SQL>
 
There are two ways to extend an ordinary tablespace. You can add an extra datafile or you can extend an existing datafile. You cannot add an extra datafile to a bigfile tablespace so, to avoid running out of space altogether, you should use them with file systems which can be dynamically extended. These can be created, for example, on an EMC Celerra. You can identify these tablespaces as follows:
 
SQL> l
  1  select bigfile from dba_tablespaces
  2* where tablespace_name = 'ANDREW'
SQL> /
 
BIGFILE
-------
YES
 
SQL>
 
If you try to add an extra file to a bigfile tablespace, you get the following error:
 
SQL> alter tablespace andrew
  2  add datafile '/tmp/one_file_too_many.dbf'
  3  size 10m
  4  /
alter tablespace andrew
*
ERROR at line 1:
ORA-32771: cannot add file to bigfile tablespace
 
SQL>
 
Bigfile tablespaces must be locally managed, they cannot be dictionary managed so, in the example below, you would replace extent management dictionary with extent management local:
 
SQL> l
  1  create bigfile tablespace fred
  2  extent management dictionary
  3* datafile '/tmp/fred.dbf' size 5m
SQL> /
create bigfile tablespace fred
*
ERROR at line 1:
ORA-32772: BIGFILE is invalid option for this type of
tablespace
 
SQL>


impdp REMAP_DATAFILE Parameter

I was asked to copy one database into another, which I usually do by copying the datafiles then recreating the control file. However, on this occasion, although both databases were on Oracle 11.2.0.4, the machine hosting the input database was X86 whereas the machine hosting the output database was Sparc. Data Pump seemed to be a better option.
 
I created the output database using dbca, which set up the SYSTEM, SYSAUX, TEMP, UNDOTBS1 and USERS tablespaces.
 
The datafiles on the input database had names beginning with /database/PQEPERF but the output database needed to have filenames starting with /cogdbase/pqecog2. When I do a full expdp/ impdp, I precreate the tablespaces in the output database if the file systems have different names. In the past, I have extracted the tablespace creation DDL from the input database. Then I have done a global edit on the resultant SQL to change the file names to match the file system name(s) used by the output database. I could not find my SQL to do this so I decided to try something else.
 
I ran the following SQL on the input database to extract the datafile names. I'm sorry the printout is so small and has a mixture of fonts but if you copy and paste it into a text file, it should look better:

SQL> @remap_datafile
SQL> set echo on
SQL> spool remap_datafile
SQL> set feedback off
SQL> set lines 200
SQL> set pages 0
SQL> set trimspool on
SQL> select 'REMAP_DATAFILE="'''||file_name||''':''+'||file_name||'''"'
  2  from dba_data_files
  3  where tablespace_name not in
  4  ('SYSAUX','SYSTEM','UNDOTBS1','USERS')
  5  /
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/costing_data1.dbf':'+/database/PQEPERF/pqe_data/costing_data1.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/costing_idx1.dbf':'+/database/PQEPERF/pqe_data/costing_idx1.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/costing_idx2.dbf':'+/database/PQEPERF/pqe_data/costing_idx2.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/datemove.dbf':'+/database/PQEPERF/pqe_data/datemove.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/event_monitor_data.dbf':'+/database/PQEPERF/pqe_data/event_monitor_data.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/event_monitor_index.dbf':'+/database/PQEPERF/pqe_data/event_monitor_index.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/mislog_data.dbf':'+/database/PQEPERF/pqe_data/mislog_data.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/rapid_growth_a.dbf':'+/database/PQEPERF/pqe_data/rapid_growth_a.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/rapid_growth_b.dbf':'+/database/PQEPERF/pqe_data/rapid_growth_b.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/rapid_growth_c.dbf':'+/database/PQEPERF/pqe_data/rapid_growth_c.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/rapid_growth_d.dbf':'+/database/PQEPERF/pqe_data/rapid_growth_d.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/rapid_growth_e.dbf':'+/database/PQEPERF/pqe_data/rapid_growth_e.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/rapid_growth_f.dbf':'+/database/PQEPERF/pqe_data/rapid_growth_f.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/rapid_growth_g.dbf':'+/database/PQEPERF/pqe_data/rapid_growth_g.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/rapid_growth_h.dbf':'+/database/PQEPERF/pqe_data/rapid_growth_h.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/rapid_growth_i.dbf':'+/database/PQEPERF/pqe_data/rapid_growth_i.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/rapid_growth_idx1_a.dbf':'+/database/PQEPERF/pqe_data/rapid_growth_idx1_a.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/slow_growth.dbf':'+/database/PQEPERF/pqe_data/slow_growth.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/slow_growth_idx1.dbf':'+/database/PQEPERF/pqe_data/slow_growth_idx1.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/stand.dbf':'+/database/PQEPERF/pqe_data/stand.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/stand_idx1.dbf':'+/database/PQEPERF/pqe_data/stand_idx1.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/static.dbf':'+/database/PQEPERF/pqe_data/static.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/static_idx1.dbf':'+/database/PQEPERF/pqe_data/static_idx1.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/tfe_indexes.dbf':'+/database/PQEPERF/pqe_data/tfe_indexes.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/transient.dbf':'+/database/PQEPERF/pqe_data/transient.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/cai_data.dbf':'+/database/PQEPERF/pqe_data/cai_data.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/rapid_growth_idx1_b.dbf':'+/database/PQEPERF/pqe_data/rapid_growth_idx1_b.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/transient_idx1.dbf':'+/database/PQEPERF/pqe_data/transient_idx1.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/mtdconsumption_a.dbf':'+/database/PQEPERF/pqe_data/mtdconsumption_a.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/rapid_growth_j.dbf':'+/database/PQEPERF/pqe_data/rapid_growth_j.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/cons_part_a.dbf':'+/database/PQEPERF/pqe_data/cons_part_a.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/cons_part_b.dbf':'+/database/PQEPERF/pqe_data/cons_part_b.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/cons_part_c.dbf':'+/database/PQEPERF/pqe_data/cons_part_c.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/cons_part_idx_a.dbf':'+/database/PQEPERF/pqe_data/cons_part_idx_a.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/cons_arch_part_a.dbf':'+/database/PQEPERF/pqe_data/cons_arch_part_a.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/cons_arch_part_b.dbf':'+/database/PQEPERF/pqe_data/cons_arch_part_b.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/cons_arch_part_c.dbf':'+/database/PQEPERF/pqe_data/cons_arch_part_c.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/cons_arch_part_d.dbf':'+/database/PQEPERF/pqe_data/cons_arch_part_d.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/cons_arch_part_idx_a.dbf':'+/database/PQEPERF/pqe_data/cons_arch_part_idx_a.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/cons_part_d.dbf':'+/database/PQEPERF/pqe_data/cons_part_d.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/cons_part_e.dbf':'+/database/PQEPERF/pqe_data/cons_part_e.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/cons_arch_part_e.dbf':'+/database/PQEPERF/pqe_data/cons_arch_part_e.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/cons_arch_part_idx_b.dbf':'+/database/PQEPERF/pqe_data/cons_arch_part_idx_b.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/cons_arch_part_idx_c.dbf':'+/database/PQEPERF/pqe_data/cons_arch_part_idx_c.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/cons_arch_part_idx_d.dbf':'+/database/PQEPERF/pqe_data/cons_arch_part_idx_d.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/cons_arch_part_idx_e.dbf':'+/database/PQEPERF/pqe_data/cons_arch_part_idx_e.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/cons_part_idx_b.dbf':'+/database/PQEPERF/pqe_data/cons_part_idx_b.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/cons_part_idx_c.dbf':'+/database/PQEPERF/pqe_data/cons_part_idx_c.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/cons_part_idx_d.dbf':'+/database/PQEPERF/pqe_data/cons_part_idx_d.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/cons_part_idx_e.dbf':'+/database/PQEPERF/pqe_data/cons_part_idx_e.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/mislog_data_1.dbf':'+/database/PQEPERF/pqe_data/mislog_data_1.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/mislog_data_2.dbf':'+/database/PQEPERF/pqe_data/mislog_data_2.dbf'"
SQL> spool off
SQL>

Then I opened the SPOOL file with vi and ran the following global edit:

:%s?+/database/PQEPERF?/cogdbase/pqecog2?g

I then appended the SPOOL file onto the parfile I was going to use for the impdp so it looked like this:

CONTENT=ALL
DIRECTORY=ANDREWS_DATAPUMP
DUMPFILE=pqeperf.dmp
FULL=Y
LOGFILE=pqeperf.imp.log
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/costing_data1.dbf':'/cogdbase/pqecog2/pqe_data/costing_data1.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/costing_idx1.dbf':'/cogdbase/pqecog2/pqe_data/costing_idx1.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/costing_idx2.dbf':'/cogdbase/pqecog2/pqe_data/costing_idx2.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/datemove.dbf':'/cogdbase/pqecog2/pqe_data/datemove.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/event_monitor_data.dbf':'/cogdbase/pqecog2/pqe_data/event_monitor_data.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/event_monitor_index.dbf':'/cogdbase/pqecog2/pqe_data/event_monitor_index.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/mislog_data.dbf':'/cogdbase/pqecog2/pqe_data/mislog_data.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/rapid_growth_a.dbf':'/cogdbase/pqecog2/pqe_data/rapid_growth_a.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/rapid_growth_b.dbf':'/cogdbase/pqecog2/pqe_data/rapid_growth_b.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/rapid_growth_c.dbf':'/cogdbase/pqecog2/pqe_data/rapid_growth_c.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/rapid_growth_d.dbf':'/cogdbase/pqecog2/pqe_data/rapid_growth_d.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/rapid_growth_e.dbf':'/cogdbase/pqecog2/pqe_data/rapid_growth_e.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/rapid_growth_f.dbf':'/cogdbase/pqecog2/pqe_data/rapid_growth_f.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/rapid_growth_g.dbf':'/cogdbase/pqecog2/pqe_data/rapid_growth_g.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/rapid_growth_h.dbf':'/cogdbase/pqecog2/pqe_data/rapid_growth_h.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/rapid_growth_i.dbf':'/cogdbase/pqecog2/pqe_data/rapid_growth_i.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/rapid_growth_idx1_a.dbf':'/cogdbase/pqecog2/pqe_data/rapid_growth_idx1_a.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/slow_growth.dbf':'/cogdbase/pqecog2/pqe_data/slow_growth.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/slow_growth_idx1.dbf':'/cogdbase/pqecog2/pqe_data/slow_growth_idx1.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/stand.dbf':'/cogdbase/pqecog2/pqe_data/stand.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/stand_idx1.dbf':'/cogdbase/pqecog2/pqe_data/stand_idx1.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/static.dbf':'/cogdbase/pqecog2/pqe_data/static.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/static_idx1.dbf':'/cogdbase/pqecog2/pqe_data/static_idx1.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/tfe_indexes.dbf':'/cogdbase/pqecog2/pqe_data/tfe_indexes.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/transient.dbf':'/cogdbase/pqecog2/pqe_data/transient.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/cai_data.dbf':'/cogdbase/pqecog2/pqe_data/cai_data.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/rapid_growth_idx1_b.dbf':'/cogdbase/pqecog2/pqe_data/rapid_growth_idx1_b.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/transient_idx1.dbf':'/cogdbase/pqecog2/pqe_data/transient_idx1.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/mtdconsumption_a.dbf':'/cogdbase/pqecog2/pqe_data/mtdconsumption_a.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/rapid_growth_j.dbf':'/cogdbase/pqecog2/pqe_data/rapid_growth_j.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/cons_part_a.dbf':'/cogdbase/pqecog2/pqe_data/cons_part_a.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/cons_part_b.dbf':'/cogdbase/pqecog2/pqe_data/cons_part_b.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/cons_part_c.dbf':'/cogdbase/pqecog2/pqe_data/cons_part_c.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/cons_part_idx_a.dbf':'/cogdbase/pqecog2/pqe_data/cons_part_idx_a.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/cons_arch_part_a.dbf':'/cogdbase/pqecog2/pqe_data/cons_arch_part_a.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/cons_arch_part_b.dbf':'/cogdbase/pqecog2/pqe_data/cons_arch_part_b.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/cons_arch_part_c.dbf':'/cogdbase/pqecog2/pqe_data/cons_arch_part_c.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/cons_arch_part_d.dbf':'/cogdbase/pqecog2/pqe_data/cons_arch_part_d.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/cons_arch_part_idx_a.dbf':'/cogdbase/pqecog2/pqe_data/cons_arch_part_idx_a.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/cons_part_d.dbf':'/cogdbase/pqecog2/pqe_data/cons_part_d.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/cons_part_e.dbf':'/cogdbase/pqecog2/pqe_data/cons_part_e.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/cons_arch_part_e.dbf':'/cogdbase/pqecog2/pqe_data/cons_arch_part_e.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/cons_arch_part_idx_b.dbf':'/cogdbase/pqecog2/pqe_data/cons_arch_part_idx_b.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/cons_arch_part_idx_c.dbf':'/cogdbase/pqecog2/pqe_data/cons_arch_part_idx_c.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/cons_arch_part_idx_d.dbf':'/cogdbase/pqecog2/pqe_data/cons_arch_part_idx_d.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/cons_arch_part_idx_e.dbf':'/cogdbase/pqecog2/pqe_data/cons_arch_part_idx_e.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/cons_part_idx_b.dbf':'/cogdbase/pqecog2/pqe_data/cons_part_idx_b.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/cons_part_idx_c.dbf':'/cogdbase/pqecog2/pqe_data/cons_part_idx_c.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/cons_part_idx_d.dbf':'/cogdbase/pqecog2/pqe_data/cons_part_idx_d.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/cons_part_idx_e.dbf':'/cogdbase/pqecog2/pqe_data/cons_part_idx_e.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/mislog_data_1.dbf':'/cogdbase/pqecog2/pqe_data/mislog_data_1.dbf'"
REMAP_DATAFILE="'/database/PQEPERF/pqe_data/mislog_data_2.dbf':'/cogdbase/pqecog2/pqe_data/mislog_data_2.dbf'"

I kicked off the impdp. It has been running for an hour or so but will not finish for a long time. However, looking at the output database, several tablespaces have already been created and the REMAP_DATAFILE parameters seem to be working as expected: 

SQL> l
  1  select tablespace_name, file_name
  2  from dba_data_files
  3* order by 1,2
SQL> /
 
TABLESPACE_NAME      FILE_NAME
-------------------- --------------------------------------------------
COSTING_DATA         /cogdbase/pqecog2/pqe_data/costing_data1.dbf
COSTING_IDX1         /cogdbase/pqecog2/pqe_data/costing_idx1.dbf
COSTING_IDX1         /cogdbase/pqecog2/pqe_data/costing_idx2.dbf
DATEMOVE             /cogdbase/pqecog2/pqe_data/datemove.dbf
EVENT_MONITOR_DATA   /cogdbase/pqecog2/pqe_data/event_monitor_data.dbf
EVENT_MONITOR_INDEX  /cogdbase/pqecog2/pqe_data/event_monitor_index.dbf
MISLOG_DATA          /cogdbase/pqecog2/pqe_data/mislog_data.dbf
MISLOG_DATA          /cogdbase/pqecog2/pqe_data/mislog_data_1.dbf
MISLOG_DATA          /cogdbase/pqecog2/pqe_data/mislog_data_2.dbf
SYSAUX               /cogdbase/pqecog2/pqe_system/sysaux01.dbf
SYSTEM               /cogdbase/pqecog2/pqe_system/system01.dbf
UNDOTBS1             /cogdbase/pqecog2/pqe_system/undotbs01.dbf
USERS                /cogdbase/pqecog2/pqe_system/users01.dbf
 
13 rows selected.
 
SQL>

The Recycle Bin does not Store Tables from the SYSTEM Tablespace

Oracle introduced the recyclebin in version 10. This post shows that tables in the SYSTEM tablespace do not go into the recyclebin when they are dropped. It was tested on Oracle 11.2.0.2.7. First I created a table in the USERS tablespace: 

SQL> conn / as sysdba
Connected.
SQL> create table tab1
  2  (col1 number)
  3  tablespace users
  4  /
 
Table created.

SQL>

Then I dropped the table, checked that I could see it in the recyclebin and restored it:
 
SQL> drop table tab1
  2  /
 
Table dropped.
 
SQL> select original_name from recyclebin
  2  /
 
ORIGINAL_NAME
--------------------------------
TAB1
 
SQL> flashback table tab1 to before drop
  2  /
 
Flashback complete.
 
SQL> desc tab1
Name                       Null?    Type
-------------------------- -------- ------------------
COL1                                NUMBER

SQL>

Then I repeated the process but created the table in the SYSTEM tablespace instead:

SQL> create table tab2
  2  (col1 number)
  3  tablespace system
  4  /
 
Table created.
 
SQL> drop table tab2
  2  /
 
Table dropped.

SQL>

This time, when I looked in the recyclebin, it was not there:
 
SQL> select original_name from recyclebin
  2  /
 
no rows selected

SQL>

... and when I tried to restore the table, I was unable to do so: 
 
SQL> flashback table tab2 to before drop
  2  /
flashback table tab2 to before drop
*
ERROR at line 1:
ORA-38305: object not in RECYCLE BIN
 

Viewing all 330 articles
Browse latest View live