How to check whether user has datapump privilege

SQL>SET lines 100 
COL privilege FOR a50
SELECT grantee, granted_role, default_role
FROM dba_role_privs
WHERE granted_role IN ('DBA', 'EXP_FULL_DATABASE', 'IMP_FULL_DATABASE')
ORDER BY 1,2;
GRANTEE                        GRANTED_ROLE                   DEF
------------------------------ ------------------------------ ---
ARJU DBA YES
DBA EXP_FULL_DATABASE YES
DBA IMP_FULL_DATABASE YES
FARUK DBA YES
MOMIN DBA YES
SYS DBA YES
SYS EXP_FULL_DATABASE YES
SYS IMP_FULL_DATABASE YES
SYSMAN DBA YES
SYSTEM DBA YES
TEST EXP_FULL_DATABASE YES

 Check for granted privileges on directory objects

SET lines 110
COL privilege FOR a12
COL grantee FOR a25
COL owner FOR a25
SELECT p.grantee, p.privilege, p.owner, d.directory_name
FROM dba_tab_privs p, dba_directories d
WHERE p.table_name=d.directory_name
AND (grantee IN ('TEST', 'PUBLIC')
OR grantee IN (SELECT granted_role FROM dba_role_privs
WHERE grantee IN ('TEST', 'PUBLIC')))
ORDER BY 4,3,2;
A typical output is 
GRANTEE PRIVILEGE OWNER DIRECTORY_NAME
-------------------- ---------- -------------------- -----------------
TEST READ SYS D
TEST WRITE SYS D
EXP_FULL_DATABASE READ SYS DATA_PUMP_DIR
EXP_FULL_DATABASE WRITE SYS DATA_PUMP_DIR

Directory Name : TEST 

Check for tablespace quota
 
SET lines 100 numwidth 12
SELECT q.username, q.tablespace_name, q.bytes, q.max_bytes
FROM dba_ts_quotas q, dba_users u
WHERE q.username=u.username AND q.username in ('TEST');
USERNAME                       TABLESPACE_NAME                       BYTES    MAX_BYTES
------------------------------ ------------------------------ ------------ ------------
TEST SYSTEM 65536 10485760


OCR And Voting In 11gR2

OCR: It created at the time of Grid Installation. It’s store information to manage Oracle cluster-ware and it’s component such as RAC database, listener, VIP,Scan IP & Services.
Minimum 1 and maximum 5 copy of OCR is possible.

Voting Disk: It manage information about node membership. Each voting disk must be accessible by all nodes in the cluster.If any node is not passing heat-beat across other note or voting disk, then that node will be evicted by Voting disk.
Minimum 1 and maximum 15 copy of voting disk is possible.

New Facts:
  • We can store OCR And Voting disk on ASM or certified cluster file system.
  • We can dynamically add or replace voting disk & OCR.
  • Backup of Voting disk using “dd” command not supported.
  • Voting disk and OCR can be keep in same disk-group or different disk-group
  • Voting disk and OCR automatic backup kept together in a single file.
  • Automatic backup of Voting disk and OCR happen after every four hours, end of the day, end of the week
  • You must have root or sudo privilege account to manage it.

To find current location of Voting disk:

[oracle@rsingle ~]$ crsctl query css votedisk
##  STATE    File Universal Id                File Name Disk group
–  —–    —————–                ——— ———
1. ONLINE   6a60a2c3510c4fbfbff62dcdc279b247 (ORCL:DATA1) [DATA]

Relocate or multiplexing Voting disk to another disk-group (With normal redundancy)

[root@rsingle ~]# /u01/app/11.2.0/grid/bin/crsctl replace votedisk +CRS
Successful addition of voting disk afb77b2693a24f1ebfe876784103e82a.
Successful addition of voting disk 3e2542c5b1154ffdbfc8b6dea7dce390.
Successful addition of voting disk 8e0f3c5921cc4f93bf223de1465d83cc.
Successful deletion of voting disk 6a60a2c3510c4fbfbff62dcdc279b247.
Successfully replaced voting disk group with +CRS.
CRS-4266: Voting file(s) successfully replaced

New location of Voting disk:

[root@rsingle ~]# /u01/app/11.2.0/grid/bin/crsctl query css votedisk

