Thursday, December 27, 2012

How to recreate the AWR Repository

last week we were upgrading our test databases from 11.2.0.2 to 11.2.0.3
All most all of them went fine but one wouldn't complete the upgrade. It didn't show
an error it just hung and that was it.
We stop the upgrade and downgrade the database back to 11.2.0.2

The name of database got me thinking as this was a database where awr reports
took forever or couldn't even be started. Also purging the awr repository cause the
database to hang.
Oracle suggested to upgrade to 11.2.0.3 as this would fix te problem but we got the problem that
the database hung during upgrade.

The real solution was to recreate the awr reporsitory.
and this is how it goes in an Rac cluster.

First diabled AWR statistics gathering parameter
SQL> alter system set statistics_level=BASIC scope=both sid='*';
ERROR at line 1:
ORA-02097: parameter cannot be modified because specified value is invalid
ORA-00830: cannot set statistics_level to BASIC with auto-tune SGA enabled

Yep you have to set sga_target or memory_target to 0.
so create a pfile from spfile and adjust the following parameters
SQL>create pfile from spfile;
this create as pfile in $ORACLE_HOME/dbs

set the following parameters to a appropriate value
shared_pool_size =
db_cache_size =
java_pool_size =
large_pool_size =
sga_target=0
memory_target=0
statistics_level=basic
cluster_database=false

shutdown database and startup in resticted mode and with the pfile in $ORACLE_HOME/dbs
SQL>shutdown immediate;
SQL>startup restrict;

Now drop an recreate the awr objects.

SQl>@/rdbms/admin/catnoawr.sql
SQL>alter system flush shared_pool;
SQl>@/rdbms/admin/catawrtb.sql
SQL>@/rdbms/admin/execsvrm.sql  # Only if database is 11g

recompile the invalid objects
SQL>@/rdbms/admin/utlrp.sql 

SQL>shutdown immediate;

Now start the database with the spfile with the old values;

After that we started the upgrade to 11.2.0.3 and that went fine without any problem.

That it.

CRS-5005: IP Address: is already in use in the network

After a change in ASM process parameter i restared the crs stack.
Everything went fine... almost the following resource are offline

ora.srvtst01.vip
ora.LISTENER.lsnr
ora.srvtst01.LISTENER_SRVTST01.LSNR

when i tried start the ora.srvtst01.vip i got the following error
$ crsctl start res ora.srvtst01.vip
CRS-2672: Attempting to start 'ora.srvtst01.vip' on 'srvtst01'
CRS-5017: The resource action "ora.srvtst01.vip start" encountered the following error:
CRS-5005: IP Address: 10.110.140.173 is already in use in the network
 CRS-2674: Start of 'ora.srvtst01.vip' on 'srvtst01' failed
CRS-2679: Attempting to clean 'ora.srvtst01.vip' on 'srvtst01'
CRS-2681: Clean of 'ora.srvtst01.vip' on 'srvtst01' succeeded
CRS-2632: There are no more servers to try to place resource 'ora.srvtst01.vip' on that would satisfy its placement policy
CRS-4000: Command Start failed, or completed with errors.
That is strange the vip ip address should not be in use off course
$ nslookup srvtst01
Server:         145.72.247.10
Address:        145.72.247.10#53

Name:   srvtst01.italie.nl
Address: 10.110.140.73

root@oesv7040:CRS:/root
$ nslookup srvtst01-vip.italie.nl.
Server:         145.72.247.10
Address:        145.72.247.10#53

Name:   srvtst01-vip.italie.nl
Address: 10.110.140.173

As you see the ip address for the host and vip are different. When a do a SSH whith the vip ip 10.110.140.173  i  connect to the host srvtst01 what is good.When i look with ifconfig command i don't see the  IP address of the vip.
$ ifconfig
eth0      Link encap:Ethernet  HWaddr 00:16:3E:70:40:01
          inet addr:10.110.140.73  Bcast:10.233.240.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:43716169 errors:0 dropped:0 overruns:0 frame:0
          TX packets:10090483 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:8036689632 (7.4 GiB)  TX bytes:98860268867 (92.0 GiB)

eth1      Link encap:Ethernet  HWaddr 00:16:3E:70:40:02
          inet addr:172.29.96.64  Bcast:172.29.96.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:19477710 errors:0 dropped:0 overruns:0 frame:0
          TX packets:9399 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:2589277692 (2.4 GiB)  TX bytes:9266153 (8.8 MiB)

eth1:1    Link encap:Ethernet  HWaddr 00:16:3E:70:40:02
          inet addr:169.254.168.11  Bcast:169.254.255.255  Mask:255.255.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:25295206 errors:0 dropped:0 overruns:0 frame:0
          TX packets:25295206 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:37308951844 (34.7 GiB)  TX bytes:37308951844 (34.7 GiB)
  As you see i'm missing the vip ip address. I only see the host ip address.
To correct this i've to make a network alias and adjust it to ETH0 as it shoud be.

$ ifconfig eth0:1 10.110.140.173 up
$ ifconfig
eth0      Link encap:Ethernet  HWaddr 00:16:3E:70:40:01
          inet addr:10.233.240.73  Bcast:10.233.240.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:43718610 errors:0 dropped:0 overruns:0 frame:0
          TX packets:10090883 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:8036957710 (7.4 GiB)  TX bytes:98860318155 (92.0 GiB)

