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)) {

Reply via email to