##  STATE    File Universal Id                File Name Disk group
–  —–    —————–                ——— ———
1. ONLINE   afb77b2693a24f1ebfe876784103e82a (ORCL:DATA2) [CRS]
2. ONLINE   3e2542c5b1154ffdbfc8b6dea7dce390 (ORCL:DATA3) [CRS]
3. ONLINE   8e0f3c5921cc4f93bf223de1465d83cc (ORCL:DATA4) [CRS]
Located 3 voting disk(s).

To find location of Corrent OCR:

[oracle@rsingle ~]$ ocrcheck

Status of Oracle Cluster Registry is as follows :
Version                  :          3
Total space (kbytes)     :     262120
Used space (kbytes)      :       2964
Available space (kbytes) :     259156
ID                       : 1390115973
Device/File Name         :      +DATA
Device/File integrity check succeeded
Device/File not configured
Device/File not configured
Device/File not configured
Device/File not configured
Cluster registry integrity check succeeded
Logical corruption check bypassed due to non-privileged user

Create mirror copy of OCR online

[oracle@rsingle ~]$ sudo ocrconfig -add +CRS
Password:

Check location of OCR after mirror copy creation:

[root@rsingle ~]# /u01/app/11.2.0/grid/bin/ocrcheck

Status of Oracle Cluster Registry is as follows :
Version                  :          3
Total space (kbytes)     :     262120
Used space (kbytes)      :       2964
Available space (kbytes) :     259156
ID                       : 1390115973
Device/File Name         :      +DATA
Device/File integrity check succeeded
Device/File Name         :       +CRS
Device/File integrity check succeeded
Device/File not configured
Device/File not configured
Device/File not configured
Cluster registry integrity check succeeded
Logical corruption check succeeded

Another file to find location of OCR:

[root@rsingle ~]# cat /etc/oracle/ocr.loc
#Device/file  getting replaced by device +CRS
ocrconfig_loc=+DATA
ocrmirrorconfig_loc=+CRS

Share it for knowledge

Thank you atual
 Osama mustafa

Scripts For Backup

This Script Will Let you choose One Of three Type Of backup , All you have to do right the backup scripts to make the below script read it and run it :

#!/bin/bash
ORACLE_SID=ORCL;export ORACLE_SID
echo $ORACLE_SID
echo “Please Specify the kind of backup you want to take”
echo “1) COLD BACKUP”
echo “2) HOT BACKUP”
echo “3) EXPORT BACKUP”
echo “Enter your option”
read option
 while [ $option -gt 3 ]||[ $option -le 0 ]
do
echo “Please Enter the correct option”
read option
done
case $option in
1|2) echo “You are taking rman backup of DB”
   rman target sys/sys @/oracle/product/11g/rman_backup_$option.txt;exit;;
3) echo “You are taking export backup of DB”
   exp system/sys file=/oracle/exp_dat.dmp log=/oracle/exp_dat.log full=y;
   exit;;
esac
exit

 The above script can call anyone of the following rman script depending upon the user who wants take cold or hot backup

The content of rman_backup_1.txt

run {
   shutdown immediate;
   startup mount;
   allocate channel dup1 device type disk;
   allocate channel dup2 device type disk;
   backup format ‘/oracle/%U’ database;
   release channel dup1;
   release channel dup2;
   alter database open;
  }

The content of rman_backup_2.txt

run {
allocate channel dup1 device type disk;
allocate channel dup2 device type disk;
backup format ‘/oracle/%U’ database;
backup format ‘/oracle/arch_%U’ archivelog all;
backup format ‘/oracle/ctl_%U’ current controlfile;
release channel dup1;
release channel dup2;
}

Thank you
Osama mustafa 

Enabling and Disabling Database Options

All New From Oracle ….
Amazing Tools , If you install Oracle Database After that you remember that you should enable/Disable some Feature Like Oracle Security ad you Forget Script That Located in RDBMS/admin the What Reinstall Again

In ORACLE 11gR2 you Can do this Easily Just Follow The Below Steps :

The chopt tool is a command-line utility that is located in the ORACLE_HOME\bin directory. The syntax for chopt is as follows:

chopt [ enable | disable] db_option
 

The possible values for db_option described in the following table.

