Unix Code - Detail View


Date

Name

Plattform

Language

Kurzbeschreibung

Owner

Link

20.10.2002

xmpTBSCStmt.pl

Unix

Perl

Generiert Redirected Restore und Create Tablespace Statements

Gernot Ruban

 

DB2 ist ein Produkt der
IBM Corporation. Bitte
Copyright-  und Trademark-Hinweise beachten!

#!/usr/local/bin/perl -w
################################################################################
# xmpTBSCReStmt.pl - Generate Tablespace/Containter SQL Statements
# Called by - Command Level oder DBA Scripts
# Calls     - xmpPerl.pm   - xmp DBA Perl Package
#             Getopt       - Argument Verwaltung
#             Env          - Zugriff auf Umgebungsvariablen
#             English      - Aliase für Perl Variablen
# Optionen  - xmpTBSCReStmt.pl -d databaseDatenbank-Name
#                              -u user -p psw   User und Password         
#                              -f file          File für Statement Generierung
#       -t CREATE|RESTORE
#                              -s CURRENT|HWM   Size: Current Alloc or High Water Mark
#                              -g nn            Plus nn % growth
#-------------------------------------------------------------------------------
# Autor     - GR /28.03.01 - V1.0 erste Version, kopiert aus xmpTBSCList.pl
# Changes   - GR /16.05.01 - V1.1 Zugriff auf Catalog für BPool und Korrekturen,
#                                 z.B. für Berechnung HWM Page Sizes
#             GR /16.05.01 - V1.2 HWM Page Size zuzügl. Minimum Requirements
#             GR /06.07.01 - V1.3 neuer Parm -g nn für Wachstum
#             GR /02.11.01 - V1.4 Mehr Hinweise in erzeugtes Script schreiben
#-------------------------------------------------------------------------------
# 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_f $opt_t $opt_s $opt_g);
use xmpPerl;
use Env;
use English;

use DBI;
use DBD::DB2::Constants;
use DBD::DB2;

################################################################################
# Declare/Init
################################################################################
my $VER     = "1.4";

my $work    = "";# for TS List
my @work;# for TS List
my $work2   = "";# for Container List
my @work2;# for Container List

my ($dbh, $sth);# DB2 Access Handles
my $stmt= "";

my $var;
my $val;
my $id;

my $ts= 0;# no. of Tablespaces
my %ts_id= (); my $f1;# Tablespace Structure
my %ts_name= (); my $f2;
my %ts_type     = (); my $f3;
my %ts_content  = (); my $f4;
my %ts_state    = (); my $f5;
my %ts_pgtotal  = (); my $f6;
my %ts_pguseable= (); my $f7;
my %ts_pgused   = (); my $f8;
my %ts_pgfree   = (); my $f9;
my %ts_pghwm    = (); my $fe;# High Water Mark
my %ts_pgsize   = (); my $fa;
my %ts_extsize  = (); my $fb;
my %ts_pfsize   = (); my $fc;
my %ts_container= (); my $fd;

my $tsc= 0;# no. of Containers
my %tsc_tsid= (); #$f1# Tablespace ID
my %tsc_id      = ();#$f2# Container ID
my %tsc_name    = ();#$f3# Container Name
my %tsc_type    = ();#$f4
my %tsc_pgtotal = ();#$f5
my %tsc_pguseable=();#$f6
my %tsc_pgaccess=();#$f7
my %tsc_tsname  = ();#$f8# Tablespace Name

my $ts_total_total = 0;# Current Total Allocation
my $ts_total_hwm   = 0;# HWM Allocation
my $ts_total_new= 0;# new to allocate

my $hFile;# File Handle
my $pagemin = 0;# Min. no. of pages
my $bpool = "";# Bufferpool Name
my ($rest1,$rest2)      = "";                           # Add. Attributes

################################################################################
# Argumente/Options prüfen
################################################################################
getopts("d:u:p:f:t:s:g:");