eth0:1    Link encap:Ethernet  HWaddr 00:16:3E:70:40:01
          inet addr:10.110.140.173  Bcast:10.255.255.255  Mask:255.0.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

As you see there is now a eth0:1 with the ip address of the vip.
Now i start the vip
$ crsctl start res ora.srvtst01.vip
CRS-2672: Attempting to start 'ora.srvtst.vip' on 'srvtst01'
CRS-2676: Start of 'ora.srvtst01.vip' on 'srvtst7040' succeeded
Why O why the eth0:1 was missing is still a ridle.

Thats it

RMAN-20052: invalid datafile create SCN

I ran last week into a bug in rman. Some backup's didn't run anymore.
The error was

RMAN-00571: ===========================================================
RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============
RMAN-00571: ===========================================================
RMAN-03015: error occurred in stored script arch_backup
RMAN-03002: failure of sql command at 12/24/2012 11:10:08
RMAN-03014: implicit resync of recovery catalog failed
RMAN-03009: failure of full resync command on default channel at 12/24/2012 11:10:08
RMAN-20052: invalid datafile create SCN

There is a bug written for this.
Resync Catalog returns RMAN-20052: invalid datafile create SCN error [ID 343213.1]

The solution that is given missed 1 step.
They suggest you should unregister the database and then register the database.
When more backups are in the controlfile than in the catalog you will wipe information with this action.

How to check this

1. Look what the oldest backup entry is in the controlfile.
   start rman
   rman> connect target;
   rman> list backup of summary;

   look for the oldest backup entry.

2.check what the oldest backup entry is in the catalog
            sqlplus owner_rmn@rman_catalog
select incr_level, min(to_char(completion_time,'DD-MM-YYYY/HH24:mi:ss')) as end_time_backup
from owner_rmn.bs where status='A'
and db_key in (select db_key from owner_rmn.dbinc where db_name = UPPER('&dbnaam') )
group by incr_level;
è Look what the oldest backup entry is.
 
3. Compare these entries,
    if the catalog contains older backup entries than the control file
    then action 3a
    else action 3b.

Action 3a:
Buy time by making archive backup and full backup connected to the rman catalog only.
The solution is to make insert commando’s before the unregister, based on the current catalog info to re-insert the backupsets you will lose with the unregister and register action.

Action 3b:
Else: do an unregister and a register action:
SQL> select 'EXECUTE dbms_rcvcat.unregisterdatabase(' || db_key||','||dbid||');' from rc_database where  name = '&dbname';
è You will be asked for the database name and you will execute the outcome of the query.
exit

<SID of the database, thus on the host were the database resides>
rman target / catalog owner_rmn@rman_catalog
register database;
show all;
è Check if everything is ok

That's it.

Friday, October 26, 2012

oracle password file in Oracle 11gr2 on rac cluster

Since Oracle 11gr2 there is very cool new enhancement regarding the password file while running a rac cluster. If you add a user to the password file on node 1 is also automaticaly propagated to node 2 password file.

SQL> select * from gv$pwfile_users order by inst_id;
INST_ID     USERNAME            SYSDBA          SYSOPER         SYSASM
---------- ------------------------ --------------- --------------- ---------------
         1          SYS                               TRUE            TRUE            FALSE
         2          SYS                               TRUE            TRUE            FALSE
  
There is the user sys on node 1 and 2. The password file is for both node's on a local filesystem $ORACLE_HOME/dbs

now we create the user asmsnmp.

SQL> create user asmsnmp identified by whatever;
SQL> grant sysdba to asmsnmp;
SQL> select * from gv$pwfile_users order by inst_id;
   INST_ID  USERNAME   SYSDBA          SYSOPER         SYSASM
----------   ---------- --------------- --------------- ---------------
         1         SYS                TRUE            TRUE            FALSE
         1        ASMSNMP    TRUE            FALSE           FALSE
         2        SYS                TRUE            TRUE             FALSE
         2        ASMSNMP    TRUE            FALSE           FALSE

And there you have it. The user asnmsnmp is on both node's.
Normally the user asmsnmp already exsist. Only when you removed the password file then you have to created again.

In all version before 11gr2 the user was created on the node where you created the user.

SQL> select * from v$version;
Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - 64bit Production
PL/SQL Release 11.1.0.6.0 - Production
CORE    11.1.0.6.0      Production
TNS for Linux: Version 11.1.0.6.0 - Production
NLSRTL Version 11.1.0.6.0 - Production
SQL> select * from gv$pwfile_users order by inst_id;
INST_ID     USERNAME            SYSDBA          SYSOPER         SYSASM
---------- ------------------------ --------------- --------------- ---------------
         1          SYS                               TRUE            TRUE            FALSE
         2          SYS                               TRUE            TRUE            FALSE

Now create the user asmsnmp.

SQL> create user asmsnmp identified by whatever;
SQL> grant sysdba to asmsnmp;
SQL> select * from gv$pwfile_users order by inst_id;
   INST_ID  USERNAME   SYSDBA          SYSOPER         SYSASM
----------   ---------- --------------- --------------- ---------------
         1         SYS                TRUE            TRUE            FALSE
         1        ASMSNMP    TRUE            FALSE           FALSE
         2        SYS                TRUE            TRUE             FALSE
       