Value Description
dm Oracle Data Mining RDBMS Files
dv Oracle Database Vault
lbac Oracle Label Security
olap Oracle OLAP
partitioning Oracle Partitioning
rat Oracle Real Application Testing
ode_net_2 Oracle Database Extensions for .NET 2.0

 Example :

To enable the Oracle Label Security option in your Oracle binary files

1-Shut down the database with srvctl or SQL*Plus:  

SQL>Shutdown immediate (single node)
 
srvctl stop database -d ORCL

2-Run the following commands: 

cd %ORACLE_HOME%/bin
chopt enable lbac

3-Start Database :

srvctl start database -d ORCL
OR 
SQL>Startup  (Single Node)

In linux the “chopt” statement will show the following output

[oracle@localhost ~]$ chopt
 
usage:
 
chopt [enable|disable] {option}
 
options:
dm = Oracle Data Mining RDBMS Files
dv = Oracle Database Vault option
lbac = Oracle Label Security
olap = Oracle OLAP
partitioning = Oracle Partitioning
rat = Oracle Real Application Testing
 
e.g. chopt enable rat

 Thank you
Osama Mustafa

Clean Concurrent Manager Tables

The Below Script "CMCLEAN.SQL For Cleaning ConCurrent Manager In Oracle EBS VERSION :  -10.7
-11.0
-11.5
-12.1.3
REM
REM FILENAME
REM cmclean.sql
REM DESCRIPTION
REM Clean out the concurrent manager tables
REM NOTES
REM Usage: sqlplus @cmclean
REM
REM
REM $Id: cmclean.sql,v 1.4 2001/04/07 15:55:07 pferguso Exp $
REM
REM
REM +======================================================================+

set verify off;
set head off;
set timing off
set pagesize 1000

column manager format a20 heading 'Manager short name'
column pid heading 'Process id'
column pscode format a12 heading 'Status code'
column ccode format a12 heading 'Control code'
column request heading 'Request ID'
column pcode format a6 heading 'Phase'
column scode format a6 heading 'Status'

WHENEVER SQLERROR EXIT ROLLBACK;

DOCUMENT

WARNING : Do not run this script without explicit instructions
from Oracle Support

*** Make sure that the managers are shut down ***
*** before running this script ***

*** If the concurrent managers are NOT shut down, ***
*** exit this script now !! ***

#

accept answer prompt 'If you wish to continue type the word ''dual'': '

set feed off
select null from &answer;
set feed on

REM Update process status codes to TERMINATED

prompt
prompt ------------------------------------------------------------------------

prompt -- Updating invalid process status codes in FND_CONCURRENT_PROCESSES
set feedback off
set head on
break on manager

SELECT concurrent_queue_name manager,
concurrent_process_id pid,
process_status_code pscode
FROM fnd_concurrent_queues fcq, fnd_concurrent_processes fcp
WHERE process_status_code not in ('K', 'S')
AND fcq.concurrent_queue_id = fcp.concurrent_queue_id
AND fcq.application_id = fcp.queue_application_id;

set head off
set feedback on
UPDATE fnd_concurrent_processes
SET process_status_code = 'K'
WHERE process_status_code not in ('K', 'S');

REM Set all managers to 0 processes

prompt
prompt ------------------------------------------------------------------------

prompt -- Updating running processes in FND_CONCURRENT_QUEUES
prompt -- Setting running_processes = 0 and max_processes = 0 for all managers

UPDATE fnd_concurrent_queues
SET running_processes = 0, max_processes = 0;

REM Reset control codes

prompt
prompt ------------------------------------------------------------------------

prompt -- Updating invalid control_codes in FND_CONCURRENT_QUEUES
set feedback off
set head on
SELECT concurrent_queue_name manager,
control_code ccode
FROM fnd_concurrent_queues
WHERE control_code not in ('E', 'R', 'X')
AND control_code IS NOT NULL;

set feedback on
set head off
UPDATE fnd_concurrent_queues
SET control_code = NULL
WHERE control_code not in ('E', 'R', 'X')
AND control_code IS NOT NULL;

REM Also null out target_node for all managers
UPDATE fnd_concurrent_queues
SET target_node = null;

REM Set all 'Terminating' requests to Completed/Error
REM Also set Running requests to completed, since the managers are down

prompt
prompt ------------------------------------------------------------------------

prompt -- Updating any Running or Terminating requests to Completed/Error
set feedback off
set head on
SELECT request_id request,
phase_code pcode,
status_code scode
FROM fnd_concurrent_requests
WHERE status_code = 'T' OR phase_code = 'R'
ORDER BY request_id;

set feedback on
set head off
UPDATE fnd_concurrent_requests
SET phase_code = 'C', status_code = 'E'
WHERE status_code ='T' OR phase_code = 'R';

REM Set all Runalone flags to 'N'
REM This has to be done differently for Release 10

prompt
prompt ------------------------------------------------------------------------

prompt -- Updating any Runalone flags to 'N'
prompt
set serveroutput on
set feedback off
declare
c pls_integer := dbms_sql.open_cursor;
upd_rows pls_integer;
vers varchar2(50);
tbl varchar2(50);
col varchar2(50);
statement varchar2(255);
begin

select substr(release_name, 1, 2)
into vers
from fnd_product_groups;

if vers >= 11 then
tbl := 'fnd_conflicts_domain';
col := 'runalone_flag';
else
tbl := 'fnd_concurrent_conflict_sets';
col := 'run_alone_flag';
end if;

statement := 'update ' || tbl || ' set ' || col || '=''N'' where ' || col || ' = ''Y''';
dbms_sql.parse(c, statement, dbms_sql.native);
upd_rows := dbms_sql.execute(c);
dbms_sql.close_cursor(c);
dbms_output.put_line('Updated ' || upd_rows || ' rows of ' || col || ' in ' || tbl || ' to ''N''');
end;
/

prompt

prompt ------------------------------------------------------------------------

prompt Updates complete.
prompt Type commit now to commit these updates, or rollback to cancel.
prompt ------------------------------------------------------------------------

prompt

set feedback on

REM <= Last REM statment -----------------------------------------------------

Disclaimer
EXCEPT WHERE EXPRESSLY PROVIDED OTHERWISE, THE INFORMATION, SOFTWARE,
PROVIDED ON AN "AS IS" AND "AS AVAILABLE" BASIS. ORACLE EXPRESSLY DISCLAIMS
ALL WARRANTIES OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE AND NON-INFRINGEMENT. ORACLE MAKES NO WARRANTY THAT: (A) THE RESULTS
THAT MAY BE OBTAINED FROM THE USE OF THE SOFTWARE WILL BE ACCURATE OR
RELIABLE; OR (B) THE INFORMATION, OR OTHER MATERIAL OBTAINED WILL MEET YOUR
EXPECTATIONS. ANY CONTENT, MATERIALS, INFORMATION OR SOFTWARE DOWNLOADED OR
OTHERWISE OBTAINED IS DONE AT YOUR OWN DISCRETION AND RISK. ORACLE SHALL HAVE
NO RESPONSIBILITY FOR ANY DAMAGE TO YOUR COMPUTER SYSTEM OR LOSS OF DATA THAT
RESULTS FROM THE DOWNLOAD OF ANY CONTENT, MATERIALS, INFORMATION OR SOFTWARE.

ORACLE RESERVES THE RIGHT TO MAKE CHANGES OR UPDATES TO THE SOFTWARE AT ANY
TIME WITHOUT NOTICE.
Limitation of Liability
IN NO EVENT SHALL ORACLE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL OR CONSEQUENTIAL DAMAGES, OR DAMAGES FOR LOSS OF PROFITS, REVENUE,
DATA OR USE, INCURRED BY YOU OR ANY THIRD PARTY, WHETHER IN AN ACTION IN
CONTRACT OR TORT, ARISING FROM YOUR ACCESS TO, OR USE OF, THE SOFTWARE.

SOME JURISDICTIONS DO NOT ALLOW THE LIMITATION OR EXCLUSION OF LIABILITY.
ACCORDINGLY, SOME OF THE ABOVE LIMITATIONS MAY NOT APPLY TO YOU.

Oracle Document ID : [ID 134007.1]
Thank you
Osama Mustafa

PRVF-5436 PRVF-9652 Cluster Time Synchronization Services check failed

$GRID_HOME/bin/cluvfy comp clocksync
Cause of the Problem
The problem happened because the time service (such as NTP) is not running or doesn’t have slew option set.