if (! defined $opt_d )# Datenbank Check
{print "$0 - Datenbank nicht angegeben\n";
         SaySyntax();
}

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();  }
}

if (! defined $opt_f )# File für Statement Generierung
{print "$0 - File für Generierung des Statements fehlt\n";
        SaySyntax();
}

if (! defined $opt_t )# Type
{$opt_t = "RESTORE";
}

if (! defined $opt_s )# Size = Current Allocation Size
{$opt_s = "CURRENT";
}

$opt_d = uc $opt_d;
$opt_s = uc $opt_s;
$opt_t = uc $opt_t;

if (($opt_t ne "RESTORE")& ($opt_t ne "CREATE") ) {
print "$0 - Type invalid, please choose either CREATE or RESTORE!\n";
SaySyntax();
}

if (($opt_s ne "CURRENT")& ($opt_s ne "HWM") ) {
print "$0 - Options -s invalid value, use CURRENT or HWM only!\n";
SaySyntax();
}

if (! defined $opt_g )# Growth Percentage
{$opt_g = 0;
}
if (($opt_g < 0) | ($opt_g > 1000) ) {
print "$0 - Option -g invalid value, use 0 - 1000 only!\n";
SaySyntax();
}

################################################################################
# Check DB2 Existenz und Informationsblock ausgeben
################################################################################
xmpPerl::chkDB2();
xmpPerl::prtHeaderDB2("$0 - Generierung Tablespace Statements - V$VER");

print "Database / DB2 User ID ......: $opt_d / $opt_u";

################################################################################
# DB2 Connect zur Datenbank
################################################################################
$work = xmpPerl::doCmdOut("db2 connect to $opt_d user $opt_u using $opt_p ");
if ($work =~ "Connection Information")
   {print " (Connect erfolgreich)\n";}
else
   {die ">>>Kann keine Verbindung zur Datenbank $opt_d mit User $opt_u herstellen\n".
">>>Meldung: $work\n".
">>>ABEND";}

print "File for generated statement : $opt_f\n";
print "Type of generation ..........: $opt_t\n";
print "Object Size to consider .....: $opt_s\n";
print "Percentage Object Growth ....: $opt_g (0=not expanding)\n";

################################################################################
# DB2 List Commands ausführen
################################################################################
$work = xmpPerl::doCmdOut("db2 list tablespaces show detail");
undef $/;
@work = split("\n",$work);
#print "$#work lines returned from DB2 List Tablespace Command.\n";