As you see the user asmsnmp is only created on the first node. You have now an inconsistentie.
So before 11gr2 you never should forget to run the create command or grant command also on the second node.

Friday, October 12, 2012

Encountered unrecognized patch ID: SLMA

When installing the soa suite i ran in to an error when patching.
 Encountered unrecognized patch ID: SLMA

$ /install/install_sw/fmw/patch_install/bin/MWPatch.sh -m /u01/app/oracle/product/11.1.1/middleware
The following components are found in /u01/app/oracle/product/11.1.1/middleware and /u01/app/oracle/java and will be checked for patching:
- oracle_common (11.1.1.2.0)
- Oracle SOA (11.1.1.6.0)
- WebLogic Server (10.3.6.0)
- JRockit (R28.2.3)

Start patching...
SKIPPING: JRockit (R28.2.3) already up to date or higher version than patch version (R28.2.3)
Patching WebLogic Server 10.3.6.0 with patch 13583235 via patch module bsu
Patch 13583235 consist of 1 patch(es)
Check if patch(es) SLMA are already installed...
Patch(es) SLMA are not installed, start patching...
Installing patchlist SLMA into /u01/app/oracle/product/11.1.1/middleware/wlserver_10.3 from patchdir /u01/app/oracle/product/11.1.1/middleware/utils/bsu/cache_dir
ERROR:
Encountered unrecognized patch ID: SLMA
Installing patchlist SLMA into /u01/app/oracle/product/11.1.1/middleware/wlserver_10.3 from patchdir /u01/app/oracle/product/11.1.1/middleware/utils/bsu/cache_dir
ERROR:
Encountered unrecognized patch ID: SLMA
REPLACING: OPatch (11.1.0.9.0) with OPatch version (11.1.0.9.4) in /u01/app/oracle/product/11.1.1/middleware/oracle_common/
REPLACING: OPatch (11.1.0.9.0) with OPatch version (11.1.0.9.4) in /u01/app/oracle/product/11.1.1/middleware/Oracle_SOA1/

Oracle has released the latest SmartUpdate 3.3 which can only be used to apply patches.
There is 1 known error and yes that is Encountered unrecognized patch ID.

The problem is that there is an old version of patch-catalog.xml.
You can find that on $MWHOME/utils/bsu/cache_dir

$ ls -altr
total 31748
-rwxrwxr-- 1 oracle dba 12217838 Jun 11 16:21 patch-catalog.xml.p7ni
-rwxrwxr-- 1 oracle dba 12217838 Jun 11 16:21 patch-catalog.xml
-rwxrwxr-- 1 oracle dba    20495 Jun 11 16:21 P7NI.jar
-rw-r--r-- 1 oracle dba   129952 Jun 11 16:23 prod-info.xml
-rw-r--r-- 1 oracle dba   456151 Jun 11 16:23 PBY8.jar
-rwxrwx--- 1 oracle dba   141444 Oct 11 08:39 SLMA.jar
-rwxrwx--- 1 oracle dba  7247271 Oct 11 08:39 patch-catalog.xml.13583235
drwxrwxr-x 2 oracle dba     4096 Oct 11 08:39 .
drwxrwxr-x 3 oracle dba     4096 Oct 11 08:48 ..
You'll see the  patch-catalog.xml is from 11-jun. You'll see also that there is a new patch-catalog.xml.13583235. This one was created during the patching i was doing.
You have to make that version the new patch-catalog.xml.

Now where going to replace to old patch-catalog.xml with th new one

$ cp patch-catalog.xml patch-catalog.old.yymmdd # Better safe then sorry
$ rm patch-catalog.xml
$ cp patch-catalog.xml.13583235 patch-catalog.xml

$ ls -altr
total 38840
-rwxrwxr-- 1 oracle dba 12217838 Jun 11 16:21 patch-catalog.xml.p7ni
-rwxrwxr-- 1 oracle dba    20495 Jun 11 16:21 P7NI.jar
-rw-r--r-- 1 oracle dba   129952 Jun 11 16:23 prod-info.xml
-rw-r--r-- 1 oracle dba   456151 Jun 11 16:23 PBY8.jar
-rwxrwx--- 1 oracle dba   141444 Oct 11 08:39 SLMA.jar
-rwxrwx--- 1 oracle dba  7247271 Oct 11 08:39 patch-catalog.xml.13583235
drwxrwxr-x 3 oracle dba     4096 Oct 11 08:48 ..
-rwxrwx--- 1 oracle dba 12217838 Oct 11 08:59 patch-catalog.old_11102012
-rwxrwx--- 1 oracle dba  7247271 Oct 11 09:00 patch-catalog.xml
drwxrwxr-x 2 oracle dba     4096 Oct 11 09:00 .

Now try again

$ /install/install_sw/fmw/patch_install/bin/MWPatch.sh -m /u01/app/oracle/product/11.1.1/middleware
The following components are found in /u01/app/oracle/product/11.1.1/middleware and /u01/app/oracle/java and will be checked for patching:
- oracle_common (11.1.1.2.0)
- Oracle SOA (11.1.1.6.0)
- WebLogic Server (10.3.6.0)
- JRockit (R28.2.3)

