Handling corrupt databases

The -X option lets you provide the qdb utility with a program to run when it encounters a corrupt database. If the program appears to run correctly, the database server will continue to run; the recovery program is responsible for stopping and restarting the qdb service if necessary.

The following is a sample qdb startup command with the -X option:

# qdb -X /usr/bin/recover_db.sh

Below is a sample script that can be launched by qdb when it encounters a corrupt database. You can copy the code and save it as recover_db.sh to use in the startup command.

#!/bin/ksh
# Corrupt database recovery script

# Set up some variables.
# Database (DB) name comes from argv[1], or $1.
# There is no way to automatically get the PPS object name from the
# DB name so the database PPS object name is made up of a path
# set by the system integrator and the DB name.
QDBPPSPATH=/pps/qnx/qdb/

DBNAME=$1
DBPPSCOBJ=${QDBPPSPATH}/config/${DBNAME}
DBPPSSOBJ=${QDBPPSPATH}/status/${DBNAME}
DBFILENAME=$(grep "^Filename\:\:" "${DBPPSCOBJ}" | cut -f3- -d \:)
BACKUPDIRS_STR=$(grep "^BackupDir\:\:" "${DBPPSCOBJ}" | cut -f3- -d \:)
IFS=","
set -A BACKUPDIRS_ARR -- ${BACKUPDIRS_STR}
PPSCOBJCONTENT=$(cat "${DBPPSCOBJ}" | grep -v "^@${DBNAME}\$")

# Delete the PPS object, then wait for the status object to go.
# The script waits for 2.5 seconds but continues even if the
# status object is still there; the script logs an error in this case.
DBPPSSOBJ_DELETED=0
rm ${DBPPSCOBJ}
for i in 1 2 3 4 5; do
  if [ ! -e ${DBPPSSOBJ} ]; then
    DBPPSSOBJ_DELETED=1
    break;
  fi
  sleep 0.5
done

if [ "${DBPPSSOBJ_DELETED}" -eq "0" ]; then
  echo "Status object \"${DBPPSSOBJ}\" still exists; continuing anyway."
fi

# Delete the database file and any backups. The backup deletion should 
# be customized by the integrator to delete only the appropriate backup
# filenames (for example DBNAME.gz).
# NOTE: This example doesn't consider auto-attached databases.
#       If you are using auto-attached databases or any other advanced
#       configuration, you may need to do some special handling.
rm ${DBFILENAME}
for dir in ${BACKUPDIRS_ARR[@]}; do
  rm -f ${dir}/${DBNAME} ${dir}/${DBNAME}.*
done

# Re-create the PPS configuration object.
echo "${PPSCOBJCONTENT}" > ${DBPPSCOBJ}

# EOF
Note:
  • To kill qdb without killing the script, send SIGTERM (the default for slay). This way, qdb keeps the thread used by popen() to start the script available and logs output until the script quits.
  • If you send SIGKILL, qdb is killed immediately. The script continues to run but its output is lost.
Page updated: