DB2 ist ein Produkt der
IBM Corporation. Bitte Copyright- und Trademark-Hinweise beachten!
#!/usr/local/bin/perl -w
################################################################################
# xmpRFHTool.pl - DB2 Recovery History File Tool
# Called by - Command Level oder DBA Scripts
# Calls - xmpPerl.pm - DBA Perl Package
# Getopt - Argument Verwaltung
# Env - Zugriff auf Umgebungsvariablen
# English - Aliase für Perl Variablen
# Optionen - -d database - Datenbank-Name
# -u USER - User ID
# -p PSW - Password
# -m - Prune History Timestamp oder Log (braucht -u/-p)
# -l - Delete Logs nach Prune History (braucht -m)
#-------------------------------------------------------------------------------
# Autor - GR /05.06.00 - V1.0 erste Version
# Changes - GR /13.06.00 - V1.0.1 Korrektur für Load Utility
# GR /06.07.00 - V1.0.2 Maint-Parameter auf Header ausgeben
# GR /12.07.00 - V1.1 neue Option -l, Prune Logfile nur mit DB2 V6,
# Logging in dba.log aktiviert
# GR /24.08.00 - V1.1.1 kleine Änderung bezügl. Liste der Logs, Tests
# mit alternativen "globs"
#-------------------------------------------------------------------------------
# Comments - PERL5LIB Environment Variable muss auf Perl Module Pfad zeigen!
################################################################################
################################################################################
# Modules
################################################################################
use strict;
use Getopt::Std;
use vars qw($opt_d $opt_u $opt_p $opt_m $opt_l);
use xmpPerl;
use Env;
use English;
use File::stat;
use File::Basename;
use Time::localtime;
################################################################################
# Declare/Init
################################################################################
my $VER = "1.1.1";
my $work = "";# for TS List
my @work;# for TS List
my ($c1, $c2, $c3, $c4, $c5, $c6, $c7, $c8, $c9);
my ($ca, $cb, $cc, $cd, $ce, $cf, $cg, $ch, $ci);
my $dm;# Feld für Dummy Werte
my $loglist;# Feld für Log Dateien
my ($lname,$lsname,$lpath,$lsuffix);# Log File Name/Path/Suffix
my $prune_ts = ""; # Timestamp to Prune
my $prune_log = ""; # Log to Prune
my $f_on = 0;# Flag on/off
my $f_write = 0;# Write Flag
my $f_bkp = 0;# Backup Exists Flag
my $n_bkp_miss = 0; # Backup Files Missing Anzahl
my $n = 0;# Counter
################################################################################
# Ausgabe-Formate
################################################################################
format EVT_KOPF =
------------------------LIST OF DATABASE EVENTS---------------------------------
+--Operation: B=BACKUP L=LOAD R=RESTORE S=RUNST T=ALTER D=DROP F=ROLLF G=REORG
! +--Object: D=DB P=TABLESPACE T=TABLE
! ! +--Type: F=OFFLINE N=ONLINE C/R=ALTER-TS S/U=QUIESCE etc
! ! ! +--Device: A=ADSM D=DISK L=LOCAL P=PIPE T=TAPE S=SERVER
! ! ! ! ?: X=BACKUP FILE EXISTS
! ! ! *
* * * D 1st Log Curr Log Path
P O Timestmp+Seq T ? Start Time End Time Statement/Comment
--------------------------------------------------------------------------------
.
format EVT_ZEILE =
@ @ @<<<<<<<<<<<<<<<< @ @ @<<<<<<<<<<< @<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<
$c1,$c2,$c3, $c4,$c5,$c6, $c7, $cb
@ @<<<<<<<<<<<<< @<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<
$cd,$c9, $ca, $cc
.
################################################################################
# Argumente/Options prüfen
################################################################################
getopts("d:u:p:ml:");
if (! defined $opt_d )# Datenbank Check
{print "$0 - Datenbank nicht angegeben\n";
SaySyntax();
}
$opt_d = uc $opt_d;
if (defined $opt_m ) {# Maintain/Prune gewählt
if (! defined $opt_u ) {# User Check
$opt_u = xmpPerl::getDBAUser();
if ($opt_u eq "") {
print "$0 - User nicht angegeben und keine lP_LUS Variable definiert\n";
SaySyntax();
}
}
if (! defined $opt_p ) {# User Password Check
$opt_p = xmpPerl::getDBAPsw();
if ($opt_p eq "") {
print "$0 - User's Password fehlt und keine lP_LPW Variable definiert\n";
SaySyntax();
}
}
}
################################################################################
# Check DB2 Existenz und Informationsblock ausgeben
################################################################################
xmpPerl::chkDB2();
xmpPerl::prtHeaderDB2("$0 - DB2 Recovery History File Tool - Version $VER");
print "Database ....................: $opt_d\n";
if (defined $opt_m) {
print "User ........................: $opt_u\n";
}
xmpPerl::LogLine("DBA I ".$0." ".$opt_d);
################################################################################
# List Recovery History File
################################################################################
$work = xmpPerl::doCmdOut("db2 list history all for $opt_d");
undef $/;
@work = split("\n",$work);
#print "$#work lines returned from DB2 List History Command.\n";
################################################################################
# Formular-Einstellungen
################################################################################
$FORMAT_NAME = "EVT_ZEILE"; # $~
$FORMAT_TOP_NAME = "EVT_KOPF";# $^
$FORMAT_FORMFEED= "";# $^L
$FORMAT_LINES_PER_PAGE= 60;# $=, plus Lines für Kopf
################################################################################
# Je nach Option DB2 Command Output auswerten
################################################################################
foreach $work (@work) {
if ($f_on) {
$f_on = 0;
($c1, $c2, $c3, $c4, $c5, $c6, $c7, $c8) = split(" ",$work);
}
if ($work =~ / -- --- -------------/) {
$f_on = 1;
#print "START ...\n";
}
if ($work =~ /Start Time:/) {
($dm,$dm,$c9) = split(" ",$work);
$c9 = substr($c9,0,14);
}
if ($work =~ /End Time:/) {
($dm,$dm,$ca) = split(" ",$work);
$ca = substr($ca,0,14);
}
if ($work =~ /Location:/) {
($dm,$dm,$cb) = split(" ",$work);
$f_write = 1;
#print "STOP ...\n";
}
if ($work =~ /DDL:/) {
$cc = substr($work,3);
}
if ($work =~ /Comment:/) {
$cc = substr($work,13);
}
########################################################################
# Über Formatmaske Report-Satz schreiben
########################################################################
if ($f_write) {
if (! defined $c5) {$c5=""}
if (! defined $c6) {$c6=""}
if (! defined $c7) {$c7=""}
if (! defined $c8) {$c8=""}
if (! defined $c9) {$c9=""}
if (! defined $ca) {$ca=""}
if (! defined $cb) {$cb=""}
if (! defined $cc) {$cc=""}
if (! defined $cd) {$cd=""}
########################################################
# Backup Datei vorhanden?
########################################################
$cd = "";# File exists?
if ( ($cb ne "")# Path
&& ($c1 eq "B") ) {# Backup
$dm = "$cb/$opt_d.*.".
substr($c3,0,14).".".substr($c3,14);
#print "$dm\n";
if (glob($dm) ne "") {# Ohne Endung
$cd = "X"
}
$dm = "$cb/$opt_d.*.".
substr($c3,0,14).".".substr($c3,14).
"*";
#print "$dm\n";
if (glob($dm) ne "") {# Mit Endung
$cd = "X"
}
if ($cd eq "") {$n_bkp_miss++}# Missing Backup File
}
########################################################
# Pruning Informationen sammeln
########################################################
# Wenn Backup File nicht vorhanden und auch noch keine gefunden
if ( ($cd ne "X")# Prune TS
&&(! $f_bkp)) {$prune_ts = $ca}
# Backup File vorhanden und Log noch nicht gemerkt
if ( ($cd eq "X")# Prune Log
&&($prune_log eq "")) {$prune_log = $c7}
# mindestens eine Backup File vorhanden
if ($cd eq "X") {$f_bkp=1}# Bkp Exitst Flag
########################################################
# Jetzt schreiben
########################################################
write;
$f_write = 0;
}
}
print "--------------------------------------------------------------------------------";
print "Prune History bis Timestamp .: $prune_ts\n";
print "Prune History bis Log (excl.): $prune_log\n";
if ($n_bkp_miss gt 0) {print "Missing Backup Files ........: $n_bkp_miss\n";}
################################################################################
# Maitain/Prune Recovery History requested
################################################################################
if (defined $opt_m) {
print "Connect zur DB ..............: $opt_d ";
$work = xmpPerl::doCmdOut("db2 connect to $opt_d user $opt_u using $opt_p");
if ($work =~ "Connection Information")
{print "erfolgreich\n"}
else
{die ">>>Kann keine Verbindung zu $opt_d herstellen\n".
">>>Maintain/Prune Recovery History File nicht möglich\n".
">>>Meldung: $work\n".
">>>ABEND";}
if ($prune_ts ne "") {
print "Prune Command ...............: db2 prune history $prune_ts\n";
$work = xmpPerl::doCmdOut("db2 prune history $prune_ts");
}
else {
if ($prune_log ne "") {
print "Prune Command ...............: db2 prune logfile prior to $prune_log\n";
print " (Nicht ausführbar mit DB2 UDB V5.x)\n";
$work = xmpPerl::doCmdOut("db2 prune logfile prior to $prune_log");
}
else {
$work = "Pruning/Maintaining nicht möglich, kein TS/Log!";
}
}
$work = xmpPerl::trim($work);
print "Pruning/Maintaining Erfolg ..: $work\n";
xmpPerl::LogLine("DBA I ".$0." ".$opt_d." mit PRUNE HISTORY $prune_ts|$prune_log=$work");
$work = xmpPerl::doCmdOut("db2 connect reset");
}
################################################################################
# Delete obsolete Log Files
################################################################################
if (defined $opt_l) {
########################################################################
# List Log Files in Log Path
########################################################################
xmpPerl::LogLine("DBA I ".$0." ".$opt_d." mit Log File Bereinigung");
print "DB2 Log-Bereinigung im Pfad : $opt_l\n";
$work = xmpPerl::doCmdOut("ls -1 $opt_l/*.LOG*");
undef $/;
@work = split("\n",$work);
$n = 0;
foreach $work (@work) {$n++};
########################################################################
# List Recovery History File
########################################################################
$loglist = xmpPerl::doCmdOut("db2 list history all for $opt_d");
########################################################################
# Abgleich File im FS gegen DB2 Recover History
########################################################################
print "Files im (Archive) Log Path : $n\n";
$f_on = 0;
foreach $work (@work) {
($lname, $lpath, $lsuffix) = fileparse($work,'.LOG*');
$lsname = substr($lname,0,8);
if ( ($loglist =~ /$lsname/)
or ($f_on)){
print "- In use ...: $lsname ($lname)\n";
$f_on = 1;# ab hier alle in Use
}
else {
print "- Not in use: $lsname ($lname): ";
if (unlink($opt_l."/".$lname)) {print "deleted\n"}
else {print "not deleted ($ERRNO)\n"}
}
}
########################################################################
# Verbleibende Files im Verzeichnis
########################################################################
$work = xmpPerl::doCmdOut("ls -1 $opt_l");
undef $/;
@work = split("\n",$work);
$n = 0;
foreach $work (@work) {$n++};
print "Verbleibende Dateien im Pfad : $n\n";
print "$work\n";
}
print "***Ende***\n";
exit 0;
#################################################################################
########################################################## Sub Routines #########
# SaySyntax #####################################################################
sub SaySyntax {
die "Usage: [perl] $0 -d db [-u user -p psw -m ] [-l logpath] ]\n".
"-d database \n".
"-u User (opt)\n".
"-p Password (opt)\n".
"-m Maintain/Prune Recovery History (opt)\n".
" -l Delete obsolete Logs (opt)\n".
"abends";
}
© Gernot Ruban