Dangit! The last version that I sent out had valid email address in
it. Please either change them, or use this new version! (Sorry, Eric and
Craig...) ;) Doh!
Alright. Thanks to the help of various people on this list, I believe that
I have developed the (beginnings of the) a really nice NetBackup Database
(catalog) backup script. It slices, it dices... This version is bourne
shell and only supports Unix masters, but it should support NT media
servers. If the demand is there, I'll work on a perl version that will
support NT Masters.
Here's what it can do:
1. Automatically grab a tape from the Scratch pool to backup the database too.
2. Move that tape into a separate pool that you determine
3. Automatically create the database paths to be backed up, including
supporting
the workaround for databases bigger than a tape!
4. Waits for up to three hours for jobs to stop
5. Stops bprd
6. Runs the bpbackupdb with the approprate volume and database paths
7. Restarts bprd
8. Runs the bpbackup command with a special class to back up the rest of the
database (if you're using the "big database" workaround).
Once it's backed up the database, you have two choices:
1. It can eject the tape or leave it in the library without doing anything
else.
2. It can also keep a "set" of database backup tapes in the library, returning
the oldest tape back to the Scratch pool.
In order to use this script, you need to:
1. Have a Scratch pool defined and have at least one tape in it.
2. Have a tape library that's operational.
3. Have a class defined to back up the rest of the database.
(If you're going to use the big database workaround.)
4. Change the variables at the top of the script to their appropriate values.
5. If you want it to support your NT media servers, you'll need to:
a. Have NetBackup installed in <drive>:\Veritas or
<drive>:\progra~1\Veritas
b. If you have it in some other location, you'll need to edit line 242
and add the
paths that you want it to check.
c. Test it! (I have no NT media servers to test against.)
The script's not perfect, but I think you'll like it. Why don't you try it
and let me know what else it needs?
-----------------------------------------cut----------------------------------------
#!/bin/sh
set -x
## Rcs_ID="$RCSfile: backupdb.sh,v $"
## Rcs_ID="$Revision: 1.0 $ $Date: 2001-01-24 23:51:54-08 $"
######################################
#Site-specific configuration section #
#Change these variables to the #
#appropriate values for your site #
######################################
#The number of the robot containing the scratch pool
robot_num=0
#The number of the database backup pool
db_pool=NBDB_Backups
#The "density" setting of the media that will be used
voltype=dlt
#Where will we store the db-backup-tapes.txt file
datadir=/usr/openv/local/data
#Where will we store the logs of this script
logdir=/usr/openv/netbackup/logs/dbbackup
#For the newest backup tape, the script will always grab a tape from
#the scratch pool. Once it's done with the db backup to the new tape,
#it can do a number of things:
#1. It can cycle through a "set" of db backup tapes, returning the oldest one
# back to the scratch pool. It can also optionally relabel the tape
# that is being returned to the scratch pool to overwrite the db backup
# label. To cycle through tapes like this, set numdbtapes to a number
# higher than 0. Once the number of db backup tapes gets above this
# number, it will return the oldest one to the Scratch pool. If you
# want it to relabel the tape, set relabel to YES.
# If you are using this feature and keeping a "set" of backup tapes,
# but you are manually ejecting them through some other means,
# then you should set relabel to NO. Otherwise, the program will
# try to relabel a tape that is not in the library.
#2. If you don't want it to cycle through the tapes like this, set
# numdbtapes to 0. It will keep grabbing a new tape from Scratch, but
# will not return the tapes it has used to Scratch. If you are doing
# this, you can also eject the tape from the library when it is done.
# To do this, set auto_eject to YES.
#
#Set to a number higher than 0 to keep a "set" of backup tapes
numdbtapes=3
#If keeping a set of backup tapes, then you can have the oldest relabeled
#when it is returned to the scratch pool. To do so, then set relabel to YES.
relabel=YES
#If you are not keeping a set of tapes, you can have this script eject
#the tape when it's done. To do so, set auto_eject to YES.
auto_eject=NO
#If you are auto-ejecting the db backup tape, set this to the name of
#the offsite volume group
volume_group=Offsite
#Set this to NULL to not mail the results, or set it to an email address
#to mail the results.
nbu_admin=root
#If you want, you can manually the set name of the master
master=`head -1 /usr/openv/netbackup/bp.conf |awk '{print $3}'`
#If the variable below is set to YES, then the path list for the bpbackupdb
#command will only contain the server's index from
/usr/openv/netbackup/db/image
#(as well as all the other directories in /usr/openv/netbackup/db.)
#This is the workaround for databases that are bigger than a tape
masters_catalog_only=YES
#The name of a class that has a manual backup schedule that this script
#can use. This is needed only if the masters_catalog_only variable is
#set to YES.
class=Test
#############################################
#END of Site-specific configuration section #
#############################################
tmp=/var/tmp
X=$$
servers=`bpstulist -l |awk '{print $3}'|sort -u|grep -v $master`
[ -d $logdir ] || mkdir -p $logdir
cd $logdir
find . -name "backupdb.*.log" -mtime +30 -exec rm {} \;
exec >$logdir/backupdb.$$.log 2>&1
PATH=/bin:/usr/bin:/usr/sbin:/sbin:/usr/openv/volmgr/bin:/usr/openv/netbackup/bin:
/usr/openv/netbackup/bin/admincmd:/usr/openv/netbackup/bin/goodies:/usr/openv/volm
gr/goodies:/usr/symmapps/bin:/usr/local/bin:/usr/openv/local/bin:/etc
export PATH
Exit() {
if [ -n "$ERROR" ] ; then
echo "ERROR:" >$tmp/$$.mail
echo $ERROR >>$tmp/$$.mail
cat $tmp/$$.errors >>$tmp/$$.mail
if [ -n "$nbu_admin" ] ; then
cat $tmp/$$.mail |mailx -s "NBU DB Backup FAILURE!" $nbu_admin
fi
else
if [ -n "$nbu_admin" ] ; then
cat $tmp/$$.log |mailx -s "NBU DB Backup Success" $nbu_admin
fi
fi
exit
rm $tmp/$$.*
}
db_pool_num=`vmpool -listall \
|awk '$0 ~ /pool number/ { printf $0 } $0 ~ /pool name/ { print $0
}' \
|grep $db_pool|sed 's/pool name.*//'|sed 's/.* //'`
#Identify scratch pool from VM.CONF
scratch_pool=`grep SCRATCH_POOL /usr/openv/volmgr/vm.conf |awk '{print $3}'`
if [ -z "$scratch_pool" ] ; then
ERROR="Could not identify scratch pool."
Exit
fi
scratch_pool_num=`vmpool -listall \
|awk '$0 ~ /pool number/ { printf $0 } $0 ~ /pool name/ { print $0 }' \
|grep $scratch_pool|sed 's/pool name.*//'|sed 's/.* //'`
#Identifies all volumes in the robot numbers current volume database and
#redirects to outfile
vmquery -b -rn $robot_num | egrep -v '^media|^ *ID|^-------' |awk '{print
$1}' \
>$tmp/$$.tapesinrobot 2>$tmp/$$.errors
if [ ! -s $tmp/$$.tapesinrobot ] ; then
ERROR="Could not find any tapes in the robot!"
Exit
fi
#Identifies all volumes that are a part of the Scratch pool on robot_num and
#assigns to volids
volids=`vmquery -b -pn $scratch_pool | egrep -v '^media|^ *ID|^-------' \
|awk '{print $1}'`
if [ -z "$volids" ] ; then
ERROR="There are no tapes left in the Scratch Pool!"
Exit
fi
#For each volid in volids check to see if the tape is part of the
#scratch pool and in the robot, if true break
for volid in $volids ; do
grep $volid $tmp/$$.tapesinrobot >/dev/null
[ $? -eq 0 ] && involids="$involids $volid"
done
if [ -z "$involids" ] ; then
ERROR="There are no Scratch tapes in robot $robot_num!"
Exit
fi
for volid in $involids ; do
vmchange -p $db_pool_num -m $volid 2>$tmp/$$.errors
if [ $? -gt 0 ] ; then
MYERROR=1
continue
fi
# find out how many currently queued, re-queued, or active jobs
# there are currently
TOTAL=1
COUNT=0
while [ $TOTAL -gt 0 ] ; do
TOTAL=`bpdbjobs -report |egrep -c 'QUEUED|ACTIVE'`
[ $TOTAL -eq 0 ] && break
sleep 600
COUNT=`expr $COUNT + 1`
if [ $COUNT -gt 36 ] ; then
ERROR="Giving up after 6 hours. Could not find an inactive time to
backup the database."
Exit
fi
done
#Stop the request daemon
echo "Stopping the request Daemon"
bprdreq -terminate
echo "bprd Daemon terminated"
tpreq -rv $volid -a w -d $voltype -p $db_pool -f $tmp/$X.mount.txt
if [ $? -gt 0 ] ; then
MYERROR=1
echo "Restarting request daemon"
bprd
continue
fi
if [ "$masters_catalog_only" = "YES" -o "$masters_catalog_only" = "yes" ]
then
for path in `ls -d /usr/openv/netbackup/db/*|grep -v images` ; do
[ -z "$db_paths" ] && db_paths=$path || db_paths="$db_paths $path"
done
else
[ -z "$db_paths" ] && db_paths=$path || db_paths="/usr/openv/netbackup/db"
fi
if [ "$masters_catalog_only" = "YES" ] ; then
if [ -d /usr/openv/netbackup/db/images/$master ] ; then
db_paths="$db_paths /usr/openv/netbackup/db/images/$master"
else
#Complain loudly!
ERROR="Master's name does not match a directory in
/usr/openv/netbackup/db/images!"
Exit
fi
fi
db_paths="$db_paths /usr/openv/volmgr/database"
for server in $servers ; do
if [ "$server" = "$master" ] ; then
continue
fi
if [ -z "`bpclclients |awk '$2 ~ /Windows.NT/ { print $3 }'|grep
$server`" ]
then
#Treat it like a UNIX host
db_paths="$db_paths $server:/usr/openv/netbackup/db/media"
db_paths="$db_paths $server:/usr/openv/volmgr/database"
else
for drive in C D E F H I J K L M N O P Q R S T U V W X Y Z ; do
for path in "Veritas" "progra~1/Veritas" ; do
bpgp from $server /$drive/$path/bin/bpcd.exe $tmp/bpcd.exe
2>/dev/null
if [ $? -eq 0 ] ; then
path=`echo $path|sed 's-/-\\-g'`
install_path="$drive:$path"
break
fi
done
done
if [ -n "$install_path" ] ; then
db_paths="$db_paths $server:$install_path\\NetBackup\\db"
db_paths="$db_paths $server:$install_path\\Volmgr\\database"
else
ERROR="Could not locate NetBackup installation on NT media server:
$server!"
Exit
fi
fi
done
#Tpreq makes a file that's a symbolic link to the real drive, right?
#If not, what does the file look like? What does it look like on NT?
device=`ls -l $tmp/$X.mount.txt|awk '{print $11}'`
# Run netbackup database backup
echo "bpbackupdb -tpath $device -rv $volid $db_paths"
bpbackupdb -tpath $device -rv $volid $db_paths
if [ $? -gt 0 ] ; then
MYERROR=1
tpunmount -f $tmp/$X.mount.txt -force
echo "Restarting request daemon"
bprd
else
echo "Database backup complete"
MYERROR=0
tpunmount -f $tmp/$X.mount.txt -force
assigntime=`bpdbjobs -report -all_columns |cut -c1-300\
|awk -F',' '{print $9}'|sort -n|tail -1`
vmquery -assignbyid $volid $voltype $db_pool_num 0 $assigntime
# restart request daemon
echo "Restarting request daemon"
bprd
if [ "$masters_catalog_only" = "YES" ] ; then
#Now that bprd is back up, we can run the backup of the rest of the
database
#This section will only get run if you are using the workaround for
#databases larger than a tape
includes="/usr/openv/netbackup/db/class/$class/includes"
echo "/usr/openv/netbackup/db" >$includes
echo "/usr/openv/volmgr/database" >>$includes
/usr/openv/netbackup/bin/bpbackup -i -w -c $class
if [ $? -gt 0 ] ; then
MYERROR=1
echo "The backup of the rest of the NBU Database failed!"
fi
fi
break
fi
done
if [ $MYERROR -gt 0 ] ; then
ERROR="Could not backup NetBackup database AT ALL!"
Exit
else
DATE=`date`
echo "$DATE: \c"
echo "Backed up database to volume $volid\n" \
|tee -a $tmp/$$.log
echo $volid >>$datadir/db-backup-tapes.txt
fi
if [ $numdbtapes -eq 0 ] ; then
if [ "$auto_eject" = YES ] ; then
#If the number of db tapes is set to 0, and we're supposed to eject
#automatically, then eject the db backup tape out of the library
volid=`tail -1 $datadir/db-backup-tapes.txt`
eject_cmd="vmchange -vh $master -res -m $volid -mt $voltype -rt none -v
$volume_group -rc1 0 -rc2 0 -e -sec 5"
$eject_cmd
if [ $? -gt 0 ] ; then
ERROR="Could not eject $volid with command \"$eject_cmd\"!"
Exit
fi
fi
else
DBTAPES=`grep -c . $datadir/db-backup-tapes.txt`
while [ $DBTAPES -gt "$numdbtapes" ] ; do
TAPE=`head -1 $datadir/db-backup-tapes.txt`
echo "There are over $numdbtapes database backup tapes: Relabeling $TAPE." \
|tee -a $tmp/$$.log
vmquery -deassignbyid $TAPE $db_pool_num 0
if [ $? -gt 0 ] ; then
ERROR="Could not deassign $TAPE with command \"vmquery -deassignbyid
$TAPE $db_pool_num 0\"!"
Exit
fi
vmchange -p $scratch_pool_num -m $TAPE 2>$tmp/$$.errors
if [ $? -gt 0 ] ; then
ERROR="Could not move $TAPE into scratch pool with command \"vmchange
-p $scratch_pool_num -m $TAPE\"!"
Exit
fi
if [ "$relabel" = YES ] ; then
bplabel -ev $TAPE -d $voltype -p $scratch_pool -o 2>$tmp/$$.errors
if [ $? -gt 0 ] ; then
ERROR="Could not label $TAPE with command \"bplabel -ev $TAPE -d
$voltype -p $scratch_pool -o\"!"
Exit
fi
fi
grep -v "^$TAPE$" $datadir/db-backup-tapes.txt >$tmp/$$.X
mv $tmp/$$.X $datadir/db-backup-tapes.txt
DBTAPES=`grep -c . $datadir/db-backup-tapes.txt`
done
echo "
This is the current list of database backup tapes in the
order they were created:" |tee -a $tmp/$$.log
cat $datadir/db-backup-tapes.txt |tee -a $tmp/$$.log
Exit
fi
done
if [ -n "$install_path" ] ; then
db_paths="$db_paths $server:$install_path\\NetBackup\\db"
db_paths="$db_paths $server:$install_path\\Volmgr\\database"
else
ERROR="Could not locate NetBackup installation on NT media server:
$server!
"
Exit
fi
fi
done
#Tpreq makes a file that's a symbolic link to the real drive, right?
#If not, what does the file look like? What does it look like on NT?
device=`ls -l $tmp/$X.mount.txt|awk '{print $11}'`
# Run netbackup database backup
echo "bpbackupdb -tpath $device -rv $volid $db_paths"
bpbackupdb -tpath $device -rv $volid $db_paths
if [ $? -gt 0 ] ; then
MYERROR=1
tpunmount -f $tmp/$X.mount.txt -force
echo "Restarting request daemon"
bprd
else
echo "Database backup complete"
MYERROR=0
tpunmount -f $tmp/$X.mount.txt -force
assigntime=`bpdbjobs -report -all_columns |cut -c1-300\
|awk -F',' '{print $9}'|sort -n|tail -1`
vmquery -assignbyid $volid $voltype $db_pool_num 0 $assigntime
# restart request daemon
echo "Restarting request daemon"
bprd
if [ "$masters_catalog_only" = "YES" ] ; then
#Now that bprd is back up, we can run the backup of the rest of the
database
#This section will only get run if you are using the workaround for
#databases larger than a tape
includes="/usr/openv/netbackup/db/class/$class/includes"
echo "/usr/openv/netbackup/db" >$includes
echo "/usr/openv/volmgr/database" >>$includes
/usr/openv/netbackup/bin/bpbackup -i -w -c $class
if [ $? -gt 0 ] ; then
MYERROR=1
echo "The backup of the rest of the NBU Database failed!"
fi
fi
break
fi
done
if [ $MYERROR -gt 0 ] ; then
ERROR="Could not backup NetBackup database AT ALL!"
Exit
else
DATE=`date`
echo "$DATE: \c"
echo "Backed up database to volume $volid\n" \
|tee -a $tmp/$$.log
echo $volid >>$datadir/db-backup-tapes.txt
fi
if [ $numdbtapes -eq 0 ] ; then
if [ "$auto_eject" = YES ] ; then
#If the number of db tapes is set to 0, and we're supposed to eject
#automatically, then eject the db backup tape out of the library
volid=`tail -1 $datadir/db-backup-tapes.txt`
eject_cmd="vmchange -vh $master -res -m $volid -mt $voltype -rt none -v
$volume_
group -rc1 0 -rc2 0 -e -sec 5"
$eject_cmd
if [ $? -gt 0 ] ; then
ERROR="Could not eject $volid with command \"$eject_cmd\"!"
Exit
fi
fi
else
DBTAPES=`grep -c . $datadir/db-backup-tapes.txt`
while [ $DBTAPES -gt "$numdbtapes" ] ; do
TAPE=`head -1 $datadir/db-backup-tapes.txt`
echo "There are over $numdbtapes database backup tapes: Relabeling $TAPE." \
|tee -a $tmp/$$.log
vmquery -deassignbyid $TAPE $db_pool_num 0
if [ $? -gt 0 ] ; then
ERROR="Could not deassign $TAPE with command \"vmquery -deassignbyid
$TAPE $db_
pool_num 0\"!"
Exit
fi
vmchange -p $scratch_pool_num -m $TAPE 2>$tmp/$$.errors
if [ $? -gt 0 ] ; then
ERROR="Could not move $TAPE into scratch pool with command \"vmchange
-p $scrat
ch_pool_num -m $TAPE\"!"
Exit
fi
if [ "$relabel" = YES ] ; then
bplabel -ev $TAPE -d $voltype -p $scratch_pool -o 2>$tmp/$$.errors
if [ $? -gt 0 ] ; then
ERROR="Could not label $TAPE with command \"bplabel -ev $TAPE -d
$voltype -p $
scratch_pool -o\"!"
Exit
fi
fi
grep -v "^$TAPE$" $datadir/db-backup-tapes.txt >$tmp/$$.X
mv $tmp/$$.X $datadir/db-backup-tapes.txt
DBTAPES=`grep -c . $datadir/db-backup-tapes.txt`
done
echo "
This is the current list of database backup tapes in the
order they were created:" |tee -a $tmp/$$.log
cat $datadir/db-backup-tapes.txt |tee -a $tmp/$$.log
Exit
fi
|