Start patching...
SKIPPING: JRockit (R28.2.3) already up to date or higher version than patch version (R28.2.3)
Patching WebLogic Server 10.3.6.0 with patch 13583235 via patch module bsu
Patch 13583235 consist of 1 patch(es)
Check if patch(es) SLMA are already installed...
Patch(es) SLMA are not installed, start patching...
Installing patchlist SLMA into /u01/app/oracle/product/11.1.1/middleware/wlserver_10.3 from patchdir /u01/app/oracle/product/11.1.1/middleware/utils/bsu/cache_dir
Patch 13583235 succesfully installed
SKIPPING: OPatch (11.1.0.9.4) in /u01/app/oracle/product/11.1.1/middleware/oracle_common/ already up to date or higher version than patch version (11.1.0.9.4)
SKIPPING: OPatch (11.1.0.9.4) in /u01/app/oracle/product/11.1.1/middleware/Oracle_SOA1/ already up to date or higher version than patch version (11.1.0.9.4)

And you see it when fine now.
If it still gives the same error you can use bsu.sh to trace.
This is located in the middleware home/utils/bsu
$ ./bsu.sh -report -log=test.log -log_priority=trace
Patch Report
============
  Report Info
    Report Options
      bea_home.................. ### OPTION NOT SET
      product_mask.............. ### OPTION NOT SET
      release_mask.............. ### OPTION NOT SET
      profile_mask.............. ### OPTION NOT SET
      patch_id_mask............. ### OPTION NOT SET
    Report Messages
  BEA Home.................. /u01/app/oracle/product/11.1.1/middleware
  Product Description
  Product Name.............. WebLogic Server
  Product Version........... 10.3.6.0
  Installed Components...... Core Application Server, Administration Console, Configuration Wizard and Upgrade Framework, Web 2.0 HTTP Pub-Sub Server, WebLogic SCA, WebLogic JDBC Drivers, Third Party JDBC Drivers, WebLogic Server Clients, WebLogic Web Server Plugins, UDDI and Xquery Support, Server Examples, Evaluation Database, Workshop Code Completion Support
  Product Install Directory. /u01/app/oracle/product/11.1.1/middleware/wlserver_10.3
  Java Home................. null
  Jave Vendor............... Sun
  Java Version.............. 1.6.0_29
  Patch Directory........... /u01/app/oracle/product/11.1.1/middleware/patch_wls1036
  Product Description
  Product Name.............. Oracle Coherence
  Product Version........... 3.7.1.1
  Installed Components...... Coherence Product Files, Coherence Examples
  Product Install Directory. /u01/app/oracle/product/11.1.1/middleware/coherence_3.7
  Java Home................. null
  Jave Vendor............... null
  Java Version.............. null
  Patch Directory........... /u01/app/oracle/product/11.1.1/middleware/patch_ocp371
You can check the logfile for error message's that can lead you to what is the cause.
In my trace file of course  there where no error message to be found.

Hope it helps.

Friday, October 5, 2012

Convert Oracle Database from Aix to Linux