Solution of the Problem
The problem happened because time service NTP is not running or doesn’t have slew option set.
So, ensure that NTP service is up and running.
Based on the operating system solutions are given below.

1) Linux:

To verify service as root user issue,
# /sbin/service ntpd status
ntpd (pid 4423) is running…

Check process is running or not by.
# ps -ef|grep ntp
ntp 4209 1 0 Mar10 ? 00:00:00 ntpd -u ntp:ntp -p /var/run/ntpd.pid -x

# grep OPTIONS /etc/sysconfig/ntpd
OPTIONS=”-u ntp:ntp -p /var/run/ntpd.pid -x”

If NTP service is not started then to start the service issue,
To start the service issue,

# /sbin/service ntpd start

2) Solaris:

To verify the service issue,

# /usr/bin/svcs ntp
STATE STIME FMRI
online 3:29:11 svc:/network/ntp:default

# ps -ef|grep ntp
root 21223 1 0 Mar 10 ? 0:21 /usr/lib/inet/xntpd

# grep slewalways /etc/inet/ntp.conf
slewalways yes

To start the NTP service issue,

# /usr/sbin/svcadm enable ntp

3) HP-UX:

To verify the service issue,

# ps -ef|grep ntp
root 6022 1 0 14:23:42 ? 0:01 /usr/sbin/xntpd -x

# grep XNTPD_ARGS /etc/rc.config.d/netdaemons
export XNTPD_ARGS=”-x”

To start the service issue,
# /sbin/init.d/xntpd start

4) AIX:

To verify the service issue,

# /usr/bin/lssrc -ls xntpd
xntpd tcpip 368754 active

# ps -ef|grep ntp
root 786614 151686 0 08:02:32 – 0:00 /usr/sbin/xntpd -x

# grep xntpd /etc/rc.tcpip
start /usr/sbin/xntpd “$src_running” -a “-x”

To start the service issue,

# /usr/bin/startsrc -s xntpd -a “-x”

Thank you
Osama mustafa

Article About Data Recovery Method

1-  If you lost all data files

SQL> startup mount;
RMAN> restore database;
RMAN> recover database;
SQL> alter database open;

2- If you lost a tablespace

SQL> alter tablespace users offline;
RMAN> restore tablespace users;
RMAN> recover tablespace users;
SQL> alter tablespace users online;

 if you can not offline tablespace;

$ sqlplus “/ as sysdba”
SQL> shutdown abort;
SQL> startup mount;
$ rman target / catalog_user/catalog_user_password@catalogdb
RMAN> restore tablespace users;
RMAN> recover tablespace users;
SQL> alter database open;

3- if you lost a datafile

SQL> alter database datafile '/oracle/oradata/users.dbf' offline;
RMAN> restore datafile '/oracle/oradata/users.dbf'
RMAN> recover datafile '/oracle/oradata/users.dbf'
SQL> alter database datafile '/oracle/oradata/users.dbf' online;
 

if you cannot offline datafile;

$ sqlplus “/ as sysdba”
SQL> shutdown abort;
SQL> startup mount;
$ rman target / catalog_user/catalog_user_password@catalogdb
RMAN> restore datafile '/oracle/oradata/users.dbf';
RMAN> recover datafile '/oracle/oradata/users.dbf';
SQL> alter database open;
 

4-  if you lost your controlfiles

$ sqlplus “/ as sysdba”
SQL> shutdown abort;
SQL> startup nomount;
$ rman target / catalog_user/catalog_user_password@catalogdb
RMAN> set dbid = 3970640872;
RMAN> restore controlfile;
SQL> alter database mount;
SQL> alter database open;

you will receive an error ORA-01589 when you open database
ORA-01589: must use RESETLOGS or NORESETLOGS option for database open

SQL> shutdown abort;
SQL> startup mount;
$ rman target / catalog_user/catalog_user_password@catalogdb
RMAN> recover database;
SQL> alter database open resetlogs;
RMAN> reset database;

if you open database with resetlogs, SCN number will be zero. In this situation
all previous backups will be invalid. You must full backup.

5- May be a special situation. You need to incomplete recovery

A. Time-Based incomplete recovery

