Perl Script Problems

Discussion in 'Perl Misc' started by, Jan 24, 2005.

  1. Guest

    Hi All, I'm a total newbie to perl but I found a script form the web
    that would automate the cloning of Oracle DB's on NT so I thought i'd
    give it a go, the problem is whenever i run it i get a badfile error, (
    found in the section that backs up Db files - think )which i'm assuming
    is becuase my path of some of my db files have a space in them, i'd
    appreciate it if anybody can give me a workaround to this


    # coldarch -- cold backup for Microsoft
    # G. Patterson, June 2002

    # WARNING ** This script SHUTS DOWN THE DATABASE! ********
    # This is the only warning!

    # Set the common parameters (contained in
    use File::Basename;
    # extract the path from $0
    $MyPath = dirname($0);
    # This file contains important site definitions
    require "$MyPath\\";
    # This determines how the database will be re-opened
    $OPEN_TYPE = 0; # 0 = Don't open, 1 = oradim, 2 = svrmgrl, 3 =


    # Write a log message to the logfile
    sub LogMsg{
    my @t = localtime(time);
    printf LOG "%04d-%02d-%02d %02d:%02d %s\n",


    # We have a problem ... cleanup and exit
    sub problem{
    LogMsg "ERROR: $_[0]";
    unlink "$lockfile";
    unlink "$stopfile";
    # hopefully we can start the database
    die "$_[0]\n";

    # -------------------------------------------------------------------
    # Run the given SQL and spool to temp.LST, because we
    # cannot redirect output from version 7 sqlplus in NT
    sub run_sql {
    # first, write the given SQL to a temp file
    open SQL,">$sqltmp" || die "cannot open $sqltmp";
    print SQL "set term off\n";
    print SQL "set echo off\n";
    print SQL "set trimspool on\n";
    print SQL "set pages 0\n";
    print SQL "set feedback off\n";
    print SQL "set verify off\n";
    print SQL "set lines 1024\n";
    print SQL "spool $tmpdir\\temp\n";
    print SQL "$_[0]\n";
    print SQL "exit\n";
    close SQL || die "$!";
    # now run it with the SQLPLUS utility
    system "$sqlplus -s $userid/$passwd\@$orasid \@$sqltmp";
    # read back the spool file and return the contents in list
    open (TMP,"$tmpdir\\temp.LST") || problem "opening temp.LST";
    my @t = (<TMP>);
    close TMP || problem "closing temp.LST";
    return( @t);


    # Run the given SQL in svrmgrl
    sub run_svrmgr {
    # construct an SQL file
    open SQL,">$sqltmp" || die "cannot open $sqltmp";
    print SQL "connect internal/$passwd\n";
    print SQL "$_[0]\n";
    print SQL "exit\n";
    close SQL || die "$!";
    # EXEC as a backticks block and return the output in list
    my @t = `$svrmgrl \@$sqltmp`;
    return( @t);

    # get list of redo logs from v_$logfile
    sub get_redo_info{
    # this should return a list of the redo logs
    my @t = run_sql "select member from v_\$logfile;";
    foreach $x (@t){
    # remove any crud from the end of the lines
    $x =~ s/\s+$//;
    push (@REDOLIST,$x) if (length($x) )


    # shutdown the database and get a copy of SQL to create control file
    sub shutdb{
    my $t; my $f; my $x; my $a;
    # run a BACKUP TO TRACE command
    my $backup_ctrl = "$coldarc\\" . uc($orasid) .
    my @t = run_svrmgr "alter system switch logfile;
    alter database backup controlfile to trace resetlogs;";
    @t = run_svrmgr "shutdown immediate;";
    LogMsg $t = `$oradim -shutdown -sid $orasid -usrpwd $passwd
    -shuttype inst,srvc -shutmode i`;
    # examine the files in USER_DUMP_DEST
    opendir (TRACE,$ORAPARM{user_dump_dest}) ||
    problem "Cannot open $ORAPARM{user_dump_dest}";
    $a = 99;
    # we want the most recent trace file ...
    while ($t = readdir TRACE){
    $x = $ORAPARM{user_dump_dest} . "\\" . $t;
    next unless ( -f $x);
    next unless ( (-M $x ) < $a);
    $f = $x;
    $a = ( -M $x )
    # save the trace file for later (the coldclone procedure)
    rename $f,$backup_ctrl || problem "Cannot move $f to

    # retrieve parameter values from v$parameter
    sub get_oraparm{
    # extract the parameters from v$parameter
    my @t = run_sql "col name format a40 trunc\ncol value format
    a512 trunc
    select name,value from v\$parameter;";
    for my $i ( 0 .. $#t){
    $t[$i] =~ s/\s+$//;
    # parse them into %ORAPARM (using parameter as a hash
    if ( $t[$i] =~ /^(\w+)/){
    $ORAPARM{$1} = $';
    $ORAPARM{$1} =~ s/^\s+//;


    # Get the list of datafiles to be backed up
    sub get_datafiles{
    my @t = run_sql "select tablespace_name, file_name, blocks+1
    from dba_data_files where status = 'AVAILABLE'
    order by tablespace_name, file_name;";
    my $j = 0;
    for my $i ( 0 .. $#t){
    my @s = split ' ',$t[$i];
    if (@s == 3){
    $DATAFILE[$j] = \@s;
    my @b = split /\\/,$DATAFILE[$j][1];
    $DATAFILE[$j++][3] = $b[$#b];
    elsif (@s > 3){
    # spit the dummy if filename contains embedded
    problem "bad file: $s[1] $s[2]";
    problem "no data files available" unless (@DATAFILE > 0);
    LogMsg sprintf "$MyName found %d data files to
    # Create a header file.
    # This is a text file that contains information about the cold archive
    # which can be used by scripts that restore from the cold archive.
    sub write_header{
    my $x;
    # gather all the necessary information
    @CTRLFILES=split /, /,$ORAPARM{control_files};
    # clobber previous backup
    unlink glob "$coldarc\\*";
    open (HDR,">$coldarc\\0header") || die "Cannot open
    # store the information in the header file
    print HDR "$MyName started at $start_str
    ORACLE_SID: $orasid
    BLOCK_SIZE: $ORAPARM{db_block_size}
    PARAM_FILE: $pfile{$orasid}\n";
    if ($ORAPARM{ifile}){
    print HDR " I FILES:\n";
    foreach $x(split (/, /,$ORAPARM{ifile})){
    print HDR "\t$x\n";
    print HDR " CTRL FILES:\n";
    foreach $x (@CTRLFILES){
    print HDR "\t$x\n";


    # create SQL for a backup control (backup to trace)
    sub backup_control_file{
    my $backup_ctrl = "$coldarc\\" . uc($orasid) . "_CTRL.FILE";
    # clobber any old versions of this file
    unlink "$backup_ctrl";
    my @t = run_sql "set feedback on
    alter database backup controlfile to '$backup_ctrl';";
    problem "Cannot backup controlfile"
    unless ( grep(/Database altered$/i,@t) );
    # use the $zipview command to verify that the backup is successful
    # this reads through the contents of the zip archive and checks
    # that the sizes match specified system size.
    # NB: This may vary from site to site. If you have actually created
    # a data file that is larger than the allocated size in the database
    # this check should be disabled.
    sub verify_backup{
    $blksz = $ORAPARM{db_block_size};
    for my $i ( 0 .. $#DATAFILE){
    my @t = `$zipview $coldarc\\$DATAFILE[$i][3].zip`;
    foreach my $x (@t){
    $x =~ s/\s+$//;
    if ($x =~ /$DATAFILE[$i][3]$/){
    $size = (split ' ',$x)[0];
    problem "suspect backup
    unless ($size == $DATAFILE[$i][2] *


    #make the output from the zipadd more pretty
    sub pretty {
    my $t = $_[0];
    $t =~ s/Deflating .*%\), done./Deflated/;


    # backup the control_file, redo logs, pfiles and ifiles
    sub backup_config(){
    my $x; my $b;
    my $dest = "$coldarc\\config.$";
    # first copy the pfile to the archive directory
    my $t = `copy $pfile{$orasid} $coldarc`;
    $t =~ s/\s+$//;
    problem "pfile: $t" unless ($t =~ /1 file\(s\) copied/);
    # add the control_file to the zip archive
    LogMsg pretty $t = `$zipadd $dest $CTRLFILES[0]`;
    foreach my $x (@REDOLIST){
    LogMsg pretty $t = `$zipadd $dest $x`;
    # copy each of the ifiles to the archive directory
    foreach $x(split (/, /,$ORAPARM{ifile})){
    $b = basename( $x);
    problem "Duplicate ifile: $b" if ( -f "$coldarc\\$b");
    $t = `copy $x $coldarc`;
    $t =~ s/\s+$//;
    problem "ifile: $t" unless ($t =~ /1 file\(s\)


    # reopen database -- called from problem(), so we must not call
    sub opendb{
    LogMsg "WARNING: Database is shutdown!" unless $OPEN_TYPE;
    LogMsg $t =
    `$oradim -startup -sid $orasid -usrpwd $passwd -starttype
    if ( $OPEN_TYPE & 1);
    run_svrmgr "startup" if ( $OPEN_TYPE & 2);


    # Main ... start here:
    # which program am I?
    $MyName = basename $0,"\.pl";
    # sanity check for command line
    die "usage: $MyName intrnl_passwd db_name\n" unless (@ARGV == 2);
    $userid = "sys";
    $passwd = $ARGV[0];
    $orasid = $ARGV[1];
    # check the environment
    # init strings for logfile
    @start = localtime(time);
    $start_str = sprintf "%04d-%02d-%02d %02d:%02d:%02d",$start[5]+1900,
    $logfile = sprintf
    $lockfile = "$logdir\\coldarch.$orasid.lock";
    $stopfile = "$logdir\\coldarch.$orasid.stop";
    die "$MyName is already running\n" if ((-f $lockfile) && (-M $lockfile
    < 1));
    # create the lockfile
    open (LOCK,">$lockfile") || die "Cannot write to $lockfile";
    print LOCK "$MyName started $start_str\n";
    close (LOCK) || die "$!";
    open(LOG,">>$logfile") || die "error opening $logfile\n";
    problem "$ORAPARM{db_name} does not match $orasid"
    unless (uc($ORAPARM{db_name}) eq uc($orasid));
    $coldarc = "$coldarc\\$ORAPARM{db_name}";
    # setup the header
    # shutdown the database, backup control_file, pfile, ifiles
    # write information about datafiles to the HEADER
    print HDR "\n DATA FILES:\n";
    for my $i ( 0 .. $#DATAFILE){
    # loop through the datafiles
    problem "$MyName Stopped!" if ( -f $stopfile);
    LogMsg "copying $DATAFILE[$i][1], $DATAFILE[$i][2] blocks";
    print HDR "\t$DATAFILE[$i][1] $DATAFILE[$i][2] blocks\n";
    LogMsg pretty $t = `$zipadd $coldarc\\$DATAFILE[$i][3].zip
    LogMsg "$MyName completed normal";
    unlink "$lockfile";
    , Jan 24, 2005
    1. Advertisements

  2. wrote:

    > Subject: Perl Script Problems

    Please put the subject of your post in the Subject of your post.

    > Hi All, I'm a total newbie to perl but I found a script form the web

    The standard answer is that you should:

    Contact the author for help.
    Learn Perl.
    Hire someone who knows Perl.

    The regulars here do not want this newsgroup to become a free "fix this
    3rd party script" service. This newsgroup is for people who want to
    discuss or learn Perl.

    Note: a quick look at that script indicates that it contains many things
    that would be severely criticised if it were posted here for code review.
    Brian McCauley, Jan 24, 2005
    1. Advertisements

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Wet Basement
    Jul 15, 2003
  2. dpackwood
  3. pj
  4. Petterson Mikael

    Execute another perl script from my perl script

    Petterson Mikael, Jan 5, 2005, in forum: Perl Misc
    Paul Lalli
    Jan 5, 2005
  5. Replies:
    Gunnar Hjalmarsson
    Jan 18, 2005

Share This Page