IBM Informix includes ON-Bar and ontape utilities to back up and restore database server data. These utilities enable you to recover your databases after data is lost or becomes corrupted due to hardware or software failure or accident. It also includes tools for data transport like dbexport and dbimport.

1 ontape

Create the following directory to save shell scripts:

Copy
mkdir /CONFIG/SCRIPTS

Create a file named dbs_ontape.sh

Copy
cat > dbs_ontape.sh

And paste the following code:

Copy
#!/bin/sh
# ======================================================================
# Sample ontape shell script
# ======================================================================

INFORMIXDIR=${INFORMIXDIR:-`grep "^informix:" /etc/passwd | awk -F: '{ print $6 }'`}
INFORMIXSERVER=${INFORMIXSERVER:-`uname -n|awk -F'.' '{print $1}'`}
DB_LOCALE=${DB_LOCALE:-es_es.8859-1}
CLIENT_LOCALE=${CLIENT_LOCALE:-es_es.8859-1}
DBDATE=${DBDATE:-DMY4-}
ONCONFIG=${ONCONFIG:-onconfig}

export INFORMIXDIR INFORMIXSERVER DB_LOCALE CLIENT_LOCALE DBDATE ONCONFIG

STATUS=OK
MOTIVE=""
LOGSYS=/usr/tmp/`basename $0 .sh`.`date +%w`.log

# Usage message.
usage () {
   STATUS=ERROR
   MOTIVE="Usage: `basename $0` --level <0|1|2> \
                                [--daysaved <value>] \
                                [--monthsave <value>] \
                                [--monthdir <value>] \
                                [--mailto <"user1@domain.es,user2@domain.es,...">] \
                                [--mailerror <"user1@domain.es,user2@domain.es,...">]"
   echo >> $LOGSYS
   echo "Error: $1" >> $LOGSYS
   echo >> $LOGSYS
   echo $MOTIVE >> $LOGSYS
   exit 1
}

#send email
do_mail ()
{
   cat -v $LOGSYS | mail -s "$STATUS `basename $0` at `date`" -r `hostname` $1
}

# ************************************************************************
#
# Main
#
# ************************************************************************
#Check log file is current day
if [ -f $LOGSYS ]; then
   CHECKLOG=`find $LOGSYS -daystart -mtime -1 -print`
   if [ -z $CHECKLOG ]; then
        cat /dev/null > $LOGSYS
   fi
fi

echo "#% "                                                    >>$LOGSYS
echo "#% START"                                               >>$LOGSYS
echo "#% name: `basename $0 .sh`"                             >>$LOGSYS
echo "#% desc: Executes ontape database backup"               >>$LOGSYS
echo "#% "                                                    >>$LOGSYS
echo "#% host: `uname -n`"                                    >>$LOGSYS
echo "#% date: `date +%d-%m-%Y`"                              >>$LOGSYS
echo "#% time: `date +%H:%M`"                                 >>$LOGSYS
echo "#% "                                                    >>$LOGSYS
echo " "                                                      >>$LOGSYS

# -------------------------------------------------------------------
# Parse and verify arguments
# -------------------------------------------------------------------
#Print argument
echo "Arguments:" >> $LOGSYS
echo $* >> $LOGSYS
echo >> $LOGSYS
echo >> $LOGSYS

#default value
DAYSAVED=6
MOYSAVE=NO

while echo $1 | grep ^- > /dev/null; do
    case $1 in
       --mailto|--mailerror|--level|--daysaved|--monthsave|--monthdir)
           eval $( echo $1 | tr 'a-z' 'A-Z' | sed 's/-//g' | tr -d '\012')=\$2;;
       --) break;;
       -*) usage "unknown argument: $1";;
        *) break;;
    esac
    shift
    shift
done

#Required params
REQPARAMS=( level )
for PARAM in "${REQPARAMS[@]}" ; do
   arg=`echo $PARAM | tr 'a-z' 'A-Z'`
   if [ -z ${!arg} ]; then
      usage "missing argument --$PARAM"
   fi
done

