#!/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);
}