#!/usr/local/bin/perl # # $Header: dgObserverStatus.pl 16-aug-2006.07:31:17 sjconnol Exp $ # # dgObserverStatus.pl # # Copyright (c) 2005, 2006, Oracle. All rights reserved. # # NAME # dgObserverStatus.pl - Script to get the status of DG Fast-start failover observer # # DESCRIPTION # This script gets the status for the Data Guard Fast-start failover observer. # The status could be one of the following # 1) Fast-start failover disabled (When FSFO is not enabled) # 2) Normal (When FSFO is enabled and observer is up) # 3) Error ORA-16820 (When FSFO is enabled and observer is down) # # NOTES # Applicable only for 10gR2 upwards # # MODIFIED (MM/DD/YY) # sjconnol 08/16/06 - 11g changes # ngade 04/06/06 - display current observer # kramarat 07/24/05 - kramarat_dgob # kramarat 07/21/05 - Creation # use strict; use Sys::Hostname; require "$ENV{EMDROOT}/sysman/admin/scripts/db/dg/dgutil.pl"; # RaiseError $SIG{__DIE__} = \&handleError; # PrintError $SIG{__WARN__} = \&handleWarning; # Trace the target name. EMD_PERL_DEBUG("Database target=$ENV{EM_TARGET_NAME}"); # Supports 10gR2. my $db_version = $ENV{VersionCategory}; verify_dbversion_102($db_version); # Connect to the instance. my %stdinArgs = get_stdinvars(); my $username = $stdinArgs{EM_TARGET_USERNAME}; my $password = $stdinArgs{EM_TARGET_PASSWORD}; my $role = $ENV{EM_TARGET_ROLE}; my $mode = 0; if($role =~ /SYSDBA/i) { $mode = 2; } elsif($role =~ /SYSOPER/i) { $mode = 4; } my $address = $ENV{EM_TARGET_ADDRESS}; my $lda = DBI->connect('dbi:Oracle:', "$username@".$address, "$password", {ora_session_mode => $mode, PrintError => 0, RaiseError => 1}); # Register this test once we're connected. register_metric_call($lda); # Make a few more checks before continuing. verifyPrimary($lda); my $broker = verifyBroker($lda); if ($broker) { doEval($lda); } $lda->disconnect; exit 0; sub verifyFSFO { my ($lda) = @_; my $sql = "select FS_FAILOVER_STATUS from v\$database"; my $dbcur = $lda->prepare($sql); $dbcur->execute; my @row = $dbcur->fetchrow_array(); my $fsfo_status = $row[0]; if($fsfo_status =~ /DISABLED/i) { return 0; } else { return 1; } } sub getObserverHost { my ($lda) = @_; my $sql = "select FS_FAILOVER_OBSERVER_HOST from v\$database"; my $dbcur = $lda->prepare($sql); $dbcur->execute; my @row = $dbcur->fetchrow_array(); my $fsfo_host = $row[0]; return $fsfo_host; } sub doEval { my ($lda) = @_; my $final_result; # verify if FSFO is enabled if(verifyFSFO($lda)) { $final_result = observerRestartRequired($lda); } else { $final_result = "em_result=Fast-start failover disabled\n"; } print $final_result; } # Get the status of DG FSFO observer # Parameters # lda - The login identifier (Login Data Area). sub observerRestartRequired { my ($lda) = @_; # Retrieve the configuration object content. my $indoc = ""; my $drc_obj = get_dg_document($lda, $indoc); # Retrieve the list of sites. my (%site_list); my ($site_id, $site_obj); my $drc_start_pos = -1; my $site_start_pos = -1; my $result; while (($site_id = get_dg_token($drc_obj, "site_id", $drc_start_pos)) ne "") { EMD_PERL_DEBUG("dgObserverStatus.observerRestartRequired: site_id=$site_id"); # Retrieve the site object content. $indoc = ""; $site_obj = get_dg_document($lda, $indoc); $site_list{$site_id} = $site_obj; } foreach $site_id (keys(%site_list)) { $site_obj = $site_list{$site_id}; my($status) = DGgetDatabaseStatus($lda, $site_obj); my $dbres_id = get_dg_property($lda, $site_id, "DBRESOURCE_ID"); if($status =~ /16820/) { EMD_PERL_DEBUG("dgObserverStatus.observerRestartRequired: found unobserved status; observer restart required"); $result = "em_result=Error $status\n"; return $result; } ## ORA-16824/16825 multiple FSFO errors; must get full status report if($status =~ /16824|16825/){ EMD_PERL_DEBUG("dgObserverStatus.observerRestartRequired: found 16824/16825 status; getting StatusReport"); my $dbres_id = get_dg_property($lda, $site_id, "DBRESOURCE_ID"); my $statusrpt = get_dg_property($lda, $dbres_id, "StatusReport"); my @dbres_status_tokens = split(/[><]+/, $statusrpt); my $dbres_status_token; foreach $dbres_status_token (@dbres_status_tokens) { if ($dbres_status_token =~ /ORA-16820/) { EMD_PERL_DEBUG("dgObserverStatus.observerRestartRequired: found unobserved status; observer restart required"); $result = "em_result=Error $dbres_status_token\n"; return $result; } } } EMD_PERL_DEBUG("dgObserverStatus.observerRestartRequired: status for site $site_id: $status"); } EMD_PERL_DEBUG("dgObserverStatus.observerRestartRequired: no observer down status"); my $fsfo_host = getObserverHost($lda); EMD_PERL_DEBUG("dgObserverStatus.observerRestartRequired: fsfo_host: ". $fsfo_host); $result = "em_result= Observer is running normally on $fsfo_host.\n"; return $result; } sub DGgetDatabaseStatus { my ($lda, $site_obj) = @_; my $site_start_pos = -1; # Parse out the site id. my $site_id = get_dg_token($site_obj, "site_id", $site_start_pos); EMD_PERL_DEBUG("dgObserverStatus.DGgetDatabaseStatus: site_id=$site_id"); # Retrieve the site DBRESOURCE_ID property. my $dbres_id = get_dg_property($lda, $site_id, "DBRESOURCE_ID"); EMD_PERL_DEBUG("dgObserverStatus.DGgetDatabaseStatus: dbres_id=$dbres_id"); # Retrieve the db resource ENABLED property. my $dbres_enabled = get_dg_property($lda, $dbres_id, "ENABLED"); EMD_PERL_DEBUG("dgObserverStatus.DGgetDatabaseStatus: dbres_enabled=$dbres_enabled"); # The db resource must be enabled. if (!($dbres_enabled =~ /YES/i)) { EMD_PERL_DEBUG("dgObserverStatus.DGgetDatabaseStatus: The db resource must be enabled."); return ""; } # Retrieve the db resource INTENDED_STATE property. my $dbres_state = get_dg_property($lda, $dbres_id, "INTENDED_STATE"); EMD_PERL_DEBUG("dgObserverStatus.DGgetDatabaseStatus: dbres_state=$dbres_state"); # The db resource intended state must not be offline. if (($dbres_state =~ /OFFLINE/i)) { EMD_PERL_DEBUG("dgObserverStatus.DGgetDatabaseStatus: The db resource must not be offline."); return ""; } # Retrieve the db resource status. my $dbres_status = ""; my $dbres_status_text = ""; get_dg_dbres_status($lda, $dbres_id, $dbres_status, $dbres_status_text); EMD_PERL_DEBUG("dgObserverStatus.DGgetDatabaseStatus: Site $dbres_id : returning $dbres_status"); return($dbres_status_text); }