Script: Monitor Long Operations
# David Mann
# http://ba6.us
use strict;
use DBI;
# WatchInstanceLongops.pl
# This program runs continuously to show current Long Operations on
# an Oracle Instance.
die "\nWatchInstanceLongops.pl\n\n" .
"This procedure watches long operations on an instance.\n\n" .
"syntax: perl $0 [SCHEMA_NAME]/[SCHEMA_PASSWORD]@[TNSNAME]\n"
if @ARGV < 0;
# Get command line arguments
my ( $connect_string ) = @ARGV;
# Connect to DB
print "Connecting to DB...\n";
my $dbh = getDBConnection( $connect_string );
### SQL Query that drives this procedure ###
my $sql = qq{ select ROUND(sofar/(totalwork+1)*100,2) as pct,
elapsed_seconds,
time_remaining,
v\$session_longops.message
from v\$session_longops
where sofar<>totalwork
order by target, sid
};
### Main Program : Begin ###
my($percent, $secselap, $secsleft, $message);
my ($count);
my $sth = $dbh->prepare($sql);
while (1) {
writeHeader($connect_string);
# Prepare and execute SELECT
$sth->execute();
# Declare and Bind Columns
$sth->bind_columns(undef, \$percent, \$secselap, \$secsleft, \$message);
# Fetch rows from DB
while( $sth->fetch() ) {
writeOutputBlock($percent, $message, $secselap, $secsleft);
}
sleep(3);
}
print "\ndone\n";
$sth->finish(); # Close cursor
$dbh->disconnect() or warn "DB disconnection failed: $DBI::errstr\n";
close(OUT);
### Main Program : End ###
# Function: getDBConnection
# Parameters: $connString - connection string in format user/password@tnsname
sub getDBConnection {
my ($connectstring) = @_;
my $slashpos = index($connectstring,'/');
my $atpos = index($connectstring,'@');
die "missing /" if ($slashpos == -1);
die "missing @" if ($atpos == -1);
my $username = substr($connectstring, 0, $slashpos);
my $password = substr($connectstring, $slashpos+1, $atpos - $slashpos - 1);
my $tnsname = substr($connectstring, $atpos + 1);
return DBI->connect( "dbi:Oracle:".$tnsname,
$username,
$password,
{
RaiseError => 1,
AutoCommit => 0
}
) || die "Database connection not made: $DBI::errstr";
};
# Function: writeHeader
# Parameters: $connString - connection string in format user/password@tnsname
sub writeHeader {
my ($connectstring) = @_;
my $atpos = index($connectstring,'@');
die "missing @" if ($atpos == -1);
system "cls";
print "Monitoring Instance: " . substr($connectstring, $atpos + 1) . "\n\n";
};
# Function: writeOutputBlock
# Parameters: $percent - percent done (0 - 100)
# $message - Text message from v$session_longops
# $secselap - Seconds elapsed from v$session_longops
# $secsleft - Estimated seconds left from v$session_longops
sub writeOutputBlock {
my ($percent, $message, $secselap, $secsleft) = @_;
print substr($message,0,79) . "\n";
print "Percent : $percent ";
print "Minutes elapsed : " . int($secselap/60) . ":" . sprintf("%02s", $secselap % 60) . " ";
print "Est. Minutes left : " . int($secsleft/60) . ":" . sprintf("%02s", $secsleft % 60) . "\n";
&writeProgressBar($percent,80);
print "\n";
};
# Function: writeProgressBar
# Parameters: $perc - percent done (0 - 100)
# $width - Total width of the Progress Bar
sub writeProgressBar {
my ($perc, $width) = @_;
my $spaces = int($perc / 100 * ($width-2));
print "|";
for ($count = 1; $count <= ($width-2); $count++) {
if ($count < $spaces) {
print "X";
} else {
print "=";
}
};
print "|";
};