We are in the middle of the migration of our Oracle 10gr2 databases to 11gr2 but also leaving our old Aix platform to go to readheat linux.
This means also we go from Big Endian format(Aix - Based Systens (64-bit) to Little Endian format on Linux IA (64-bit). We did them all with the export import method but now with the larger databases we want to use convert datafile rman command fo migrating the database.
Here are the steps how we did this for our Simcorp database.

To find out witch endian your platform has you use the following query

SQL> select * from v$transportable_platform;
PLATFORM_ID PLATFORM_NAME                            ENDIAN_FORMAT
----------- ---------------------------------------- --------------
          1 Solaris[tm] OE (32-bit)                                   Big
          2 Solaris[tm] OE (64-bit)                                   Big
          7 Microsoft Windows IA (32-bit)                      Little
         10 Linux IA (32-bit)                                           Little
          6 AIX-Based Systems (64-bit)                          Big
          3 HP-UX (64-bit)                                             Big
          5 HP Tru64 UNIX                                           Little
          4 HP-UX IA (64-bit)                                       Big
         11 Linux IA (64-bit)                                         Little
         15 HP Open VMS                                           Little
          8 Microsoft Windows IA (64-bit)                    Little
PLATFORM_ID PLATFORM_NAME                            ENDIAN_FORMAT
----------- ---------------------------------------- --------------
          9 IBM zSeries Based Linux                             Big
         13 Linux x86 64-bit                                         Little
         16 Apple Mac OS                                           Big
         12 Microsoft Windows x86 64-bit                   Little
         17 Solaris Operating System (x86)                   Little
         18 IBM Power Based Linux                            Big
         20 Solaris Operating System (x86-64)             Little
         19 HP IA Open VMS                                     Little

As we are on Aix Based system Big endian and Linux IA is on Litle endian.
First a ran my script that create the script we use for the convert.

set feedback off trimspool off verify off
set head off
set lines 100
set pages 0
spool convert_dt.rcv
prompt run
prompt {
select 'CONVERT DATAFILE' from dual;
select case when rownum!=e.aantal then ''''||d.file_name||''''||','
when rownum=e.aantal then ''''||d.file_name||''''||''  end
from (select count(*) aantal from dba_tablespaces f,dba_data_files g
where f.tablespace_name = g.tablespace_name
and f.tablespace_name not in ('SYSTEM','SYSAUX','TOOLS','USERS')
and f.contents = 'PERMANENT'
order by f.tablespace_name)
 ,(select substr(upper(file_name),instr(file_name,'/',-1)+1) file_name
from dba_tablespaces a, dba_data_files b
where a.tablespace_name = b.tablespace_name
and a.tablespace_name not in ('SYSTEM','SYSAUX','TOOLS','USERS')
and contents = 'PERMANENT'
order by a.tablespace_name) d,(select count(*) aantal from dba_tablespaces f,dba_data_files g
where f.tablespace_name = g.tablespace_name
and f.tablespace_name not in ('SYSTEM','SYSAUX','TOOLS','USERS')
and f.contents = 'PERMANENT'
order by f.tablespace_name) e
/
prompt FROM PLATFORM 'AIX-Based Systems (64-bit)'
prompt PARALLELISM 4
prompt FORMAT '+DATA/'
select ';' from dual;
prompt }
spool off
set head off
set feedb off
set pages 0
set lines 80
set verify off
set timing off
spool source_exp.par
prompt directory=data_pump_dir
prompt dumpfile=exp_db.dmp
prompt transport_full_check=no
select 'transport_tablespaces=' from dual
/
select case when rownum!=b.aantal then tablespace_name||','
when rownum=b.aantal then tablespace_name||''  end
from dba_tablespaces a,(select count(*) aantal from dba_tablespaces
where tablespace_name not in ('SYSTEM','SYSAUX','TOOLS','USERS')
and contents = 'PERMANENT'
order by tablespace_name) b
where tablespace_name not in ('SYSTEM','SYSAUX','TOOLS','USERS')
and contents = 'PERMANENT'
order by tablespace_name
/
prompt log=exp_db.log
spool off
spool target_import.par

prompt directory=data_pump_dir
prompt dumpfile=exp_db.dmp
prompt logfile=import_db.log
select 'transport_datafiles=' from dual
/
select case when rownum!=b.aantal then ''''||file_name||''''||','
when rownum=b.aantal then  ''''||file_name||''''||''  end
from dba_data_files a,(select count(*) aantal from dba_data_files
where tablespace_name not in ('SYSTEM','SYSAUX','TOOLS','USERS','TEMP','UNDO')
order by tablespace_name) b
where tablespace_name not in ('SYSTEM','SYSAUX','TOOLS','USERS','TEMP','UNDO')
order by tablespace_name
/
spool off
spool ro_tbs.sql
select 'alter tablespace '||tablespace_name||' read only;'
from dba_tablespaces
where tablespace_name not in ('SYSTEM','SYSAUX','TOOLS','USERS')
and contents = 'PERMANENT'
group by tablespace_name
/
spool off
spool rw_tbs.sql
select 'alter tablespace '||tablespace_name||' read write;'
from dba_tablespaces
where tablespace_name not in ('SYSTEM','SYSAUX','TOOLS','USERS')
and contents = 'PERMANENT'
group by tablespace_name
/
spool off

set heading off feedback off trimspool on linesize 140 pages 0
spool drop_tbs.sql
select 'DROP TABLESPACE '||tablespace_name ||' INCLUDING CONTENTS AND DATAFILES;'
from dba_tablespaces
where tablespace_name not in ('SYSTEM','SYSAUX','TOOLS','USERS')
and contents = 'PERMANENT';
spool off
col USERDDL format A150
set pages 0
spool sys_privs.sql
select 'grant '||privilege||' on '||table_name||' to '||grantee||' '||
decode(grantable,'YES',' with grant option ')||
decode(hierarchy,'YES',' with hierarchy option ')||
';'
from dba_tab_privs
where owner in
(select name
from system.logstdby$skip_support
where action=0)
and grantee in
(select username
from dba_users
where username not in
(select name
from system.logstdby$skip_support
where action=0) )
/
spool off
This create's the following scripts.
@ro_tbs.sql     # script to set tablespace on source database in read only mode
@rw_tbs.sql     #script to set tablespace on target database in read write mode
@sys_priv.sql   #script to grant sys privileges from source database on target database
@sour_exp.par   # metadata parfile for tablespace from source database
@target_imp.par # metadata parfile to plugin tablespace in target database
@drop_tbs.sql        # drop user tablespaces in target database

In our case were going to migrate Simcorp database SCD401P1 on Aix to Linux SC451P1.
make sure the characterset of both databases are th same

SQL> select * from database_properties where property_name like '%CHARACTERSET';
PROPERTY_NAME                  PROPERTY_VALUE                 DESCRIPTION
------------------------------ ------------------------------ ------------------------------
NLS_NCHAR_CHARACTERSET         UTF8                           NCHAR Character set
NLS_CHARACTERSET               WE8MSWIN1252                   Character set
The Target database SC451P1 is created with only the default tablespaces.sysaux,system,tools,users,undo and temp.

First we create a database link in the target database SCD451P1.
under user system.
SQL> CREATE DATABASE LINK TSS_LINK USING 'SCD401P1';

Don't forget to put the source database SCD401P1  in the tnsnames.ora on the server where the target database SCD451P1  is running.

On the target database SCS451P1 we create the tablespaces were going to convert later from the source database. We only do this so that the impdp of user,role and profiles runs without errors. Later on we drop those tablespaces again. this are the tablespaces
FBT4_D
FBT4_I
SCAUDIT
SCAUDIX
SCDAT
SCINDX
SCQUEUE
SCSYS
SCTRDARC
SCTRDDAT
SCTRDIDX
SCUSERS

Now we import the user,profiles roles roles_grant from source SCD401P1to SCD451P1
We do this on the target server

$ impdp system DIRECTORY=data_pump_dir LOGFILE=user_imp.log NETWORK_LINK=tss_link FULL=y INCLUDE=PROFILE,USER,ROLE,ROLE_GRANT

After that al users,profiles,roles and role_grant exsist in the target database.

Now we run export the metadata from the source database SCD401P1 on the source server
$ expdp system DIRECTORY=data_pump_dir \
LOGFILE=full_exp_meta.log \
DUMPFILE=full_exp_meta.dmp FULL=y \
CONTENT=METADATA_ONLY \
EXCLUDE=USER,ROLE,ROLE_GRANT,PROFILE \
PARALLEL=6

Shutdown the application if needed.
Set tablespace on source database SCD401P1 read only.
SQL>@ro_tbs.sql

export user tablespaceses source database SCD401P1
We use the parfile source_exp.par
cat source_exp.par
directory=data_pump_dir
dumpfile=exp_db.dmp
transport_full_check=no
transport_tablespaces=
FBT4_D,
FBT4_I,
SCAUDIT,
SCAUDIX,
SCDAT,
SCINDX,
SCQUEUE
SCSYS,
SCTRDARC,
SCTRDDAT,
SCTRDIDX,
SCUSERS,
log=exp_db.log
$ expdp system parfile=source_exp.par

Now drop the user tablespaces on the target database SCD451P1 we created for the import for the users,roles ...

Don't forget on the server where the target database SCD451P1 runs
SQL>drop_tbs.sql

Now we can run the convert script.
First we created an nfs mount for the filesystem were the datafiles are. In our case it was /oracle/SCD401P/DATA_01 .This is so on the target server(LINUX) we can access the
datafiles. In that way we can run rman from the target server.

The convert_dt.rcv looks like this
cat convert_dt
run
{
CONVERT DATAFILE
'FBT_D_01.DBF',
'FBT4_I_01.DBF',
'SCAUDIT_02.DBF',
'SCAUDIT_01.DBF',
'SCAUDIX_02.DBF',
'SCAUDIX_01.DBF',
'SCDAT_04.DBF',
'SCDAT_02.DBF',
'SCDAT_03.DBF',
'SCDAT_14.DBF',
'SCDAT_01.DBF',
'SCINDX_01.DBF',
'SCINDX_02.DBF',
'SCINDX_03.DBF',
'SCQUEUE_01.DBF',
'SCSYS_01.DBF',
'SCTRDARC.DBF',
'SCTRDDAT.DBF',
'SCTRDIDX.DBF',
'SCUSERS_01.DBF'
FROM PLATFORM 'AIX-Based Systems (64-bit)'
PARALLELISM 4
FORMAT '+DATA/'
;
}
As we start the rman script on linux the platform is from which is comes AIX in our case.
The datafile will be set on a ASM in the diskgroup DATA.

start the script
RMAN> connect target /
RMAN>@convert_dt.rcv

When it finished succesfully then we must import(plugin) all user tablespaces into the target database SCD451P1.

You have to manualy adjust the location of the datafiles(Sorry if i had thime enough i would write a script for this)as where going from filesystem to ASM.

$ vi target_import.par
directory=data_pump_dir
dumpfile=exp_db.dmp
logfile=import_db.log
transport_datafiles='+DATA/upg401p/datafile/ars4_arcm_d.265.791808391',
'+DATA/scd451p/datafile/ars4_arcm_i.257.791808377',
'+DATA/scd451p/datafile/ars4_arcm_l.264.791808399',
'+DATA/scd451p/datafile/ars4_bp_d.262.791808403',
'+DATA/scd451p/datafile/ars4_bp_i.261.791808405',
'+DATA/scd451p/datafile/ars4_d.258.791808311',
'+DATA/scd451p/datafile/ars4_i.259.791808227',
'+DATA/scd451p/datafile/ars4_l.260.791808409'

start the import
$ impdp gda001 parfile=target_import.par
set tablespaces on target database SCD451P1 read,write
SQL>@rw_tbs.sql
Now import the remaing metadata from the source database
into the target database
$ impdp gda001 DIRECTORY=data_pump_dir LOGFILE=full_imp.log DUMPFILE=full_exp_meta.dmp FULL=y PARALLEL=6

There you've it. Database is converted from aix to linux. and from 10.2.0.4 to 11.2.0.3
Only 1 thing to do
compile invalid objects.
SQL>@?/rdbms/admin/utlrp.sql

CRS-2566: User 'oracle' does not have sufficient permissions to operate on resource

The following error came up while creating an 4 node rac database on Oracle Unbreakle Linux.
CRS-2566: User 'oracle' does not have sufficient permissions to operate on resource

Exactly there was another error right before the CRS-2566 and that was
ERROR: failed to update diskgroup resource ora.DGTXXX.dg
Strange because i've created the diskgroup without error and its mounted.
I checked if the resource realy didn't exsist.

$ crsctl stat res -t |grep ora.DGTXXX.dg
Noting found. and then comes the second error and the cause of the problem

$ crsctl status resource xxx.test1-admin-vip -p
NAME=eco.paer1-admin-vip
TYPE=app.appvip_net1.type
ACL=owner:root:rwx,pgrp:root:r-x,other::r--,user:root:r-x
ACTION_FAILURE_TEMPLATE=
ACTION_SCRIPT=
ACTIVE_PLACEMENT=1
AGENT_FILENAME=%CRS_HOME%/bin/orarootagent%CRS_EXE_SUFFIX%
APPSVIP_FAILBACK=0
AUTO_START=restore
CARDINALITY=1
CHECK_INTERVAL=1
CHECK_TIMEOUT=30
DEFAULT_TEMPLATE=PROPERTY(RESOURCE_CLASS=vip)
DEGREE=1
DESCRIPTION=Application VIP
ENABLED=1
FAILOVER_DELAY=0
FAILURE_INTERVAL=0
FAILURE_THRESHOLD=0
GEN_USR_ORA_STATIC_VIP=
GEN_USR_ORA_VIP=
HOSTING_MEMBERS=GFM0001.test.nl
LOAD=1
LOGGING_LEVEL=1
NLS_LANG=
NOT_RESTARTING_TEMPLATE=
OFFLINE_CHECK_INTERVAL=0
PLACEMENT=balanced
PROFILE_CHANGE_TEMPLATE=
RESTART_ATTEMPTS=0
SCRIPT_TIMEOUT=60
SERVER_POOLS=*
START_DEPENDENCIES=hard(ora.net1.network) pullup(ora.net1.network)
START_TIMEOUT=0
STATE_CHANGE_TEMPLATE=
STOP_DEPENDENCIES=hard(ora.net1.network)
STOP_TIMEOUT=0
TYPE_VERSION=2.1
UPTIME_THRESHOLD=7d
USR_ORA_ENV=
USR_ORA_VIP=10.001.0001.10
VERSION=11.2.0.2.0

You must as the user who runs the scripts in our case oracle
have read and executer rights on the vips. If not then it can't
create the resource for the diskgroup

As you see in red that the acl(access control list) is there only for root.
The user oracle has no rights on this vip.
So we must grant oracle read and execute rights as on the group oradba.
this is how is looks before
$ crsctl getperm resource xxx.test1-admin-vip
Name: xxx.test1-admin-vip
owner:root:rwx,pgrp:root:r-x,other::r--,user:root:r-x

Now we grant read an executer rights to user oracle and group oradba
As user root(In my enviroment at least)

crsctl setperm resource xxx.test1-admin-vip -u user:oracle:r-x
crsctl setperm resource xxx.test1-admin-vip -g group:oradba:r-x

and then again run
$ crsctl getperm resource xxx.test1-admin-vip
 Name: xxx.test1-admin-vip
owner:root:rwx,pgrp:root:r-x,other::r--,user:root:r-x,user:oracle:r-x,group:oradba:r-x

After that i restarted the creation of the rac database and it when fine.

Wednesday, August 1, 2012

Virtual Columns 11G

Before 11g virtual columns where created when you created a function based index
They were also hidden. On virtual columns statistics can be created witch is usefull but
you had to create an index for it.

As of 11g you can define virtual columns and are visible in the table definition.

SQL>create table aap as select rownum a1,
         'AHH' a2
         FROM DUAL CONNECT BY LEVEL <= 100000;
SQL>CREATE INDEX aap_i ON aap(a2);
SQL> insert into aap values(100001,'GIN');
1 row created.
SQL> insert into aap values(100002,'Gin');
1 row created.
SQL> insert into aap values(100003,'GiN');
1 row created.
SQL> commit;
SQL>begin
         dbms_stats.gather_table_stats(ownname=>'GDA001',
         tabname=> 'AAP',
         cascade=> true,
         estimate_percent=>null,
         method_opt=> 'FOR ALL COLUMNS SIZE 1');
         end;
          /
SQL> SELECT * FROM AAP WHERE UPPER(a2)='GIN';
        A1 A2
---------- ---
    100001 GIN
    100002 Gin
    100003 GiN

Execution Plan
----------------------------------------------------------
Plan hash value: 3829027638

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |  1000 |  9000 |    54   (6)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| AAP  |  1000 |  9000 |    54   (6)| 00:00:01 |
--------------------------------------------------------------------------

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

   1 - filter(UPPER("A2")='GIN')

Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
        216  consistent gets
          0  physical reads
          0  redo size
        664  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)
          3  rows processed