$ sqlplus "/ as sysdba"
SQL> shutdown abort;
SQL> startup mount;
$ rman target / catalog_user/catalog_user_password@catalogdb
RMAN> restore database until time "to_date('06/05/11 12:0:00','DD/MM/YY HH24:MI:SS')";
RMAN> recover database until time "to_date('06/05/11 12:0:00','DD/MM/YY HH24:MI:SS')";
SQL> alter database open resetlogs;
 
 
B. SCN-Based incomplete recovery
$ sqlplus "/ as sysdba"
SQL> shutdown abort;
SQL> startup mount;
$ rman target / catalog_user/catalog_user_password@catalogdb
RMAN> restore database until scn 1000;
RMAN> recover database until scn 1000;
SQL> alter database open resetlogs;
C. Archive log sequence based incomplete recovery

$ sqlplus "/ as sysdba"
SQL> shutdown abort;
SQL> startup mount;
$ rman target / catalog_user/catalog_user_password@catalogdb
RMAN> restore database until sequence 9923;
RMAN> recover database until sequence 9923;
SQL> alter database open resetlogs;

6-  if you need some archive logs in your backup
$ rman target / catalog_user/catalog_user_password@catalogdb
RMAN> restore ARCHIVELOG FROM TIME 'SYSDATE-1' UNTIL TIME 'SYSDATE';
 

OR

RMAN> restore ARCHIVELOG FROM TIME "to_date('07/11/05 00:00:01','MM/DD/YY HH24:MI:SS')
UNTIL TIME 'SYSDATE';
 
7- if your data block is corrupted you will receive an error below.

