I havn't been able to automate a restore completely within bacula for
DB2 databases, but I've gotten close. The bacula restore process
creates a FIFO with only root permissions but doesn't change the
permissions of the actual fifo file until data starts restoring to it.
At that time though, it's too late for the DB2 process (I think the file
is actually deleted and re-created and the DB2 process loses it's handle
on it).
I've attached the script that I use, maybe it will help you. I've also
attached a patch to fd_cmds.c in the director source directory that will
allow this script to work properly (otherwise, my script can't tell if
the backup is incremental, or full, and doesn't know what to do in
either case).
Here is my job resource I use with these scripts:
Job {
Name = database-db2
JobDefs = "WeeklyFull"
Client = "tiamat2-fd"
File Set = "Database DB2"
Client Run Before Job = "su - <instance owner> -c \"/<database
directory>/backupdb.sh '%t' '%l
' '<instance owner>' '<database name>'\""
Client Run After Job = "su - <instance owner> -c \"/<database
directory>/prunelogs.sh '%t' '%l
' '<instance owner>' '<database name>'\""
Write Bootstrap = "/var/lib/bacula/database.bst"
}
Job {
Name = restore-database-db2
Type = Restore
Client = tiamat2-fd
File Set = "Database DB2"
Messages = Standard
Storage = Tape
Pool = Default
Client Run Before Job = "su - <instance owner> -c \"<database
dir>/backupdb.sh '%t' '%l
' '<instance owner>' '<database name>'\""
Client Run After Job = "su - <instance owner> -c \"<database
dir>/prunelogs.sh '%t' '%l
' '<instance owner>' '<database name>'\""
Where = "/"
}
FileSet {
Name = "Database DB2"
Include {
Options { signature=MD5; readfifo=Yes }
File = "<database dir>/dbpipe"
}
Include {
Options { signature=MD5 }
File = "<database dir>/<instance name>/NODE0000/SQL00001"
File = "<database dir>/<instance name>/NODE0000/sqldbdir"
File = "<database dir>/backupdb.sh"
File = "<database dir>/prunelogs.sh"
}
}
You will need to create a new set of these job/file resources for each
database instance you have.
If you improve these scripts at all to make a restore of a DB2 database
a bit more automated, please let me know!
Tom
[EMAIL PROTECTED] wrote:
Hi,
I'm using bacula to backup a DB2 database to a fifo.
The backup is working correctly thanks to the additions made to the
developer's documentation.
The problem I have at the moment is getting the restore process to work.
The idea was to create the fifo (using mkfifo) in the same location as
previously used then start the Db2
restore process using the usual DB2 restore db ...xxxx... commands in
the 'run client before job' option but redirecting
standard input to null and standard output and standard error to a log
file (as per the developer documentation)
While this part works, when the backed up fifo is restored it is
forced into having the attributes:
/tmp/bacula-fifo (root, bacula) prw-r-----
This means that DB2 no longer has access to the fifo and responds with
a 'Attempt to access media /tmp/bacula-fifo is denied' error.
Despite the fact the fifo is created with the following attributes
when it was backed up originally (and prior to the restore process):
/tmp/bacula-fifo (db2inst1,db2grp1) prw-rw-rw
I'm using 1.36.3 (RHEL2.1AS and RHEL3AS)
Does anyone have any ideas?
Thanks,
Best Regards,
Brett
#!/bin/sh
# Prune the log files after a successful backup
# Are we backing up or restoring?
BACKUP=${1}
# Level of the backup?
LEVEL=${2}
# Database name
DB=${3}
# Instance name
INST=${4}
# Calling Instance ID
ID=${5}
# Make sure arguments are set before continuing
if [ "${BACKUP}x" = "x" ]; then
echo "No Backup/Restore" argument
exit 1
fi
if [ "${LEVEL}x" = "x" ]; then
echo "No Level argument"
exit 1
fi
if [ "${DB}x" = "x" ]; then
echo "No Database Name"
exit 1
fi
if [ "${INST}x" = "x" ]; then
echo "No Instance Name"
exit 1
fi
DIR=`finger $INST | grep Directory | cut -d" " -f2`
if [ "${DIR}x" = "x" ]; then
echo "Instance name not correct"
exit 2
fi
. $DIR/sqllib/db2profile
rm -rf $DIR/dbpipe${ID}
# Backup section
if [ "${BACKUP}" = "Backup" ]; then
# Full or Incremental?
if [ "${LEVEL}" = "Full" ]; then
ONEWEEK=`date -d "1 week ago" "+%Y%m%d"`
# Prune the log files
db2 CONNECT TO ${DB}
db2 PRUNE HISTORY ${ONEWEEK}
fi
fi
#!/bin/sh
# Script file to backup a DB2 database to a named pipe to Bacula
#
# Are we backing up or restoring?
BACKUP=${1}
# Level of the backup?
LEVEL=${2}
# Database name
DB=${3}
# Instance name
INST=${4}
# calling instance ID
ID=${5}
# Make sure arguments are set before continuing
if [ "${BACKUP}x" = "x" ]; then
echo "No Backup/Restore" argument
exit 1
fi
if [ "${LEVEL}x" = "x" ]; then
echo "No Level argument"
exit 1
fi
if [ "${DB}x" = "x" ]; then
echo "No Database Name"
exit 1
fi
if [ "${INST}x" = "x" ]; then
echo "No Instance Name"
exit 1
fi
DIR=`finger $INST | grep Directory | cut -d" " -f2`
if [ "${DIR}x" = "x" ]; then
echo "Instance name not correct"
exit 2
fi
# Create the FIFO
rm -rf $DIR/dbpipe${ID}
mkfifo -m 660 $DIR/dbpipe${ID}
. $DIR/sqllib/db2profile
# Restore section
if [ "${BACKUP}" = "Restore" ]; then
echo "The database is ready to be restored. Change permissions of"
echo "$DIR/dbpipe${ID} and issue a 'db2 RESTORE DATABASE $DB FROM
$DIR/dbpipe${ID}'"
# db2 RESTORE DATABASE ${DB} FROM $DIR/dbpipe${ID} INTO ${DB} REPLACE EXISTING
WITHOUT PROMPTING > $DIR/restore.log 2>&1 < /dev/null &
# sleep 1
else
# Backup section
if [ "${LEVEL}" = "Full" ]; then
db2 FORCE APPLICATION ALL
sleep 1
db2 BACKUP DATABASE ${DB} TO $DIR/dbpipe${ID} WITHOUT PROMPTING >
$DIR/backup.log 2>&1 < /dev/null &
sleep 1
else
db2 CONNECT TO ${DB}
db2 BACKUP DATABASE ${DB} ONLINE TO $DIR/dbpipe${ID} WITHOUT PROMPTING >
$DIR/backup.log 2>&1 < /dev/null &
sleep 1
fi
fi
exit 0
--- ../../../bacula-1.36.3-pre1/src/dird/fd_cmds.c 2005-02-14
03:02:21.000000000 -0700
+++ fd_cmds.c 2005-04-14 00:29:10.000000000 -0600
@@ -591,6 +591,7 @@
BSOCK *fd = jcr->file_bsock;
if (jcr->job->ClientRunBeforeJob) {
- pm_strcpy(msg, jcr->job->ClientRunBeforeJob);
+ pm_strcpy(msg, edit_job_codes(jcr, msg, jcr->job->ClientRunBeforeJob);
bash_spaces(msg);
bnet_fsend(fd, runbefore, msg);
if (!response(jcr, fd, OKRunBefore, "ClientRunBeforeJob",
DISPLAY_ERROR)) {
@@ -600,6 +600,6 @@
}
if (jcr->job->ClientRunAfterJob) {
- fd->msglen = pm_strcpy(msg, jcr->job->ClientRunAfterJob);
+ fd->msglen = pm_strcpy(msg, edit_job_codes(jcr, msg,
jcr->job->ClientRunAfterJob, ""));
bash_spaces(msg);
bnet_fsend(fd, runafter, msg);
if (!response(jcr, fd, OKRunAfter, "ClientRunAfterJob", DISPLAY_ERROR)) {