#!/usr/local/bin/perl # # $Header: rac_srvctl.pl 22-dec-2005.12:21:48 ysun Exp $ # # rac_srvctl.pl # # Copyright (c) 2002, 2005, Oracle. All rights reserved. # # NAME # rac_srvctl.pl - # # DESCRIPTION # # # NOTES # # # MODIFIED (MM/DD/YY) # ysun 12/22/05 - support 10.1OMS and 10.2agent # vkapur 08/24/05 - fix bug 4572452 # vkapur 11/03/04 - show success msg for job # vkapur 10/25/04 - fixes for job support # vkapur 10/13/04 - support calling startup_rac, shutdown_rac for # start/shut jobs # xuliu 10/07/04 - xuliu_mov_rac_f # vkapur 09/17/04 - R2 features: add,modify,remove # vkapur 03/05/04 - NT fix 3486880 # xuliu 03/01/04 - fix 3469118 # vkapur 01/22/04 - NT fix: add doAll check # vkapur 09/03/03 - NT switch for password piping # vkapur 07/28/03 - error report for startup/shutdown # ysun 07/08/03 - provide absolute path # ysun 07/01/03 - pipe password # vkapur 06/17/03 - mod version check # vkapur 06/10/03 - add get_db_status, get_db_config # vkapur 06/06/03 - improve error handling # vkapur 04/17/03 - fix relocate string # vkapur 04/07/03 - correct version check, more services functions # vkapur 03/20/03 - add services # ysun 08/20/02 - handle connection string # ysun 07/30/02 - ysun_rac_srvctl_support # ysun 07/30/02 - Creation # use Cwd; require "$ENV{EMDROOT}/sysman/admin/scripts/db/db_common.pl"; require "$ENV{EMDROOT}/sysman/admin/scripts/db/dbstate.pl"; require "$ENV{EMDROOT}/sysman/admin/scripts/semd_common.pl"; $statexe = '$ENV{ORACLE_HOME}/bin/srvctl'; #get_rac_version(); #get_rac_status($dbName); # dbName #startup_rac($dbName, $option, $connStr, $sidList); #get_rac_status($dbName); # dbName #shutdown_rac($dbName, $option, $connStr, $sidList); sub get_exec_env { # chomp ($version = `$ENV{ORACLE_HOME}/bin/srvctl`) # chomp ($version = `$ENV{ORACLE_HOME}/bin/lsnodes`) chomp ($version = `echo $ENV{ORACLE_HOME}`) or die 'Failed to echo'; print $version."\n"; chomp ($version = `echo $ENV{JAVA_HOME}`) or die 'Failed to echo'; print $version."\n"; } sub get_srvctl_version { $cmd = "$ENV{ORACLE_HOME}/bin/srvctl config -V"; chomp ($result = `$cmd`); if ($? != 0) { ## print 'Failed to run the srvctl command in get_rac_version'; print "$result\n"; return ($? >> 8); } ## chomp ($version = `$ENV{ORACLE_HOME}/bin/srvctl config -V`) ## or die "Failed to run the srvctl command in get_rac_version, ORACLE_HOME = $oh"; # for services, require at least 10i # for startup/shutdown, require at least 9.2 version if ($result =~ /10/) { $version = '10'; print $version; return; } if ( $result =~ /9.2/) { $version='92'; } else { $version='90'; } print "$version"; return has_ec($result); } ### to be deprecated: sub get_rac_version { chomp ($version = `$ENV{ORACLE_HOME}/bin/srvctl config -V`) or die "Failed to run the srvctl command in get_rac_version"; # for services, require at least 10i # for startup/shutdown, require at least 9.2 version if ($version =~ /10/) { $serv_version = '10'; $version = '92'; # for start/shut, 9.2 and 10 are treated same return; } if ( $version =~ /9.2/) { $serv_version = '92'; $version='92'; } else { $serv_version = '90'; $version='90'; } } sub get_rac_status { my $dbName = $_[0]; if ( $version =='92' ) { $cmd = "$ENV{ORACLE_HOME}/bin/srvctl config database -d ".$dbName; chomp ($result = `$cmd`) or die 'Failed to get db config'; print "\{".$result."\}\n"; $cmd = "$ENV{ORACLE_HOME}/bin/srvctl status database -S 1 -d ".$dbName; chomp ($result = `$cmd`) or die 'Failed to run the srvctl command in get_rac_status'; } if ( $version =='90' ) { } print $result."\n"; } sub get_db_status { my $dbName = $_[0]; if ( $version =='92' || $version=='10') { $cmd = "$ENV{ORACLE_HOME}/bin/srvctl status database -S 1 -d ".$dbName; chomp ($result = `$cmd`); if ($? != 0) { ## print 'Failed to run the srvctl command in get_db_status'; print "$result\n"; return ($? >> 8); } } if ( $version =='90' ) { } print $result."\n"; return has_ec($result); } sub get_db_config { my $dbName = $_[0]; if ( $version =='92' || $version=='10') { $cmd = "$ENV{ORACLE_HOME}/bin/srvctl config database -d ".$dbName; chomp ($result = `$cmd`); if ($? != 0) { ## die 'Failed to run the srvctl command in get_db_config'; print "$result\n"; return ($? >> 8); } } if ( $version =='90' ) { } print $result."\n"; return has_ec($result); } # # startup_rac: wrapper around dbstate.pl # Starts RAC database on ALL instances. # Used for startup/shutdown job support in 10.2 # # dbName: RAC database name # startupOption: {open, mount, nomount} [force] [restrict] [read only] # connStr, instanceList, doAll are ignored (kept for backward compatibility with 10.1 agent) # oracleHome: ORACLE_HOME for database # localSID: local instance name for host where this fcn is invoked # sub startup_rac { my ($dbName, $startupOption, $connStr, $instanceList, $doAll, $oracleHome, $localSID) = @_; if ( !$oracleHome ) { $oracleHome=$ENV{ORACLE_HOME}; } # connStr, instanceList are ignored (kept for backward compatibility with 10.1 agent) my $dbUsername = ""; my $dbPassword = ""; my $dbRole = "SYSDBA"; my $targetType = "rac_database"; my $tns = ""; $instanceList = ""; my $isDB10i = 1; my $sqlRunState = ""; my $restoreDBState = 0; my $initState = ""; my $bounceAfterPostSQL = 0; my @postStartupSql; # call to dbstate.pl $exitCode = startup_db($targetType, $oracleHome, $localSID, $dbName, $dbUsername, $dbPassword, $dbRole, $tns, $instanceList, $isDB10i, $startupOption, $sqlRunState, $restoreDBState, $initState, $bounceAfterPostSQL, @postStartupSql); if ($exitCode == 0) { print "Startup successful on all nodes.\n"; } return $exitCode; } # # shutdown_rac: wrapper around dbstate.pl # Stops RAC database on ALL instances. # Used for startup/shutdown job support in 10.2 # # dbName: RAC database name # shutdownOption: {immediate, transactional, normal, abort} # connStr, instanceList are ignored (kept for backward compatibility with 10.1 agent) # oracleHome: ORACLE_HOME for database # localSID: local instance name for host where this fcn is invoked # sub shutdown_rac { # my ($oracleHome, $dbName, $dbUsername, $dbPassword, $dbRole, $localSID, $shutdownOption) = @_; my ($dbName, $shutdownOption, $connStr, $instanceList, $doAll, $oracleHome, $localSID) = @_; if ( !$oracleHome ) { $oracleHome=$ENV{ORACLE_HOME}; } # connStr, instanceList are ignored (kept for backward compatibility with 10.1 agent) my $dbUsername = ""; my $dbPassword = ""; my $dbRole = "SYSDBA"; my $targetType = "rac_database"; my $tns = ""; $instanceList = ""; my $isDB10i = 1; my $restoreDBState = 0; my $initState = ""; my $bounceAfterPostSQL = 0; my @preShutdownSql; # call to dbstate.pl $exitCode = shutdown_db($targetType, $oracleHome, $localSID, $dbName, $dbUsername, $dbPassword, $dbRole, $tns, $instanceList, $isDB10i, $shutdownOption, $restoreDBState, $initState, @preShutdownSql); if ($exitCode == 0) { print "Shutdown successful on all nodes.\n"; } return $exitCode; } ######################### Services ############################# # note: Rac Services functionality is only for 10i db # Usage: get_service_status(dbName, [sv1...svK]) # Calls: srvctl status service -f -S 1 -d dbName -s sv1,sv2...svK sub get_service_status { my ($dbName, $sv_names) = @_; # if ( $serv_version =='10' ) if ($version=='10') { $cmd = "$ENV{ORACLE_HOME}/bin/srvctl status service -f -S 1 -d ".$dbName." -s ".$sv_names; print "Srvctl command: $cmd\n"; ## if (system "$cmd") { chomp ($result = `$cmd`); if ($? != 0) { ## print "Failed to run the srvctl command in get_service_status\n"; print "$result\n"; return ($? >> 8); } } print $result."\n"; return has_ec($result); } # Usage: get_service_config(dbName, [sv1...svK]) # Calls: srvctl config service -S 1 -d dbName -s [sv1,...,svK] sub get_service_config { my ($dbName, $sv_names) = @_; # if ( $serv_version =='10' ) if ($version=='10') { if ($sv_names) { $cmd = "$ENV{ORACLE_HOME}/bin/srvctl config service -S 1 -d $dbName -s $sv_names"; } else { $cmd = "$ENV{ORACLE_HOME}/bin/srvctl config service -S 1 -d ".$dbName; } print "Srvctl command: $cmd\n"; ## if (system "$cmd") { chomp ($result = `$cmd`); if ($? != 0) { print "$result\n"; ## print "Failed to run the srvctl command in get_service_config\n"; return ($? >> 8); } } print $result."\n"; return has_ec($result); } # Usage: do_service_add(dbName, servName, pref_list, avail_list, taf_policy) # Calls: srvctl add service -d dbName -s servName -r -a -P sub do_service_add { my ($dbName, $servName, $pref_list, $avail_list, $taf_policy) = @_; if ($version == '10') { $cmd = "$ENV{ORACLE_HOME}/bin/srvctl add service -d $dbName -s $servName -r $pref_list"; if ($avail_list) { $cmd = $cmd." -a $avail_list"; } $cmd = $cmd." -P $taf_policy"; print "Srvctl command: $cmd\n"; chomp ($result = `$cmd`); if ($? != 0) { print "$result\n"; return ($? >> 8); } } print $result."\n"; return has_ec($result); } # Usage: do_service_modify(dbName, servName, pref_list, avail_list, taf_policy) # Calls: srvctl modify service -d dbName -s servName -n -i -a -P sub do_service_modify { my ($dbName, $servName, $pref_list, $avail_list, $taf_policy) = @_; if ($version == '10') { $cmd = "$ENV{ORACLE_HOME}/bin/srvctl modify service -d $dbName -s $servName -n -i $pref_list"; if ($avail_list) { $cmd = $cmd." -a $avail_list"; } # $cmd = $cmd." -P $taf_policy"; print "Srvctl command: $cmd\n"; chomp ($result = `$cmd`); if ($? != 0) { print "$result\n"; return ($? >> 8); } # modify taf policy: $cmd = "$ENV{ORACLE_HOME}/bin/srvctl modify service -d $dbName -s $servName -P $taf_policy"; print "Srvctl command: $cmd\n"; chomp ($taf_result = `$cmd`); if ($? != 0) { print "$taf_result\n"; return ($? >> 8); } } print "$result \n $taf_result \n"; return has_ec($result); } # Usage: do_service_remove(dbName, servName, doDisconnect) # Calls: srvctl remove service -d dbName -s servName [-f] sub do_service_remove { my ($dbName, $servName, $doDisconnect) = @_; if ($version == '10') { $cmd = "$ENV{ORACLE_HOME}/bin/srvctl remove service -d $dbName -s $servName -f"; print "Srvctl command: $cmd\n"; chomp ($result = `$cmd`); if ($? != 0) { print "$result\n"; return ($? >> 8); } } return has_ec($result); } # Usage: do_service_enable(dbName, [sv1...svK], inst_name) # Calls: srvctl enable service -d dbName -s [sv1,...,svK] -i inst_name # Requires: inst_name, if specified, must be registered to all [sv1...svk] sub do_service_enable { my ($dbName, $sv_names, $inst_name) = @_; # if ( $serv_version =='10' ) if ($version=='10') { $cmd = "$ENV{ORACLE_HOME}/bin/srvctl enable service -d ".$dbName." -s $sv_names"; # add instance (if it was passed in): if ($inst_name) { $cmd = $cmd." -i $inst_name"; } print $cmd."\n"; ### if (system "$cmd") { chomp ($result = `$cmd`); if ($? != 0) { ## print "Failed to run the srvctl command in do_service_start\n"; print "$result\n"; return ($? >> 8); } } print $result."\n"; return has_ec($result); } # Usage: do_service_disable(dbName, [sv1...svK], inst_name) # Calls: srvctl disable service -d dbName -s [sv1,...,svK] -i inst_name # Requires: inst_name, if specified, must be registered to all [sv1...svk] sub do_service_disable { my ($dbName, $sv_names, $inst_name) = @_; # if ( $serv_version =='10' ) if ($version=='10') { $cmd = "$ENV{ORACLE_HOME}/bin/srvctl disable service -d ".$dbName." -s $sv_names"; # add instance (if it was passed in): if ($inst_name) { $cmd = $cmd." -i $inst_name"; } print "Srvctl command: $cmd\n"; ## if (system "$cmd") { chomp ($result = `$cmd`); if ($? != 0) { ## print 'Failed to run the srvctl command in do_service_disable'; print "$result\n"; return ($? >> 8); } } print $result."\n"; return has_ec($result); } # Usage: do_service_start(dbName, [sv1...svK], inst_name) # Calls: srvctl start service -d dbName -s [sv1,...,svK] -i inst_name # Requires: inst_name, if specified, must be registered to all [sv1...svk] sub do_service_start { my ($dbName, $sv_names, $inst_name) = @_; # if ( $serv_version =='10' ) if ($version=='10') { $cmd = "$ENV{ORACLE_HOME}/bin/srvctl start service -d ".$dbName." -s $sv_names"; # add instance (if it was passed in): if ($inst_name) { $cmd = $cmd." -i $inst_name"; } print "Srvctl command: $cmd\n"; # if ($ec = system "$cmd") { chomp ($result = `$cmd`); if ($? != 0) { ## print 'Failed to run the srvctl command in do_service_start'; print "$result\n"; return ($? >> 8); } } print $result."\n"; # print "result = $result\n"; return has_ec($result); } # Usage: do_service_stop(dbName, [sv1...svK], inst_name, [doDisconnect]) # Calls: srvctl stop service -d dbName -s [sv1,...,svK] -i inst_name [-f] # Requires: inst_name, if specified, must be registered to all [sv1...svk] sub do_service_stop { my ($dbName, $sv_names, $inst_name, $doDisconnect) = @_; # if ( $serv_version =='10' ) if ($version=='10') { $cmd = "$ENV{ORACLE_HOME}/bin/srvctl stop service -d ".$dbName." -s $sv_names"; # add instance (if it was passed in): if ($inst_name) { $cmd = $cmd." -i $inst_name"; } if ($doDisconnect) { $cmd = $cmd." -f"; } print "Srvctl command: $cmd\n"; ### if (system "$cmd") { chomp ($result = `$cmd`); if ($? != 0) { ## print 'Failed to run the srvctl command in do_service_stop'; print "$result\n"; return ($? >> 8); } } print $result."\n"; return has_ec($result); } # Usage: do_service_relocate(dbName, sv_name, from_inst, to_inst) # Calls: srvctl relocate service -d dbName -s sv_name -i from_inst -t to_inst # Requires: sv_name is currently running on from_inst, and to_inst is a # registered instance sub do_service_relocate { my ($dbName, $sv_name, $from_inst, $to_inst) = @_; # if ( $serv_version =='10' ) if ($version=='10') { $cmd = "$ENV{ORACLE_HOME}/bin/srvctl relocate service -d ".$dbName." -s $sv_name -i $from_inst -t $to_inst"; print "Srvctl command: $cmd\n"; ## if (system "$cmd") { chomp ($result = `$cmd`); if ($? != 0) { ## print 'Failed to run the srvctl command in do_service_relocate'; print "$result\n"; return ($? >> 8); } } print $result."\n"; return has_ec($result); } # Purpose: find following error codes in input string: # "PRKP" # "PRKH" # "PRKO" # "CRS" # "ORA" sub has_ec { $in_str = $_[0]; # print "error code detector: $in_str\n"; if ($in_str =~ /PRKP-/ || $in_str =~ /PRKH-/ || $in_str =~ /PRKO-/ || $in_str =~ /CRS-/ || $in_str =~ /ORA-/) { return(-1); # error mesg } else { return(0); } } ## The following method is written to workaround bug 3469118. ## For pre-10g NT rac, if PATH env doesn't include $oracleHome/bin, ## the srvctl will return error when invoked not within $oracleHome/bin. ## The workaround for this bug is to change the current dir to $oracleHome/bin ## before calling srvctl and set it back when finished ## # Return the original current dir if it's changed # Otherwise return "" sub changeCWDForSrvctlIfNecessary { my ($oracleHome, $srvctlVersion) = @_; my $orgDIR = ""; if (get_osType() eq 'WIN' && $srvctlVersion eq '92') { # This is a NT pre-10g srvctl $orgDIR = getcwd; chdir "$oracleHome/bin"; } $orgDIR; }