#!/usr/local/bin/perl -w # # $Id: irebuild,v 2.0 2000/02/29 22:45:47 oracle Exp oracle $ # # This perl script will re-create Oracle indexes # for all non SYS or SYSTEM schemas in the # database. It will check that it executes # during the time limits specified. If there is # a problem during execution of the script it # writes the Oracle error on STDERR and continues. # # Copyright (c) 2000, Brad Christensen. All rights reserved. # # Syntax: # irebuild --sid --uid --pwd --maxtm [--debug] # # ------------------------------------------------------------------- # D I S C L A I M E R * * D I S C L A I M E R * * D I S C L A I M E R # ------------------------------------------------------------------- # This script is free software. Use it at your own risk. This script # may be redistributed under the same terms as PERL itself. # The latest version of the script may be found at: # http://www.andrews.edu/~bradc/perl/irebuild # ------------------------------------------------------------------- # $| = 1; use Oraperl; use Getopt::Long; use strict( "vars" ); use constant SUCCESS => 0; use constant FAILURE => 1; my $sid = ''; my $maxtm = 0; my $uid = ''; my $pwd = ''; my $debug = 0; my %OPTNCTL = ( 'sid' => \$sid, 'maxtm' => \$maxtm, 'uid' => \$uid, 'pwd' => \$pwd, 'debug' => \$debug ); my $res = GetOptions( \%OPTNCTL, 'sid=s', 'maxtm=i', 'uid=s', 'pwd=s', 'debug' ); die &Syntax() if ( scalar @ARGV ); die &Syntax() unless( $sid && $maxtm && $uid && $pwd ); ################################################################### $ENV{ORACLE_SID} = $sid; $ENV{ORACLE_HOME} = `/u/cc/aucc/orahome $sid`; my $login = ora_login( $sid, $uid, $pwd ) || die "Couldn't connect to $sid as user $uid!"; my $sql = ''; $sql = "select owner, index_name, table_owner, table_name, tablespace_name, decode( uniqueness, 'NONUNIQUE', null, uniqueness ) from dba_indexes where owner not in ( 'SYS', 'SYSTEM' ) order by owner, index_name"; print STDERR "Running in debug mode...\n" if ( $debug ); my $csr = ora_open( $login, $sql ) || die $ora_errstr; # now, loop through indexes we're going to rebuild # and quit when done or when time is up # if done, then reset schema & index to null # if time up, save next schema & index as starting # point for next script run... my $STARTTIME = time; my $STOPTIME = $STARTTIME + $maxtm; my $lastkey = ''; my $rsql = ''; my $indexes = 0; while( my( $iown, $inm, $town, $tnm, $tbsp, $uniq, $colnm, $seq ) = ora_fetch( $csr ) ) { $uniq ||= ''; $uniq .= ' '; my $newkey = $iown . "\t" . $inm; if ( $newkey ne $lastkey ) { if ( $lastkey ) { if ( time >= $STOPTIME ) { print STDOUT "Time limit exceeded.\n", "$indexes indexes rebuilt for $sid in " . ( time - $STARTTIME ) . " second(s)\n"; ora_close( $csr ); exit( 0 ); } if ( $debug ) { print STDERR $rsql . "\n"; } else { ora_do( $login, $rsql ) || ScriptError( $ora_errstr ); } $indexes++; } $rsql = "alter index $iown.$inm rebuild unrecoverable tablespace $tbsp"; $lastkey = $newkey; } } ora_close( $csr ); if ( $lastkey ) { if ( $debug ) { print STDERR $rsql . "\n"; } else { ora_do( $login, $rsql ) || ScriptError( $ora_errstr ); } $indexes++; } print STDOUT "$indexes indexes rebuilt for $sid in " . ( time - $STARTTIME ) . " second(s).\n"; exit 0; sub ScriptError { my( $err ) = @_; my $msg = join( "\n", $err, '-' x 15 ); warn $msg; } sub Syntax { my $cmd = `/bin/basename $0`; chomp( $cmd ); print STDERR "\nSyntax: $cmd --sid --maxtm \n", " ", ' ' x length( $cmd ) . " --uid --pwd \n\n", "\t = Oracle instance to connect to\n", "\t = maximum # of seconds to allow $cmd to run\n", "\t = user id of schema to connect to\n", "\t = password for schema\n\n"; exit( -1 ); } __END__ =pod =head1 NAME irebuild - Oracle Index Rebuild utility =head1 SYNOPSIS irebuild --sid --uid --pwd --maxtm [--debug] =head1 DESCRIPTION irebuild is a PERL script that will allow the DBA to rebuild the non-SYS and non-SYSTEM schema indexes in an Oracle instance. It generates and executes the ALTER INDEX REBUILD commands in UNRECOVERABLE mode (since that speeds up index rebuilding). If a problem is encountered during the index rebuilding operation, the script logs the Oracle error message to STDERR. and continues. You should probably run irebuild from a crontab entry at a particular time each day/week. You should also configure the maximum time allowed for the script to execute so that it is not rebuilding indexes during times when the database is available to users. When run with the debug option, irebuild will NOT rebuild the indexes, it will just generate the SQL that would be executed to STDERR. =head1 AUTHOR Brad Christensen, bradc@andrews.edu =head1 COPYRIGHT Copyright (c) 2000, Brad Christensen. All rights reserved. =head1 AVAILABILITY The latest release of irebuild can be found at http://www.andrews.edu/~bradc/irebuild/ =cut