Error:
ORA-01578: ORACLE data block corrupted (file # 8, block # 13)
ORA-01110: data file 8: ‘/oracle/oradata/users.dbf’

for recover data block;

$ rman target / catalog_user/catalog_user_password@catalogdb
RMAN>blockrecover datafile 8 block 13;
 

For Block-Level Media Recovery – Concept & Example (Doc ID 144911.1)

To recover, we can give a specific backup set;

# recovery from backupset
RMAN> BLOCKRECOVER DATAFILE 8 BLOCK 13 DATAFILE 2 BLOCK 19 FROM BACKUPSET;
# recovery from image copy
RMAN> BLOCKRECOVER DATAFILE 8 BLOCK 13 DATAFILE 2 BLOCK 19
FROM DATAFILECOPY;
# recovery from backupset which have "FULL" tag
RMAN> BLOCKRECOVER DATAFILE 8 BLOCK 13 DATAFILE 2 BLOCK 199
FROM TAG = FULL;

During backup or “Validate Backup” command, RMAN finds corrupted blocks and writes to V$DATABASE_BLOCK_CORRUPTION view. When the RMAN recover the corrupt block then automatically updates this view. List of all the corruption of the past, can be viewed over V$BACKUP_CORRUPTION and V$COPY_CORRUPTION views.  If you run the following command,  RMAN will recover all the corrupted blocks in view V$DATABASE_BLOCK_CORRUPTION.

  RMAN>BLOCKRECOVER CORRUPTION LIST RESTORE UNTIL TIME ‘SYSDATE-10’;

8- if you have a image copy backup and your datafile number 2 has problems then you
can switch datafile number2 to image copy.

RMAN>sql ‘alter database datafile 2 offline’;
RMAN>switch datafile 2 to copy;
RMAN>recover datafile 2;
RMAN>sql ‘alter database datafile 2 online’;

Orginial Article
 Thank You
 Osama Mustafa

ORA-01110 When trying to Open Database

ALTER DATABASE OPEN
*
ERROR at line 1:
ORA-01194: file 1 needs more recovery to be consistent
ORA-01110: data file 5: ‘ /u01/test/users02.dbf’

This Error Maybe Appear On Different Database Files Because DBF Not Exists .

Solution
1-Restore From Rman if its Not Found .

Or

SQL> select file#,name, status from v$datafile where file#=5;
FILE# NAME STATUS
———- ————————————————- ———–
5 /u01/test/users02.dbf ONLINE

SQL>
SQL> alter database datafile ‘/u01/test/users02.dbf’ offline drop;
Database altered.

SQL> alter database open;
Database altered.
SQL>

Thank you
Osama Mustafa

Using FAN callouts (relocate a service back)

In Oracle 10g RAC, every time a node/instance/service goes up/down, that event can be trapped and used to make user defined callouts. So every time a state change occurs, a FAN event is posted to ONS immediately. When a node receives an event through ONS, it will asynchronously execute all executables in the server side callouts directory.

There could be lot of applications to using this feature of callouts. For example, when an instance goes down, we all know that services running on that instance are relocated to other available instances. But when that instance comes back up, those relocated services need to be manually put back to their preferred instance. By using FAN callouts, we can automate this task.

1. Go to $ORA_CRS_HOME/racg and create usrco directory on all the nodes. So the server side callout directory would look something like this:
/oracle/product/crs/racg/usrco

2. Place your callout scripts under this dir. This will be called on every state change. You could use any executable like shell script or a perl script.
I have tested this on a 2-node Oracle RAC database version 10.2.0.2 on x64 RHEL4U7.
Save the below sample script as /oracle/product/crs/racg/usrco/instup_relocate.pl
This one traps the INSTANCE UP event and calls another script to relocate the services

#!/usr/local/bin/perl
# instup_relocate.pl
# This is a callout program that will, on an INSTANCE UP event relocate services back
# This script is supposed to reside in $CRS_HOME/racg/usrco as an executable on all the nodes. “usrco” directory needs to be created for callouts.
use strict;

# Define Oracle and Crs Home
my $CRS_HOME=”/oracle/product/crs”;
my $ORACLE_HOME=”/oracle/product/10.2″;

# TMP refers to the log location only
my $TMP = “/tmp”;

# Enable logging
my $LOGFILE = “$TMP/SRV_co.log”;

# Define variables that would be captured by callout event
my $instance;
my $database;
my $host;
my $service;
my $reason;
my $card;
my $status;
my ($key,$value) = “”;

# Open logfile
local *LOG_FILE;
open (LOG_FILE, “>>$LOGFILE”) or do
{
   print “Cannot open $LOGFILE\n”;
   exit(1);
};

# Uncomment these lines if only interested in specific events

if ($ARGV[0] ne “INSTANCE”) { exit(0); };
#if ($ARGV[0] ne “SERVICEMEMBER”) { exit(0); };
#if ($ARGV[0] ne “SERVICE”) { exit(0); };
#if ($ARGV[0] ne “NODE”) { exit(0); };

for (my $i=0; $i <= $#ARGV; $i++)
{
    print LOG_FILE “For Loop $i $ARGV[$i]\n”;
    if ($ARGV[$i] =~ m#=#)
    {
        ($key,$value) = (split /=/, $ARGV[$i]);
        #print “Key = $key  Value = $value\n”;
        if ($key eq “service”)
        {
            $service = $value;
        } elsif ($key eq “instance”)
        {
            $instance = $value;
            $ENV{ORACLE_SID} = $value;
        } elsif ($key eq “database”)
        {
            $database = $value;
        } elsif ($key eq “host”)
        {
            $host = $value;
        } elsif ($key eq “card”)
        {
            $card = $value;
        } elsif ($key eq “status”)
        {
            $status = $value;
        } elsif ($key eq “reason”)
        {
            $reason = $value;
        }
    }
}
print LOG_FILE “Arg=$ARGV[0]\n”;
print LOG_FILE “DB=$database\n”;
print LOG_FILE “Host = $host DB = $database Inst = $instance Service = $service Status = $status Reason = $reason\n”;
# Call relocate service after instance up event is trapped.
#
if ($status eq “up” && $ARGV[0] eq “INSTANCE”)
{
    print LOG_FILE “Instance up found. Calling relocate services for $database\n”;
    # Call Service relocate
    sleep(30);
    system(“/usr/local/bin/perl /oracle/scripts/relocate_service.pl $database”);
    print LOG_FILE “Success!!!\n”;
}
else
{
    print LOG_FILE “Failed: Instance up check failed\n”;
}


Save the below sample script as /oracle/scripts/relocate_service.pl

#!/usr/local/bin/perl
# relocate_service.pl
# This script does a comparison between srvctl config and srvctl status and accordingly relocates the service back based on the config.

my $ret;
my $host1;
# Get dbname passed as an argument from command line
my $dbname;
$argc=scalar @ARGV;
$dbname = $ARGV[0];
chop($host1= `/bin/hostname`);
$ret = system(“srvctl config service -d $dbname|sed ‘s/PREF: //’|sed ‘s/AVAIL:.*\$//’ >/tmp/config_service.log”);
$ret = system(“srvctl status service -d $dbname | sed ‘s/\,\ /\,/g’|cut -f2,7 -d ‘ ‘ | tr -s ‘,’ ‘ ‘>/tmp/status_service.log”);

open(READ_CONFIG, “/tmp/config_service.log”);
open(READ_STATUS, “/tmp/status_service.log”);

my ($rl_from, $rl_to, $no_relocs,$conf_inst_i,$status_inst_i);

# Due to HTML issues, please replace “<" by "” by “>”
while ($config_line = )
{
   chomp($config_line);
   chop($config_line);

# Due to HTML issues, please replace “<" by "” by “>”
   $status_line = ;
   chomp($status_line);
   if ($config_line eq  $status_line)
   {
      print  “$config_line OK\n”;
   }
   else
   {
     # Array to store relocate to/from instance names for each service
     my @relocate_from;
     my @relocate_to;

     ($conf_serv,@conf_inst) = split / /,$config_line;
     ($status_serv,@status_inst) = split / /,$status_line;

     # Relocate to which node
     my $i=0;
     my $found;

     for (@conf_inst)
     {
         $conf_inst_i = $_;
         $found=0;

         for (@status_inst)
         {
           $status_inst_j = $_;
           if ($conf_inst_i eq $status_inst_j) { $found=1; last;}

         }

         $relocate_to[$i++] = $conf_inst_i if (! $found);
     }

     # Relocate from which node
     my $j=0;
     for (@status_inst)
     {
         $status_inst_i = $_;
         $found=0;
         for (@conf_inst)
         {
           $conf_inst_j = $_;
           if ($status_inst_i eq $conf_inst_j) { $found=1; last;}
         }

         $relocate_from[$j++] = $status_inst_i if (! $found);
     }
     $rl_from= scalar @relocate_from;
     $rl_to=scalar @relocate_to;

     # How many relocations need to be done
     $no_relocs=$rl_from;
     if ($rl_from > $rl_to)
     {
        $no_relocs=$rl_to;
     }

     # Relocate for all possible instances
     if ($no_relocs > 0)
     {
        for ($i=0; $i<$no_relocs; $i++)
        {
             $relocate_cmd = “srvctl relocate service -d $dbname -s \”$conf_serv\” -i $relocate_from[$i] -t $relocate_to[$i]”;
             $ret = `$relocate_cmd 2>&1`;
             print  “RELOCATED: $relocate_cmd\n”;
        }
     }

     # Start services on the remaining preferred instanecs
     if ($rl_to > $rl_from)
     {
         for ($i=$no_relocs; $i<$rl_to; $i++)
         {
             $start_serv_cmd=”srvctl start service -d $dbname -s \”$conf_serv\” -i $relocate_to[$i]”;
             $ret = system(“$start_serv_cmd”);
             print  “STARTED: $start_serv_cmd\n”;
         }
      }
   }
}#End of while

if ($no_relocs > 0)
{
  $ret = system(“srvctl status service -d $dbname | sed ‘s/\,\ /\,/g’|cut -f2,7 -d ‘ ‘ | tr -s ‘,’ ‘ ‘>/tmp/status_service_new.log”);
}

Here are the test results. We can see that after an instance is brought back up, the service srv_inst1 is relocated back to it’s preferred instance by the callout script without any manual intervention.

% srvctl config service -d testdb
srv_inst1 PREF: testdb1 AVAIL: testdb2
srv_inst2 PREF: testdb2 AVAIL: testdb1

% srvctl status service -d testdb
Service srv_inst1 is running on instance(s) testdb1Service srv_inst2 is running on instance(s) testdb2

% srvctl stop instance -d testdb -i testdb1

% srvctl status service -d testdb
Service srv_inst1 is running on instance(s) testdb2Service srv_inst2 is running on instance(s) testdb2

% srvctl start instance -d testdb -i testdb1

% srvctl status service -d testdb
Service srv_inst1 is running on instance(s) testdb1Service srv_inst2 is running on instance(s) testdb2

I would thank ritzy .

Thank you
Osama mustafa