foreach $work (@work) {
($var,$val) = split("=",$work);
if (! defined $var) {$var = "";}
if (! defined $val) {$val = "";}

$var = uc xmpPerl::trim($var);
$val = uc xmpPerl::trim($val);

########################################################################
# Korrektur erforderlich, wenn Utility Pending (z.B. Load vorher abgebr.)
########################################################################
if ($var =~ "CHANGE"){
$var = "";
$val = "";
}
#if ($var ne "" || $val ne "") {
#print "$var\t$val\n";
#}
########################################################################
# Beginn eines neuen Tablespace-Blocks
########################################################################
if ($var =~ "TABLESPACE ID"){
################################################################
# Tablespace Nummer erfassen
################################################################
##$ts++;
$ts = $val;
$ts_id{$ts} = $val;# neue TSpace ID
#print "Neuer TS $var $val\n";
}

#######################################################################
# andere Suchbegriffe
#######################################################################
if ($var =~ "NAME")      {
$ts_name{$ts} = $val;
################################################################
# Container Infos anfordern
################################################################
$f1   = $ts_id{$ts};
$f2 = "db2 list tablespace containers for $f1 show detail";
#print "TS-ID=$f1\n";
$work2= xmpPerl::doCmdOut($f2);
#print "$work2\n";
@work2 = split("\n",$work2);
#print "$#work2 lines returned from DB2 List Container Command.\n";
foreach $work2 (@work2) {
($var,$val) = split("=",$work2);
if (! defined $var) {$var = "";}
if (! defined $val) {$val = "";}
$var = uc xmpPerl::trim($var);
$val = xmpPerl::trim($val);
        #$val = uc xmpPerl::trim($val);

if ($var =~ "CONTAINER ID")  {
$tsc++;
$tsc_tsid{$tsc} = $f1;# Tablespace ID
$tsc_id{$tsc}   = $val;# neue Container ID
$tsc_tsname{$tsc} = $ts_name{$ts} # TS Name
}
if ($var =~ "NAME"){$tsc_name{$tsc} = $val}
if ($var =~ "TYPE")     {$tsc_type{$tsc} = uc $val};
if ($var =~ "TOTAL"){$tsc_pgtotal{$tsc}= $val}
if ($var =~ "USEABLE"){$tsc_pguseable{$tsc}= $val}
if ($var =~ "ACCESS"){$tsc_pgaccess{$tsc}= uc $val}
}
}

#######################################################################
# Und der Rest der anderen Suchbegriffe
#######################################################################
if ($var =~ "TYPE")     {
if ($val =~ "SYSTEM") {$ts_type{$ts} = "SMS"};
if ($val =~ "DATA")   {$ts_type{$ts} = "DMS"};
}
if ($var =~ "CONTENTS")  {
$ts_content{$ts}    = uc $val;
if ($val =~ "ANY") {$ts_content{$ts}  = "REGULAR"}
if ($val =~ "TEMP") {$ts_content{$ts} = "TEMPORARY"}
if ($val =~ "LONG") {$ts_content{$ts} = "LONG"}
}
if ($var =~ "STATE"){$ts_state{$ts}     = $val}
if ($var =~ "TOTAL")    {$ts_pgtotal{$ts}   = $val}
if ($var =~ "USEABLE")  {$ts_pguseable{$ts} = $val}
if ($var =~ "USED")     {$ts_pgused{$ts}    = $val}
if ($var =~ "FREE")     {
if ($val =~ "NOT APPLIC") {
$ts_pgfree{$ts} = "N/A"}
else {$ts_pgfree{$ts}= $val}
}
if ($var =~ "HIGH WATER"){
if ($val =~ "NOT APPLIC") {
$ts_pghwm{$ts}     = $ts_pgtotal{$ts} }
else {$ts_pghwm{$ts}     = $val }
}

if ($var =~ "PAGE SIZE") {$ts_pgsize{$ts}    = $val/1024}
if ($var =~ "EXTENT")    {$ts_extsize{$ts}   = $val}
if ($var =~ "PREFETCH")  {$ts_pfsize{$ts}    = $val}
if ($var =~ "CONTAINERS"){$ts_container{$ts} = $val}
}

################################################################################
# DB2 Connection abbauen
################################################################################
$work = xmpPerl::doCmdOut("db2 connect reset");

################################################################################
# File für Statements öffnen, falls vorhanden
################################################################################
if (! open(hFile, "> $opt_f") )
{  die "$0 kann nicht in $opt_f schreiben. \n".
    "abends";
}

################################################################################
# Create Header for Redirected RESTORE DATABASE Statement
################################################################################
if ($opt_t eq "RESTORE" ) {
print hFile "UPDATE COMMAND OPTIONS USING S ON Z ON $opt_f.out V ON;\n";
print hFile "SET CLIENT ATTACH_NODE 0;\n";
print hFile "SET CLIENT CONNECT_NODE 0;\n";
$work = xmpPerl::getTimestamp();

print hFile "ECHO \@---------------------------------------------------------\@;\n";
print hFile "ECHO \@Script created ........: $work \@;\n";
print hFile "ECHO \@Script File ...........: $opt_f \@;\n";
print hFile "ECHO \@Database to be restored: $opt_d (Redirected Restore) \@;\n";
print hFile "ECHO \@Database Object Sizing : $opt_s plus $opt_g\% growth \@;\n";
print hFile "ECHO \@Disclaimer: Check/edit this script to avoid loss of data! \@;\n";
print hFile "----------------------------------------------------------------\n";
print hFile "RESTORE DB $opt_d \n".
    "        FROM /back-up-path\n".
    "        TAKEN AT yyyymmddhhmmss\n".
    "        TO   /new-db-path\n".
    "        INTO new-db\n".
    "        NEWLOGPATH /new-logpath\n".
    "        WITH 2 BUFFERS BUFFER 2048\n".
    "        REDIRECT;\n";
print hFile "----------------------------------------------------------------\n";
print hFile "-- Comments: DO NOT CHANGE THE NAME IN 'RESTORE DB $opt_d'!\n".
    "--           DO NOT CHANGE THE NAME IN 'RESTORE DB $opt_d CONTINUE'!\n".
    "--           /back-up-path = path or location of back-up file \n".
    "--           yyymmddhhmmss = back-up start timestamp, part of backup-file name\n".
    "--           /new-db-path  = database path, see CONTAINER statement below\n".
    "--           new-db        = original database name or new target db name\n".
    "--           /new-logpath  = path to log files, you may alter it afterwards\n".
    "--                           with UPDATE DB CFG FOR ... USING NEWLOGPATH ...\n";
print hFile "----------------------------------------------------------------\n";
print hFile "-- RESTORE DB $opt_d ABORT;\n";
}

################################################################################
# Create Header for CREATE TABLESPACE Statement
################################################################################
if ($opt_t eq "CREATE" ) {
$work = xmpPerl::getTimestamp();
print hFile "----------------------------------------------------------------\n";
print hFile "-- DDL created ........: $work\n";
print hFile "-- DDL File ...........: $opt_f\n";
print hFile "-- Database ...........: $opt_d\n";
        print hFile "-- Object Sizing ......: $opt_s\n";
print hFile "-- Disclaimer: Check/edit this DDL script to avoid loss of data!\n";
print hFile "----------------------------------------------------------------\n";

################################################################################
# DBI Switches
################################################################################
my $switch = DBI->internal;
$switch->debug(0);                     # 1=normal debug, 2=detailed handle trace
#print "DBI Version and Attributes ..: $switch->{'Attribution'}, $switch->{'Version'}\n";
#print "DBI Drivers .................: ",join(", ",DBI->available_drivers()),"\n";

################################################################################
# Connect to Database
################################################################################
$dbh = DBI->connect("dbi:DB2:$opt_d",
                       $opt_u,
                       $opt_p,
                    { PrintError => 0, # don't print error by default
                      RaiseError => 0, # don't print error and die by default
                      AutoCommit => 0, # don't commit after each statement
                      ChopBlanks => 0, # don't remove trailing blanks on CHAR-Types
                    } )
        || die ">>>$0 Problem mit Connect to $opt_d\n>>>".$DBI::errstr;
}

################################################################################
# Anweisungen für jeden Tablespace Container oder Pfad
################################################################################
$work  = $tsc;
$work2 = "";
for ($tsc = 1; $tsc <= $work; $tsc++) {
$f1 = $tsc_tsid{$tsc};
$f2 = $tsc_id{$tsc};
$f3 = $tsc_name{$tsc};
$f4 = $tsc_type{$tsc};
$f5 = $tsc_pgtotal{$tsc};
$f6 = $tsc_pguseable{$tsc};
$f7 = $tsc_pgaccess{$tsc};
$f8 = $tsc_tsname{$tsc};
#print ">>>".$ts_name{$f1}."\n";

$ts_total_total = $ts_total_total + ( $f5 * $ts_pgsize{$f1} );

########################################################################
# Consider percentage of growth from net space                      V1.3
########################################################################
if ($opt_g > 0) {
$f5 = $f5 * ((100+$opt_g)/100);  # V1.3
$f5 = int($f5 + 0.5);  # V1.3
}

########################################################################
# Calculate minumum number of pages per Tablespace
########################################################################
$pagemin = $ts_container{$f1} + ( (3+2+2 +1)* $ts_extsize{$f1} );
$pagemin = $pagemin + $ts_pghwm{$f1};# Overhead V1.2

########################################################################
# Calculate HWM per file dividing HWM pages by number of containers
########################################################################
#print "TS HWM: ".$ts_pghwm{$f1}." / ".$ts_container{$f1}."\n";
        $fe = int(( $pagemin / $ts_container{$f1} )+ 0.5);# round
$fe = int(( ($fe + 9 )/ 10 ) ) * 10;
$ts_total_hwm   = $ts_total_hwm   + ( $fe * $ts_pgsize{$f1} );
if ($opt_g > 0) {
$fe = $fe * ((100+$opt_g)/100);  # V1.3
$fe = int($fe + 0.5);  # V1.3
}

########################################################################
# Assign calculated new space, summarize Page Counts and KBytes
########################################################################
if ($opt_s eq "HWM") { $f5 = $fe };
$ts_total_new = $ts_total_new + ( $f5 * $ts_pgsize{$f1} );

########################################################################
# Create Redirected RESTORE DATABASE Statement, Tablespace Sections
########################################################################
if ($opt_t eq "RESTORE" ) {
################################################################
# Create Container
################################################################
if ($f1 ne $work2){# TS-ID changed?
if ($tsc gt 1) {print hFile "    );\n"};
print hFile "----------------------------------------------------***\n";
print hFile "--  TS ID $f1 / $f2 / $f8 \n";
 print hFile "--  Space Allocated in Pages: ".$ts_pgtotal{$f1}."\n";
if ( $ts_type{$f1} eq "DMS" ) {
print hFile "--  High Water Mark in Pages: ".$ts_pghwm{$f1}."\n";
}
print hFile "-------------------------------------------------------\n";
print hFile "SET TABLESPACE CONTAINERS FOR $f1 USING (\n";
if ($f4 eq "FILE") {print hFile "    $f4 $f3 $f5     \n";}
if ($f4 eq "PATH") {print hFile "    $f4 $f3         \n";}
if ($f4 eq "DISK") {print hFile "    DEVICE $f3 $f5  \n";}
}
else{
if ($f4 eq "FILE") {print hFile "   ,$f4 $f3 $f5     \n";}
if ($f4 eq "PATH") {print hFile "   ,$f4 $f3         \n";}
if ($f4 eq "DISK") {print hFile "   ,DEVICE $f3 $f5  \n";}
}
}

########################################################################
# Create CREATE TABLESPACE Statement
########################################################################
if ($opt_t eq "CREATE" ) {

################################################################
# Next Tablespace? Add additional attributes at end of current cmd
################################################################
if (($work2 ne "") & ($work2 ne $f1)) {
print hFile $rest1;
print hFile $rest2;
}

########################################################################
# Access to DB2 Catalog to get Bufferpool
########################################################################
#$stmt = "select a.tbspace, a.tbspaceid, a.bufferpoolid,b.bpname".
$stmt ="select b.bpname ".
"from   sysibm.systablespaces a, ".
"       sysibm.sysbufferpools b ".
"where  a.bufferpoolid = b.bufferpoolid ".
"and    a.tbspace = '$f8' ".
"and    a.tbspaceid = $f1 ";
$sth = $dbh->prepare($stmt);
$sth->execute() || die $dbh->errstr;
if ( $dbh->err ) {
die "$0 abended with $dbh->errstr";
}
$bpool = $sth->fetchrow();
if ( $dbh->err ) {
$bpool = "BPCannotCreate $dbh->errstr";
}

################################################################
# Additional attributes for the end of current cmd
################################################################
$rest1 = "          ) EXTENTSIZE ".$ts_extsize{$f1}." PREFETCHSIZE ".$ts_pfsize{$f1}."\n";
$rest2 = "          BUFFERPOOL $bpool;\n";

################################################################
# Create Tablespace
################################################################
if ($f1 ne $work2){# TS-ID changed?
print hFile "----------------------------------------------------***\n";
print hFile "-- TS $f1 $f8: ".$ts_pgtotal{$f1}." total pages, HWM ".$ts_pghwm{$f1}." pages\n";
print hFile "-- DROP TABLESPACE $f8;\n";
print hFile "   CREATE ".$ts_content{$f1}." TABLESPACE $f8\n";
print hFile "          PAGESIZE ".$ts_pgsize{$f1}."K \n";

if ($ts_type{$f1} eq "DMS") {
print hFile "          MANAGED BY DATABASE\n";}
else {print hFile "          MANAGED BY SYSTEM\n";}
if ($f4 eq "FILE") {print hFile "          USING (FILE '$f3' $f5 \n";}
if ($f4 eq "PATH") {print hFile "          USING ('$f3' \n";}
if ($f4 eq "DISK") {print hFile "          USING (DEVICE '$f3' $f5\n";}
}
else{
if ($f4 eq "FILE") {print hFile "                ,FILE '$f3' $f5\n";}
if ($f4 eq "PATH") {print hFile "                ,'$f3'    \n";}
if ($f4 eq "DISK") {print hFile "                ,DEVICE '$f3' $f5\n";}
}
}

$work2 = $f1;
}


$tsc--;

################################################################################
# Create Footer for Redirected RESTORE DATABASE Statement
################################################################################
if ($opt_t eq "RESTORE" ) {
print hFile "   );\n";
print hFile "----------------------------------------------------***\n";
print hFile "ECHO \@Restored Database Size : $ts_total_new KBytes \@;\n";
print hFile "----------------------------------------------------***\n";
print hFile "RESTORE DB $opt_d CONTINUE;\n";
print hFile "-- ROLLFORWARD DATABASE $opt_d TO END OF LOGS;\n";
print hFile "-- ROLLFORWARD DATABASE $opt_d STOP;\n";
print hFile "----------------------------------------------------------------\n";
print hFile "-- Comments: Use ROLLFORWARD TO END OF LOGS, if log files will\n".
    "--           contain important information which will bring the\n".
    "--           database to latest consistent state. Use STOP to\n".
    "--           ignore log files at all. Do not use CANCEL keyword!\n";
print hFile "----------------------------------------------------------------\n";
}
else {
print hFile $rest1;print hFile $rest2;
        print hFile "-- \n";
        print hFile "-- Database Total Size : $ts_total_new KBytes\n";
        print hFile "-- ***END***\n";

################################################################################
# Close Statement, Disconnect from Database
################################################################################
$sth->finish()   || die $dbh->errstr;
$dbh->commit     || die $dbh->errstr;
$dbh->disconnect || die $dbh->errstr;
}

########################################################################
# Close File and set File Access Mode
########################################################################
close(hFile);
chmod 0775,$opt_f;

print "Current Total allocated .....: $ts_total_total kBytes\n";
print "High Water Mark used ........: $ts_total_hwm kBytes\n";
print "New space to be allocated ...: $ts_total_new kBytes\n";
print "Tablespaces $opt_t File successfully created for $opt_d!\n";

print "***Ende***\n";

exit 0;


#################################################################################
########################################################## Sub Routines #########
# SaySyntax #####################################################################
sub SaySyntax {
die "Usage: [perl] $0 -d db [-u parm -p parm] -f file [-t {RESTORE|CREATE} -s {CURRENT|HWM}] [-g nn]\n".
"-d database \n".
"-u User (opt)\n".
"-p Password (opt)\n".
"-f file for statement generation\n".
"-t type of statement to generate\n".
"-s current allocation or HWM High Water Mark)\n".
"-g percentage growth (CURRENT/HWM plus n%)\n".
"abends";
}

© Gernot Ruban