As you see the index is not used because of the UPPER function.
Let create the function based index.

SQL> create index f_aap_a2_i on aap(UPPER(a2)) compute statistics;
Index created.
        A1 A2
---------- ---
    100001 GIN
    100002 Gin
    100003 GiN

Execution Plan
----------------------------------------------------------
Plan hash value: 2746435280

------------------------------------------------------------------------------------------
| Id  | Operation                   | Name       | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |            |  1000 |  9000 |    50   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| AAP        |  1000 |  9000 |    50   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | F_AAP_A2_I |   400 |       |   105   (0)| 00:00:02 |
------------------------------------------------------------------------------------------

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

   2 - access(UPPER("A2")='GIN')

Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          5  consistent gets
          0  physical reads
          0  redo size
        664  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)
          3  rows processed

As you see the index is now used.

SQL> select table_name, column_name, num_distinct,
          density, virtual_column, hidden_column
          from dba_tab_cols
         where table_name = 'AAP';
TABLE COLUMN_NAME     NUM_DISTINCT    DENSITY VIR HID
-----         ---------------               ------------              ---------- --- ---
AAP     SYS_NC00003$                       2                         .5        NO NO
AAP   A2                                               4                       .25         NO  NO
AAP   A1                                      100003                9.9997E-06 NO  NO

As you see there is a virtual column that is hidden.
and no statistics also

SQL> begin
dbms_stats.gather_table_stats(ownname=>'GDA001',
tabname=> 'AAP',
cascade=> true,
estimate_percent=>null,
method_opt=> 'FOR ALL HIDDEN COLUMNS SIZE 3');
end;
/

SQL> select table_name, column_name, num_distinct,
          density, virtual_column, hidden_column
          from dba_tab_cols
         where table_name = 'AAP';

TABLE COLUMN_NAME     NUM_DISTINCT    DENSITY VIR HID
-----     ---------------                   ------------             ---------- --- ---
AAP   SYS_NC00003$                         2                            .5 YES YES
AAP   A2                                               4                          .25 NO  NO
AAP   A1                                      100003            9.9997E-06 NO  NO
The virtual statistics are now in place.
Lets run the statement again

SQL>  SELECT * FROM AAP WHERE UPPER(a2)='GIN';
        A1 A2
---------- ---
    100001 GIN
    100002 Gin
    100003 GiN

Execution Plan
----------------------------------------------------------
Plan hash value: 2746435280
------------------------------------------------------------------------------------------
| Id  | Operation                   | Name       | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |            |     3 |    39 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| AAP        |     3 |    39 |     2   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | F_AAP_A2_I |     3 |       |     1   (0)| 00:00:01 |
------------------------------------------------------------------------------------------

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

   2 - access(UPPER("A2")='GIN')

Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
          5  consistent gets
          0  physical reads
          0  redo size
        664  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)
          3  rows processed
Al you now see also the statiscts are now much more accurate. there are 100000 rows with AHH and only
3 with GIN. The rows are now 3 before that is was 100000 and with the index 400.

Now the above was the method before 11g.
This is how you can do it in 11g

SQL> drop index F_AAP_A2_I;
Index dropped.
SQL> alter table aap add (upper_naam as (UPPER(a2)));
Table altered.
SQL>begin
         dbms_stats.gather_table_stats(ownname=>'GDA001',
         tabname=> 'AAP',
         cascade=> true,
         estimate_percent=>null,
         method_opt=> 'FOR ALL COLUMNS SIZE 1');
         end;
          /
SQL> select table_name, column_name, num_distinct,
          density, virtual_column, hidden_column
          from dba_tab_cols
         where table_name = 'AAP';
 
TABLE COLUMN_NAME     NUM_DISTINCT    DENSITY VIR HID
-----         ---------------               ------------              ---------- --- ---
AAP   UPPER_NAAM                          2                         .5        YES NO
AAP   A2                                               4                       .25         NO  NO
AAP   A1                                      100003                9.9997E-06 NO  NO

As you see the virtual column upper_naam is not hidding more.

SQL> select table_name, column_name
          from  dba_tab_columns
         where  table_name = 'AAP';
TABLE COLUMN_NAME
----- ---------------
AAP   A1
AAP   A2
AAP   UPPER_NAAM

SQL> SELECT * FROM AAP WHERE UPPER(a2)='GIN';
        A1 A2  UPP
---------- --- ---
    100001 GIN GIN
    100002 Gin GIN
    100003 GiN GIN

Execution Plan
----------------------------------------------------------
Plan hash value: 3829027638
--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |            | 50002 |   634K| 56(9)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| AAP  | 50002 |   634K|    56   (9)| 00:00:01 |
--------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   1 - filter("AAP"."UPPER_NAAM"='GIN')

Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
        216  consistent gets
          0  physical reads
          0  redo size
        744  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)
          3  rows processed
SQL> create index upper_naam_i on aap(upper(a2));
create index upper_naam_i on aap(upper(upper(a2))
                                       *
ERROR at line 1:
ORA-54018: A virtual column exists for this expression
So you can't create the index because there is virtual column

SQL> create index upper_naam_i on aap(upper_naam);
Index created.
But we can create a normal index on the virtual column

SQL> SELECT index_name, index_type FROM user_indexes WHERE index_name='UPPER_NAAM_I';
INDEX_NAME                     INDEX_TYPE
------------------------------ ---------------------------
UPPER_NAAM_I                   FUNCTION-BASED NORMAL

As you see the index type is function based

SQL> SELECT index_name, column_expression
          FROM user_ind_expressions
         WHERE index_name = 'UPPER_NAAM_I'; 

INDEX_NAME                     COLUMN_EXP
------------------------------ ----------
UPPER_NAAM_I                   UPPER("A2")
                              
SQL>  select * from aap where upper_naam =  'GIN';
        A1 A2  UPP
---------- --- ---
    100001 GIN GIN
    100002 Gin GIN
    100003 GiN GIN

Execution Plan
----------------------------------------------------------
Plan hash value: 2505477614
--------------------------------------------------------------------------------------------
| Id  | Operation                   | Name         | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |              |     3 |    39 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| AAP          |     3 |    39 |     2   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | UPPER_NAAM_I |     3 |       |     1   (0)| 00:00:01 |
--------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("UPPER_NAAM"='GIN')

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

And there is the index on the virtual column

Thats it