#CHECK MOYSAVE
MONTH=`date +\%m`
NUMMONTH=$((10#$MONTH + 0))
for VAL1 in `echo $MONTHSAVE | tr "," "\n"`; do
   NUM1=$((VAL1+0));
   if [ $NUM1 -eq $NUMMONTH ]; then
      MOYSAVE=YES
      break
   fi
   i=0
   LVAL=-1
   RVAL=-1
   for VAL2 in `echo $VAL1 | tr "-" "\n"`; do
       NUM2=$((VAL2+0))
       if [ $i -eq 0 ]; then
          LVAL=$NUM2;
       fi
       if [ $i -eq 1 ]; then
          RVAL=$NUM2;
          break
       fi
       i=$((i+1));
   done
   if [ $LVAL -ne -1 ] && [ $RVAL -ne -1 ]; then
      if [ $NUMMONTH -ge $LVAL ] && [ $NUMMONTH -le $RVAL ]; then
         MOYSAVE=YES
         break
      fi
   fi
done

#
# The database must be On-Line in order to act
#
echo "Verificando que el estado de IBM-IDS es Online..." >> $LOGSYS
su informix -c "$INFORMIXDIR/bin/onstat -" >/dev/null 2>&1
rc=$?
#
# onstat return codes:
#    0 = Initialization
#    1 = Quiescent
#    2 = Fast Recovery
#    3 = Archive Backup
#    4 = Shutting Down
#    5 = Online
#    6 = System Aborting
#  127 = Online (IDS 9.X)
#

if [ $rc -ne 5 -a $rc -ne 127 -a $rc -ne 255 ]; then
    echo "IBM-IDS is not On-Line... rc= $rc" >> $LOGSYS
    STATUS=ERROR
else
   SERVERNUM=`su - informix -c "onstat -c" | grep "^SERVERNUM" | awk '{ print $2 }'`
   TAPEDEV=`su - informix -c "onstat -c" | grep "^TAPEDEV" | awk '{ print $2 }'`
   if [ ! -d $TAPEDEV ]; then
      echo "***** ERROR $TAPEDEV should be an existing folder." >>$LOGSYS
      echo "***** ONTAPE -L $LEVEL Aborted"                     >>$LOGSYS
      STATUS=ERROR
      MOTIVE="$TAPEDEV should be an existing folder."
   fi
   if [ "$STATUS" = "OK" ]; then
        su informix -c "$INFORMIXDIR/bin/ontape -s -L $LEVEL -d" >>$LOGSYS 2>&1
        if [ $? -ne 0 ]; then
            STATUS=ERROR
            echo "***** ERROR ontape -s -L $LEVEL" >>$LOGSYS
        else
            if [ $LEVEL -eq 0 ]; then
                echo "Eliminando copias anteriores..." >> $LOGSYS
                cd /tmp; find $TAPEDEV -maxdepth 1 -name "*L?" -ctime +$DAYSAVED -print -exec rm "{}" \; >> $LOGSYS 2>&1
                
                ######### TODO:
                ######### IT IS MORE ACCURATE TO USE THE newermt
                #########
                ######### cd /tmp; find $TAPEDEV -maxdepth 1 -name "*L?" \! \( -newermt ''${HOURSAVED}' hours ago' \) -print -exec rm "{}" \; >> $LOGSYS 2>&1
            fi
            #Monthly Backup
            if [ "$MOYSAVE" = "YES" ]; then
               if [ -z "$MONTHDIR" ]; then
                   TAPEMOY=$TAPEDEV/MOY/$MONTH
               else                         
                   TAPEMOY=$MONTHDIR/$MONTH
               fi                                          
               
               if [ ! -d $TAPEMOY ]; then
                  mkdir -p $TAPEMOY
               else
                  rm -f $TAPEMOY/*L$LEVEL
               fi
              su informix -c "cp $TAPEDEV/${HOSTNAME}_${SERVERNUM}_L$LEVEL $TAPEMOY/" >> $LOGSYS 2>&1
            fi
        fi
   fi
fi

echo ""                                                    >>$LOGSYS
echo "#% status: $STATUS"                                  >>$LOGSYS
echo "#% motive: $MOTIVE"                                  >>$LOGSYS
echo "#% enddate: `date +%d-%m-%Y`"                        >>$LOGSYS
echo "#% endtime: `date +%H:%M`"                           >>$LOGSYS
echo ""                                                    >>$LOGSYS
echo "END $STATUS `basename $0 .sh` `date` "               >>$LOGSYS
echo "===================================================" >>$LOGSYS

# ************************************************************************
# We send the result of the process to the administrator via e-mail. 
# In this way we make sure that the administrator always knows
# if the process i executed correctly or not.
# For this you have to make sure that the equipment can do mail relay.
# ************************************************************************
if [ -n "$MAILTO" ]; then
     do_mail $MAILTO
fi
if [ -n "$MAILERROR" ] && [ "$STATUS" != "OK" ]; then
     do_mail $MAILERROR
fi

# END dbs_ontape

Backup filesystem

It is recommended to have a disk partition exclusively for backups, mounted on /backup1.

Create the IFMX-ONTAPES subdirectory:

Copy
cd /backup1
Copy
mkdir /backup1/IFMX-ONTAPES

Change the owner and group to informix:

Copy
chown informix:informix IFMX-ONTAPES

Give it the following permissions:

Copy
chmod 775 IFMX-ONTAPES

Check that the parameter of the onconfig TAPEDEV file has as value ehis directory:

Copy
TAPEDEV /backup1/IFMX-ONTAPES

Comprimir ontape

It is recommended to configure the Informix server to compress the ontapes, assigningg the value '/usr/bin/pigz -p 4' to the configuration parameter BACKUP_FILTER. And by symmetry, the value '/usr/bin/pigz -d -p 4' in the RESTORE_FILTER.

Finally add in the root crontab the following executions of the shell script dbs_ontape:

Copy
crontab -e
Copy
00  6 * * * /CONFIG/SCRIPTS/dbs_ontape.sh --level 0 --mailto “sysadmin@empresa.es"
00 15 * * * /CONFIG/SCRIPTS/dbs_ontape.sh --level 1
00 19 * * * /CONFIG/SCRIPTS/dbs_ontape.sh --level 2

Where sysadmin@empresa.es must be replaced by the email address of the system administrator responsible for the installation. Hours are approximate. It's about having a complete backup before rhe users start the workday. Having a first incremental backup at noon. And a second incremental backup at the enf of the day.

2 Logical logs

Create the IFMX-LBACKUP subdirectory:

Copy
cd /backup1
Copy
mkdir /backup1/IFMX-LBACKUP

Change the owner and group to informix:

Copy
chown informix:informix IFMX-LBACKUP

Give it the following permissions:

Copy
chmod 775 IFMX-LBACKUP

And check that the parameter of the onconfig file have this directory

Copy
LTAPEDEV /backup1/IFMX-LBACKUP

3 dbexport

The dbexport and dbimport utilities import and export a database and its schema to disk or tape.

The dbexport utility unloads an entire database into text files and creates a schema file. You can unload the database and its schema file either to disk or tape. If you prefer, you can unload the schema file to disk and unload the data to tape. You can use the schema file with the dbimport utility to re-create the database schema in another IBM® Informix® environment, and you can edit the schema file to modify the database that dbimport creates.

The dbimport utility creates a database and loads it with data from text files on tape or disk. The input files consist of a schema file that is used to re-create the database and data files that contain the database data. Normally, you generate the input files with the dbexport utility, but you can use any properly formatted input files.

3.1 Sample usage

Create a file named dbs_export.sh in the /CONFIG/SCRIPTS directory

Copy
cat > dbs_export.sh

And paste the following code:

Copy
#!/bin/sh
# ======================================================================
# Sample dbexport shell script
# ======================================================================

INFORMIXDIR=${INFORMIXDIR:-`grep "^informix:" /etc/passwd | awk -F: '{ print $6 }'`}
INFORMIXSERVER=${INFORMIXSERVER:-`uname -n|awk -F'.' '{print $1}'`}
DB_LOCALE=${DB_LOCALE:-es_es.8859-1}
CLIENT_LOCALE=${CLIENT_LOCALE:-es_es.8859-1}
DBDATE=${DBDATE:-DMY4-}
export INFORMIXDIR INFORMIXSERVER DB_LOCALE CLIENT_LOCALE DBDATE

STATUS=OK
MOTIVE=""
LOGSYS=/usr/tmp/`basename $0 .sh`.`date +%w`.log

INFORMIXVER=`${INFORMIXDIR}/bin/onstat -version | grep  "Build Version" | awk '{ print $3 }'`

# Usage message.
usage () {
   STATUS=ERROR
   MOTIVE="Usage: `basename $0` [--direxport <path-dir>] \
                                [--dbsexclude <"'db1','db2',...">] \
                                [--dbsinclude <"'db1','db2',...">] \
                                [--restartdbs] \
                                [--monthsave <value>] \
                                [--monthdir <value>] \
                                [--mailto <"user1@domain.es,user2@domain.es,...">] \
                                [--mailerror <"user1@domain.es,user2@domain.es,...">]"
   echo >> $LOGSYS
   echo "Error: $1" >> $LOGSYS
   echo >> $LOGSYS
   echo $MOTIVE >> $LOGSYS
   exit 1
}

#send email
do_mail ()
{
   cat -v $LOGSYS | mail -s "$STATUS `basename $0` at `date`" -r `hostname` $1
}

# ************************************************************************
#
# Main
#
# ************************************************************************
#Check log file is current day
if [ -f $LOGSYS ]; then
   CHECKLOG=`find $LOGSYS -daystart -mtime -1 -print`
   if [ -z $CHECKLOG ]; then
        cat /dev/null > $LOGSYS
   fi
fi
echo "#% "                                                    >>$LOGSYS
echo "#% START"                                               >>$LOGSYS
echo "#% name: `basename $0 .sh`"                             >>$LOGSYS
echo "#% desc: Export databases to ascii files"               >>$LOGSYS
echo "#% "                                                    >>$LOGSYS
echo "#% host: `uname -n`"                                    >>$LOGSYS
echo "#% date: `date +%d-%m-%Y`"                              >>$LOGSYS
echo "#% time: `date +%H:%M`"                                 >>$LOGSYS
echo "#% "                                                    >>$LOGSYS
echo " "                                                      >>$LOGSYS

# -------------------------------------------------------------------
# Parse and verify arguments
# -------------------------------------------------------------------
echo "Arguments:" >> $LOGSYS
echo $* >> $LOGSYS
echo >> $LOGSYS
echo >> $LOGSYS

#default value
DIREXPORT=/backup/IFMX-EXPORTS/`date +%w`
DBSEXCLUDE="\"\""
RESTARTDBS=N
MOYSAVE=NO

while echo $1 | grep ^- > /dev/null; do
    case $1 in
       --mailto|--mailerror|--direxport|--dbsexclude|--dbsinclude|--monthsave|--monthdir)
           eval $( echo $1 | tr 'a-z' 'A-Z' | sed 's/-//g' | tr -d '\012')=\$2;shift;shift;;
       --restartdbs)
           RESTARTDBS=Y;shift;;
       --) break;shift;shift;;
       -*) usage "unknown argument: $1";;
        *) break;shift;shift;;
    esac
done

#######################################################
# Main
#######################################################
#CHECK MOYSAVE
MONTH=`date +\%m`
NUMMONTH=$((10#$MONTH + 0))
for VAL1 in `echo $MONTHSAVE | tr "," "\n"`; do
   NUM1=$((VAL1+0));
   if [ $NUM1 -eq $NUMMONTH ]; then
      MOYSAVE=YES
      break
   fi
   i=0
   LVAL=-1
   RVAL=-1
   for VAL2 in `echo $VAL1 | tr "-" "\n"`; do
       NUM2=$((VAL2+0))
       if [ $i -eq 0 ]; then
          LVAL=$NUM2;
       fi
       if [ $i -eq 1 ]; then
          RVAL=$NUM2;
          break
       fi
       i=$((i+1));
   done
   if [ $LVAL -ne -1 ] && [ $RVAL -ne -1 ]; then
      if [ $NUMMONTH -ge $LVAL ] && [ $NUMMONTH -le $RVAL ]; then
         MOYSAVE=YES
         break
      fi
   fi
done

if [ ! -d $DIREXPORT ]; then
  mkdir -p $DIREXPORT
  chown -f informix:informix $DIREXPORT
fi

# ************************************************************************
#
# Reboot IBM-IDS if needed
#
# ************************************************************************
if [ "$RESTARTDBS" != "N" ]; then
      su informix -c "$INFORMIXDIR/bin/onmode -ky"
      sleep 5
      su informix -c "$INFORMIXDIR/bin/oninit -jy"
      sleep 20
      echo "`date` Servidor IDS iniciado en modo administrador." >>$LOGSYS
fi

# ************************************************************************
#
# Gets the list of databases to be processed
#
# ************************************************************************
if [ -z "$DBSINCLUDE" ]; then
    DBSINCLUDE="''"
    INCLCMD="1=1"
else
    INCLCMD="1=0"
fi

su informix -c "$INFORMIXDIR/bin/dbaccess sysmaster" >>$LOGSYS 2>>$LOGSYS <<EOF
  SET ISOLATION TO DIRTY READ;
  SET LOCK MODE TO WAIT 30;
  UNLOAD TO "/tmp/dbslist.$$" DELIMITER ' '
  SELECT trim(name) || "/" || trim(dbs_collate) name
         FROM sysdatabases, OUTER sysdbslocale
  WHERE sysdatabases.name = sysdbslocale.dbs_dbsname
    AND name NOT MATCHES "sys*"
    AND name NOT IN ($DBSEXCLUDE)
    AND (name IN ($DBSINCLUDE) OR $INCLCMD)
EOF
if [ $? -gt 0 ]; then
  STATUS=ERROR
  echo "`date` ***** ERROR Obteniendo lista de bases de datos" >>$LOGSYS
fi
DBSLIST=`cat /tmp/dbslist.$$`
rm -f /tmp/dbslist.$$


echo "Exportando: [$DBSLIST]" >>$LOGSYS

# ************************************************************************
#
# For each database
#
# ************************************************************************
for DBSOBJ in `echo $DBSLIST | sed 's/name //g'`; do
  LOC=`basename $DBSOBJ`
  DBS=`dirname $DBSOBJ`
  echo "`date` Exporting [$DBS] locale [$LOC] on [$DIREXPORT] ..." >>$LOGSYS

  # ------------------------------------------------------------------
  # Always run dbexport from /tmp to avoid directory permissions
  # problems on Linux. the root crontab in linux is executed
  # in /root in wich the informix user does not have 
  # write permission and the dbexport can not be executed as
  # informix from this directory!
  # ------------------------------------------------------------------
  touch /tmp/dbexport.out
  chown informix:informix /tmp/dbexport.out

  # Delete previous dbexport
  rm -rf $DIREXPORT/$DBS.exp*

  # Begin dbexport
  su informix -c "cd /tmp; CLIENT_LOCALE=${LOC}; export CLIENT_LOCALE; DB_LOCALE=${LOC}; export DB_LOCALE; $INFORMIXDIR/bin/dbexport $DBS -q -ss -o $DIREXPORT </dev/null" >>$LOGSYS 2>&1
  if [ $? -gt 0 ]; then
    STATUS=ERROR
    echo "********************************************" >>$LOGSYS
    echo "`date` ***** ERROR Exportando $DBS a $DIREXPORT" >>$LOGSYS
    su informix -c "$INFORMIXDIR/bin/onstat -g sql" >>$LOGSYS 2>&1
    echo "********************************************" >>$LOGSYS
    for PROC in `su informix -c "$INFORMIXDIR/bin/onstat -g sql | grep $DBS | awk '{ print $1 }'"`; do
                  su informix -c "$INFORMIXDIR/bin/onstat -g ses $PROC" >>$LOGSYS 2>&1
    done
  fi

  if [ -d $DIREXPORT/$DBS.exp ]; then
    mv $DIREXPORT/$DBS.exp $DIREXPORT/$DBS.exp.$LOC
    if [ -f /usr/bin/bzip2 ]; then
      CMDZIP=bzip2
    elif [ -f /usr/bin/gzip -o -f /usr/local/bin/gzip ]; then
      CMDZIP=gzip
    else
      CMDZIP=compress
    fi

    #Monthly Backup Exports
    if [ "$MOYSAVE" = "YES" ]; then
        if [ -z "$MONTHDIR" ]; then
            DIREXPORTMOY=`dirname $DIREXPORT`/MOY/$MONTH
        else                         
            DIREXPORTMOY=$MONTHDIR/$MONTH
        fi                                          
        
        if [ ! -d $DIREXPORTMOY ]; then
          mkdir -p $DIREXPORTMOY
        else
          rm -rf $DIREXPORTMOY/$DBS.exp.$LOC
        fi
        (cd $DIREXPORT/$DBS.exp.$LOC; $CMDZIP -f *; cp -r $DIREXPORT/$DBS.exp.$LOC $DIREXPORTMOY/) &
    else
        (cd $DIREXPORT/$DBS.exp.$LOC; $CMDZIP -f *) &
    fi
  fi
done


# If we had the server in single user we put it in multiuser.
if [ "$RESTARTDBS" != "N" ]; then
    su informix -c "$INFORMIXDIR/bin/onmode -my"
    echo "`date` Servidor IDS $INFORMIXVER en modo multiusuario." >>$LOGSYS
fi

rm -f /tmp/dbexport.out
echo ""                                                    >>$LOGSYS
echo "#% status: $STATUS"                                  >>$LOGSYS
echo "#% motive: $MOTIVE"                                  >>$LOGSYS
echo "#% enddate: `date +%d-%m-%Y`"                        >>$LOGSYS
echo "#% endtime: `date +%H:%M`"                           >>$LOGSYS
echo ""                                                    >>$LOGSYS
echo "END $STATUS `basename $0 .sh` `date` "               >>$LOGSYS
echo "===================================================" >>$LOGSYS

# ************************************************************************
# We send the result of the process to the administrator via e-mail.
# In this way we make sure thtat the administrator always knows
# if the process is executed correctly or not.
# For this you have to make sure that the equipment can do mail relay.
# ************************************************************************

if [ -n "$MAILTO" ]; then
     do_mail $MAILTO
fi
if [ -n "$MAILERROR" ] && [ "$STATUS" != "OK" ]; then
     do_mail $MAILERROR
fi

Give it execution permissions:

Copy
chmod +x dbs_export.sh

Backup filesystem

It is recommended to have a disk partition exclusively for backups,mmounted on /backup1.

Create the IFMX-EXPORTS subdirectory:

Copy
cd /backup1
Copy
mkdir /backup1/IFMX-EXPORTS

Change owner and group to informix:

Copy
chown informix:informix IFMX-EXPORTS

Give it the following permissions:

Copy
chmod 775 IFMX-EXPORTS

Finally add in the root crontab the following shell script execution dbs_export:

Copy
crontab -e
Copy
00  5 * * * /CONFIG/SCRIPTS/dbs_export.sh --mailto “sysadmin@empresa.es"

Where sysadmin@empresa.es must be replaced by the email address of the system administrator responsible for the installation.

4 AWS Backup

Use the ifxbkpcloud.jar utility to configure an online storage device for the Amazon Simple Storage Service.

The following options are supported by the ifxbkpcloud.jar utility:

  • CREATE_DEVICE provider device [region]
  • DELETE_DEVICE provider device
  • LIST_DEVICES provider
  • DELETE_FILE provider device file
  • LIST_FILES provider device

The parameters for the ifxbkpcloud.jar commands are defined as follows:

  • provider is amazon.
  • device is the name of the storage device.
  • region is one of the following: US_Standard, US_West, EU_Ireland or AP_Singapore.
  • file is the name of backup object (key) stored on Amazon S3.
Error messages from ifxbkpcloud.jar are written to $INFORMIXDIR/ifxbkpcloud.log on UNIX machines and to %INFORMIXDIR%\ifxbkpcloud.log on Windows machines.

See also: