backup des bases des instances Informix

26.04.2005 | Mis à jour le 02.05.2005 | marcori
8381 visiteurs  -  18 visiteurs aujourd'hui  -  1 commentaire

Introduction. Pour sauvegarder les bases de données Informix d’un serveur fonctionnant sous Linux, récupérer la structure des tables et les données, j’ai pu être confronté à l’élaboration d’un script assez complexe mais efficace.

Outre la simple sauvegarde texte, ce script génère un fichier de commande par table permettant de re-créer une table avec les bonnes tailles d’Extent.Le déchargement en fichier texte est trié sur l’ordre du premier index trouvé pour cette table.

Ce script utilise la base sysmaster pour retrouver certaines informations. Ce script execute sa sauvegarde pour toutes les instances locales définies dans le fichier $INFORMIXDIR/etc/sqlhosts, et retrouve les bases de chacune de ces instances.

Il est fait mention dans ce script d’un fichier portant l’extension .var plaçé dans /home/shared/scripts/connexion et nommé du nom de l’instance. C’est une habitude que j’ai de placer dans ce fichier les variables d’environnement nécessaires à Informix, mais même sans ce fichier, ce script devrait pouvoir fonctionner.

Script


#!/bin/sh

###############################################################################
# Programme        : backup_informix.sh
# Application      : Sauvegardes
# Date de creation : 25/04/2005
# Auteur           : Marc-Henri PAMISEUX
#
# Copyright (c) 2005 Marc-Henri PAMISEUX
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
# -----------------------------------------------------------------------------
# ! Date Modif. ! fonction          ! description                    ! auteur !
# -----------------------------------------------------------------------------
# !             !                   !                                !        !
# !             !                   !                                !        !
###############################################################################

###############################################################################
# FONCTION        Genere_IfxScript
# LIBELLE        Fonction génératrice de script SQL
# TYPE          NORMAL
# ARGUMENTS        OUI
# ENTREE        INSTANCE,DATABASE,TABLE
# RETOUR        AUCUN
# DESCRIPTION        Cette fonction permet de génerer les scripts de rechargement
#                des tables pour une base et une instance Informix donnée
###############################################################################
Genere_IfxScript()
{
        if [ $# -gt 2 ]
        then
                export INSTANCE=$1
                export DATABASE=$2
                export TABLE=$3
        fi

        pagesUsed=`"${INFORMIXDIR}"/bin/oncheck -pT "${DATABASE}":"${TABLE}" | head -n 30 | grep 'Number of pages used' | sed -r 's,[[:alpha:][:blank:][:cntrl:][:punct:]],,g'`

        ${INFORMIXDIR}/bin/oncheck -pT "${DATABASE}":"${TABLE}" | head -n 30 |grep -C 2 'umber of pages allocated' | sed -r 's,[[:space:]],,g' | sed -r 's,.*[A-Z],\L&,g' | sed -e 's,[0-9], &,' >${DirBakIfx}/${INSTANCE}/${DATABASE}/${TABLE}.check

#...............................................................................
# Si le fichier est vide ou n'existe pas on le créé avec des valeurs égales à 0
#...............................................................................
        if [ ! -s ${DirBakIfx}/${INSTANCE}/${DATABASE}/${TABLE}.check ]
        then
                echo -e "firstextentsize\t0\nnextextentsize\t0numberofpagesused\t0" >${DirBakIfx}/${INSTANCE}/${DATABASE}/${TABLE}.check
        fi

#...............................................................................
# On vient lire la taille du First Extent
#...............................................................................
        unset firstExtent
        firstExtent=`cat "${DirBakIfx}"/"${INSTANCE}"/"${DATABASE}"/"${TABLE}".check | grep 'firstextentsize' | awk '\
                /firstextentsize/ { value=$2*2 } { \
                if (value <= 16) \
                { \
                        value=16 \
                } \
                printf ("%6d",value) \
        } '`

        if [ -z "${firstExtent}" ]
        then
                firstExtent=16
        fi

#...............................................................................
# On vient lire la taille du Next Extent
#...............................................................................
        unset nextExtent
        nextExtent=`cat "${DirBakIfx}"/"${INSTANCE}"/"${DATABASE}"/"${TABLE}".check | grep 'nextextentsize' | awk '\
                /nextextentsize/ { value=$2*2 } { \
                if (value <= 16) \
                { \
                        value=16 \
                } \
                printf ("%6d",value) \
        } '`

        if [ -z "${nextExtent}" ]
        then
                nextExtent=16
        fi

#...............................................................................
# On vient calculer la taille du First Extent ideal (pagesUsed+25%)
# Attention le First Extent minimum doit être de 16
#...............................................................................
        unset pagesUsed
        pagesUsed=`cat "${DirBakIfx}"/"${INSTANCE}"/"${DATABASE}"/"${TABLE}".check | grep 'numberofpagesused' | awk '\
                /numberofpagesused/ { value=$2*2*1.25 } { \
                if (value <= 16) \
                { \
                        value=16 \
                } \
                printf ("%6d",value) \
        } '`

        if [ -z "${pagesUsed}" ]
        then
                pagesUsed=16
        fi

#...............................................................................
# On vient calculer la taille du Next Extent basé sur la taille de pagesUsed
# Attention le Next Extent minimum doit être de 16
#...............................................................................
        unset newNextExtent
        if [ ${pagesUsed} -gt 64 ]
        then
                newNextExtent=`expr ${pagesUsed} / 4`
        else
                newNextExtent=16
        fi

        if [ -f ${DirBakIfx}/${INSTANCE}/${DATABASE}/${TABLE}.check ]
        then
                rm -f ${DirBakIfx}/${INSTANCE}/${DATABASE}/${TABLE}.check
        fi

#...............................................................................
# On vient lire le nom des colonnes de la table
#...............................................................................
        echo "UNLOAD TO '${DirBakIfx}/${INSTANCE}/${DATABASE}/${TABLE}.col' \
                        SELECT syscolumns.colno,syscolumns.colname \
                        FROM systables,syscolumns \
                        WHERE systables.tabname='${TABLE}' \
                        AND syscolumns.tabid=systables.tabid \
                        ORDER BY syscolumns.colno ASC;" | \
                        ${INFORMIXDIR}/bin/dbaccess ${DATABASE} 1>/dev/null 2>&1

#...............................................................................
# On vient retirer les | liés a l'UNLOAD Informix
#...............................................................................
        if [ -s ${DirBakIfx}/${INSTANCE}/${DATABASE}/${TABLE}.col ]
        then
                cat ${DirBakIfx}/${INSTANCE}/${DATABASE}/${TABLE}.col | \
                        sed -e 's,|$,,g' | sed -e 's,|, ,g' \
                        >${DirBakIfx}/${INSTANCE}/${DATABASE}/${TABLE}.colname

                if [ ! -s ${DirBakIfx}/${INSTANCE}/${DATABASE}/${TABLE}.colname ]
                then
                        echo "99999 noname" \
                        >${DirBakIfx}/${INSTANCE}/${DATABASE}/${TABLE}.colname
                fi
        else
                echo "99999 noname" >${DirBakIfx}/${INSTANCE}/${DATABASE}/${TABLE}.colname
        fi

        if [ -f ${DirBakIfx}/${INSTANCE}/${DATABASE}/${TABLE}.col ]
        then
                rm -f ${DirBakIfx}/${INSTANCE}/${DATABASE}/${TABLE}.col
        fi

#...............................................................................
# On vient lire l'index primaire de la table
#...............................................................................
        echo "UNLOAD TO '${DirBakIfx}/${INSTANCE}/${DATABASE}/${TABLE}.idx' \
                        SELECT sysindexes.levels,sysindexes.part1,\
                                sysindexes.part2,sysindexes.part3,sysindexes.part4,\
                                sysindexes.part5,sysindexes.part6,sysindexes.part7,\
                                sysindexes.part8,sysindexes.part9,sysindexes.part10,\
                                sysindexes.part11,sysindexes.part12,sysindexes.part13,\
                                sysindexes.part14,sysindexes.part15,sysindexes.part16 \
                        FROM systables,sysindexes \
                        WHERE systables.tabname='${TABLE}' \
                        AND sysindexes.tabid=systables.tabid \
                        ORDER BY sysindexes.levels ASC;" | \
                        ${INFORMIXDIR}/bin/dbaccess ${DATABASE} 1>/dev/null 2>&1

#...............................................................................
# On vient retirer la colonne levels du fichier issu de l'UNLOAD
# Si le fichier est vide c'est qu'il n'y a pas d'index
#...............................................................................
        if [ -s ${DirBakIfx}/${INSTANCE}/${DATABASE}/${TABLE}.idx ]
        then
                cat ${DirBakIfx}/${INSTANCE}/${DATABASE}/${TABLE}.idx | \
                        sed -e 's,^[0-9]*.|,,' | sed -e 's,^,|,g' \
                        >${DirBakIfx}/${INSTANCE}/${DATABASE}/${TABLE}.idxname

                if [ ! -s ${DirBakIfx}/${INSTANCE}/${DATABASE}/${TABLE}.idxname ]
                then
                        echo "|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|" \
                        >${DirBakIfx}/${INSTANCE}/${DATABASE}/${TABLE}.idxname
                fi
        else
                echo "|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|" \
                >${DirBakIfx}/${INSTANCE}/${DATABASE}/${TABLE}.idxname
        fi

        if [ -f ${DirBakIfx}/${INSTANCE}/${DATABASE}/${TABLE}.idx ]
        then
                rm -f ${DirBakIfx}/${INSTANCE}/${DATABASE}/${TABLE}.idx
        fi

#...............................................................................
# On vient fusionner le fichier index avec le fichier des noms de colonnes
#...............................................................................
        /usr/bin/awk -v FICCOL=${DirBakIfx}/${INSTANCE}/${DATABASE}/${TABLE}.colname -v FICIDX=${DirBakIfx}/${INSTANCE}/${DATABASE}/${TABLE}.idxname '
                BEGIN {
                        FS = "|"
                        tabidx=0

                        while ((getline < FICIDX) > 0) {
                                tabindex[tabidx]=$0

                                FS = " "
                                while ((getline < FICCOL) > 0) {
                                        colid=$1
                                        colname=$2

                                        gsub("\\|" colid "\\|","|" colname "|",tabindex[tabidx])
                                }
                                close(FICCOL)
                                tabidx++
                                FS = "|"
                        }
                        close(FICIDX)
                        tabidx=0
                        while ((tabidx in tabindex) > 0) {
                                print tabindex[tabidx]
                                tabidx++
                        }
                }' | sed -e 's,0,,g' | sed -e 's,||,,g' | sed -e 's,^|,,g' | sed -e 's,|$,,g' | sed -e 's/|/,/g'>${DirBakIfx}/${INSTANCE}/${DATABASE}/${TABLE}.idx

        if [ -s ${DirBakIfx}/${INSTANCE}/${DATABASE}/${TABLE}.idx ]
        then
                rm -f ${DirBakIfx}/${INSTANCE}/${DATABASE}/${TABLE}.colname
                rm -f ${DirBakIfx}/${INSTANCE}/${DATABASE}/${TABLE}.idxname
        fi

#...............................................................................
# On vient fabriquer un script de rechargement de la table
#...............................................................................
        echo -e "#!/bin/sh\n" >${DirBakIfx}/${INSTANCE}/${DATABASE}/${TABLE}.cmd

        echo "if [ -s ./${TABLE}.out ]" \
                        >>${DirBakIfx}/${INSTANCE}/${DATABASE}/${TABLE}.cmd
        echo "then" >>${DirBakIfx}/${INSTANCE}/${DATABASE}/${TABLE}.cmd
        echo -e "\tmv ./${TABLE}.out ./${TABLE}.bak" \
                        >>${DirBakIfx}/${INSTANCE}/${DATABASE}/${TABLE}.cmd
        echo -e "fi\n" >>${DirBakIfx}/${INSTANCE}/${DATABASE}/${TABLE}.cmd

        echo "${INFORMIXDIR}/bin/dbaccess ${DATABASE}<<!EOF" \
                        >>${DirBakIfx}/${INSTANCE}/${DATABASE}/${TABLE}.cmd
        echo -e "\tUNLOAD TO '${TABLE}.out'" \
                        >>${DirBakIfx}/${INSTANCE}/${DATABASE}/${TABLE}.cmd
        echo -e "\tSELECT *" >>${DirBakIfx}/${INSTANCE}/${DATABASE}/${TABLE}.cmd
        echo -e "\tFROM ${TABLE}" >>${DirBakIfx}/${INSTANCE}/${DATABASE}/${TABLE}.cmd

#...............................................................................
# On vient lire le premier index de la liste des index de la table
#...............................................................................
        if [ -s ${DirBakIfx}/${INSTANCE}/${DATABASE}/${TABLE}.idx ]
        then
                unset sOrderBy
                sOrderBy=`head -1 "${DirBakIfx}"/"${INSTANCE}"/"${DATABASE}"/"${TABLE}".idx`
        else
                sOrderBy=""
        fi

        if [ ! -z "${sOrderBy}" ]
        then
                echo -e "\tORDER BY ${sOrderBy} ASC;\n" \
                                >>${DirBakIfx}/${INSTANCE}/${DATABASE}/${TABLE}.cmd
        else
                echo -e ";\n" >>${DirBakIfx}/${INSTANCE}/${DATABASE}/${TABLE}.cmd
        fi

        echo -e "\tDROP TABLE ${TABLE};\n" \
                        >>${DirBakIfx}/${INSTANCE}/${DATABASE}/${TABLE}.cmd

#...............................................................................
# On vient fabriquer le schema de la table
#...............................................................................
        unset inDbSpace
        if [ -z "${nomDbSpace}" ]
        then
                inDbSpace=") extent size"
        else
                inDbSpace=") in ${nomDbSpace} extent size"
        fi

        ${INFORMIXDIR}/bin/dbschema -d ${DATABASE} -ss -t ${TABLE} | grep -v -E "DBSCHEMA|Copyright|Software|\{|\}" | grep -v '^$' | sed -e 's,unipe,informix,g' | sed -e 's,develop,informix,g' | sed -e 's,jacquelg,informix,g' | sed -e 's,martinec,informix,g' | sed -e 's,mhenrip,informix,g' | sed -e 's,noelb,informix,g' | sed -e 's,benoitg,informix,g' | sed -e 's,fadrian,informix,g' | sed -e 's,mterreau,informix,g' | sed -e "s,revoke.*$,LOAD FROM '\./${TABLE}\.out' INSERT INTO ${TABLE}\;," | sed -r "s,\) *.extent size,${inDbSpace},g" | sed -r "s,extent size [0-9]*.,extent size ${pagesUsed} ,g" | sed -r "s,next size [0-9]*.,next size ${newNextExtent} ,g" | sed -e 's,lock mode page,lock mode row,g' >>${DirBakIfx}/${INSTANCE}/${DATABASE}/${TABLE}.cmd

        echo -e "UPDATE STATISTICS HIGH FOR TABLE ${TABLE};\n" >>${DirBakIfx}/${INSTANCE}/${DATABASE}/${TABLE}.cmd
        echo -e "!EOF 1>/dev/null 2>&1\n" >>${DirBakIfx}/${INSTANCE}/${DATABASE}/${TABLE}.cmd

}
###############################################################################
# FONCTION        Unload_IfxTable
# LIBELLE        Fonction d'exportation des données Informix
# TYPE          NORMAL
# ARGUMENTS        OUI
# ENTREE        INSTANCE,DATABASE,TABLE
# RETOUR        AUCUN
# DESCRIPTION        Cette fonction permet d'extraire les données d'une table
#                informix dans un fichier texte à plat.
###############################################################################
Unload_IfxTable()
{
        if [ $# -gt 2 ]
        then
                export INSTANCE=$1
                export DATABASE=$2
                export TABLE=$3
        fi

#...............................................................................
# Déchargement de la table courante dans un fichier texte
#...............................................................................
        unset sRequete
        sRequete="SELECT * FROM ${TABLE}"

#...............................................................................
# On vient lire le premier index de la liste des index de la table
#...............................................................................
        if [ -s ${DirBakIfx}/${INSTANCE}/${DATABASE}/${TABLE}.idx ]
        then
                unset sOrderBy
                sOrderBy=`head -1 "${DirBakIfx}"/"${INSTANCE}"/"${DATABASE}"/"${TABLE}".idx`
        else
                sOrderBy=""
        fi

        if [ -f ${DirBakIfx}/${INSTANCE}/${DATABASE}/${TABLE}.idx ]
        then
                rm -f ${DirBakIfx}/${INSTANCE}/${DATABASE}/${TABLE}.idx
        fi

        if [ ! -z "${sOrderBy}" ]
        then
                sRequete=${sRequete}" ORDER BY ${sOrderBy} ASC;"
        else
                sRequete=${sRequete}";"
        fi

        echo "UNLOAD TO '${DirBakIfx}/${INSTANCE}/${DATABASE}/${TABLE}.out' \
                        ${sRequete}" |\
                        ${INFORMIXDIR}/bin/dbaccess ${DATABASE} 1>/dev/null 2>&1

}
###############################################################################
# FONCTION        Compress_IfxTable
# LIBELLE        Fonction de compression des donées
# TYPE          NORMAL
# ARGUMENTS        OUI
# ENTREE        INSTANCE,DATABASE,TABLE
# RETOUR        AUCUN
# DESCRIPTION        Cette fonction permet de compresser les fichiers contenant les
#                données d'une table informix afin d'économiser de la place
###############################################################################
Compress_IfxTable()
{
        if [ $# -gt 2 ]
        then
                export INSTANCE=$1
                export DATABASE=$2
                export TABLE=$3
        fi

        if [ ! -s ${DirBakIfx}/${INSTANCE}/${DATABASE}/${TABLE}.out ]
        then
                echo "La table ${TABLE} de la base ${DATABASE}, instance ${INSTANCE} est vide"
        else
                unset TailleTable
                TailleTable=`du -sk ${DirBakIfx}/${INSTANCE}/${DATABASE}/${TABLE}.out | awk '{print $1}'`

                gzip ${DirBakIfx}/${INSTANCE}/${DATABASE}/${TABLE}.out
                echo "Table sauvegardée: ${TABLE} (${TailleTable} Ko)"
        fi
}
###############################################################################
# FONCTION        Histo_Dech
# LIBELLE        Fonction d'historisation de la sauvegarde
# TYPE          NORMAL
# ARGUMENTS        OUI
# ENTREE        folderHisto
# RETOUR        AUCUN
# DESCRIPTION        Cette fonction permet d'ajouter une entrée dans le fichier
#                d'historisation des sauvegardes
###############################################################################
Histo_Dech()
{
        if [ $# -gt 0 ]
        then
                folderHisto=$1
        else
                return 1
        fi

#...............................................................................
# On vient vérifier que le dossier des historiques existe bien
#...............................................................................
        if [ ! -d ${folderHisto} ]
        then
                echo "Erreur: Le dossier ${folderHisto} n'existe pas"
                return 1
        fi

        if [ -z "${BakDate}" ]
        then
                export BakDate=`date --iso-8601`
        fi

        if [ ! -d ${folderHisto}/${BakDate} ]
        then
                echo "Erreur: Le dossier ${folderHisto}/${BakDate} n'existe pas"
                return 1
        fi

        unset tailleBackup
        tailleBackup=`du -sk ${folderHisto}/${BakDate} | awk '{print $1}'`

#...............................................................................
# On vient vérifier que la sauvegarde courante n'a pas déjà été historisée.
#...............................................................................
        if [ -s ${folderHisto}/histo_dech ]
        then
                unset isHisto
                isHisto=`cat ${folderHisto}/histo_dech | grep ${BakDate}`

#...............................................................................
# Si isHisto n'est pas vide, c'est qu'il existe une historisation pour ce jour
# Dans ce cas, on l'efface et on la recalcule; Sinon, on l'insère directement
#...............................................................................
                if [ ! -z "${isHisto}" ]
                then
                        cat ${folderHisto}/histo_dech | grep -v ${BakDate} > ${folderHisto}/histo_temp
                        if [ -f ${folderHisto}/histo_temp ]
                        then
                                echo -e "${BakDate}\t${folderHisto}/${BakDate}\t${tailleBackup}" >>${folderHisto}/histo_temp
                                rm -f ${folderHisto}/histo_dech
                                mv ${folderHisto}/histo_temp ${folderHisto}/histo_dech
                        else
                                echo "Une erreur est survenue lors de l'historisation de la sauvegarde."
                        fi
                else
                        echo -e "${BakDate}\t${folderHisto}/${BakDate}\t${tailleBackup}" >>${folderHisto}/histo_dech
                fi
        else
                touch ${folderHisto}/histo_dech
                echo -e "${BakDate}\t${folderHisto}/${BakDate}\t${tailleBackup}" >>${folderHisto}/histo_dech
        fi
       
}
###############################################################################
# FONCTION        Test_DblBackup
# LIBELLE        Fonction de test de la sauvegarde
# TYPE          NORMAL
# ARGUMENTS        OUI
# ENTREE        folderBackup
# RETOUR        AUCUN
# DESCRIPTION        Cette fonction permet de tester si la taille du dossier de
#                backup est supérieure à la sauvegarde précedente du même jour.
#                Cela permet de conserver une bonne sauvegarde dans un même
#                jour, dans le cas où la sauvegarde courante serait incorrecte
###############################################################################
Test_DblBackup()
{
        if [ $# -gt 0 ]
        then
                folderBackup=$1
        else
                return 1
        fi

#...............................................................................
# On vient vérifier que le dossier de la sauvegarde existe bien
#...............................................................................
        if [ ! -d ${folderBackup} ]
        then
                echo "Erreur: Le dossier ${folderBackup} n'existe pas"
                return 1
        fi

        unset tailleBackup
        tailleBackup=`du -sk ${folderBackup} | awk '{print $1}'`

        unset tailleMinor
        tailleMinor=`expr ${tailleBackup} / 4`

#...............................................................................
# On vient tester s'il existe une même sauvegarde pour ce jour
#...............................................................................
        if [ -d ${folderBackup}.old ]
        then
                unset tailleOldBackup
                tailleOldBackup=`du -sk ${folderBackup}.old | awk '{print $1}'`
                tailleOldBackup=`expr ${tailleOldBackup} - ${tailleMinor}`

#...............................................................................
# Si la taille de l'ancien dossier de sauvegarde minoré du quart de la taille
# de la sauvegarde actuelle est > 0 ET
# que la taille de l'actuel dossier de sauvegarde est supérieur ou égal à
# cette valeur, alors on supprime l'ancien dossier de sauvegarde
#...............................................................................
                if ([ ${tailleBackup} -ge ${tailleOldBackup} ] && [ ${tailleOldBackup} -gt 0 ])
                then
                        rm -rf ${folderBackup}.old
                else
                        echo "Pas de suppression de ${folderBackup}.old."
                        echo "Valeur de tailleBackup=>${tailleBackup}"
                        echo "Valeur de tailleOldBackup=>${tailleOldBackup}"
                fi
        fi
}
###############################################################################
# FONCTION      Remove_Backup
# LIBELLE       Fonction de suppression des anciennes sauvegardes
# TYPE          NORMAL
# ARGUMENTS     OUI
# ENTREE        nbBakToKeep
# RETOUR        AUCUN
# DESCRIPTION   Cette fonction permet de tester le nombre de sauvegardes
#               présentes dans le dossier de backup, et de supprimer toutes
#               les plus anciennes sauvegardes
###############################################################################
Remove_Backup()
{
       if [ $# -gt 1 ]
       then
               folderBackup=$1
               nbBakToKeep=$2
       else
               return 1
       fi

#...............................................................................
# On vient vérifier que le dossier de la sauvegarde existe bien
#...............................................................................
       if [ ! -d ${folderBackup} ]
       then
               echo "Erreur: Le dossier ${folderBackup} n'existe pas"
               return 1
       fi

#...............................................................................
# On récupère la liste des 8 dernières sauvegardes
#...............................................................................
       unset ListeToKeep
       ListeToKeep=`ls -1t ${folderBackup} | grep -v 'histo_dech' | head -8`

       if [ -z "${ListeToKeep}" ]
       then
               echo "Erreur: Le dossier ${folderBackup} est vide"
               return 1
       fi

#...............................................................................
# On vient lire la liste de tous les dossiers
#...............................................................................
       listeAll=`ls -1t ${folderBackup} | grep -v 'histo_dech'`

#...............................................................................
# On supprime de la liste des dossiers les éléments à conserver
#...............................................................................
       for Dossier in ${ListeToKeep}
       do
               listeAll=`echo ${listeAll} | sed -e 's,'${Dossier}',,g'`
       done

#...............................................................................
# Pour chaque élément de la nouvelle liste, on supprime le dossier
#...............................................................................
       unset Dossier

       if [ ! -z "${listeAll}" ]
       then
               for Dossier in ${listeAll}
               do
                       echo "suppression de ${Dossier} (rm -rf ${folderBackup}/${Dossier})"
                       rm -rf ${folderBackup}/${Dossier}
               done
       fi
}
###############################################################################
# FONCTION        backup_IfxBases
# LIBELLE        Fonction de sauvegarde des bases de données
# TYPE          NORMAL
# ARGUMENTS        OUI
# ENTREE        INSTANCE,DATABASE
# RETOUR        AUCUN
# DESCRIPTION        Cette fonction permet de déclencher une sauvegarde des bases
#                de données Informix relatives à une instance
###############################################################################
backup_IfxBases()
{
        if [ $# -gt 1 ]
        then
                export INSTANCE=$1
                export DATABASE=$2
        fi

#...............................................................................
# Création du dossier de sauvegarde
#...............................................................................
        if [ -d ${DirBakIfx}/${INSTANCE}/${DATABASE} ]
        then
                if [ -d ${DirBakIfx}/${INSTANCE}/${DATABASE}.old ]
                then
                        rm -rf ${DirBakIfx}/${INSTANCE}/${DATABASE}.old
                fi
                mv ${DirBakIfx}/${INSTANCE}/${DATABASE} ${DirBakIfx}/${INSTANCE}/${DATABASE}.old
        fi

        mkdir ${DirBakIfx}/${INSTANCE}/${DATABASE}

        unset nomDbSpace
        if [ -s ${DirBakIfx}/${INSTANCE}/liste_dbspaces ]
        then
                nomDbSpace=`cat ${DirBakIfx}/${INSTANCE}/liste_dbspaces | grep ${DATABASE} | awk '{print $1}'`
        else
                nomDbSpace=""
        fi

#...............................................................................
# Fonction de génération des scripts de rechargement de la base
#...............................................................................
        echo "UNLOAD TO '/tmp/liste_tbl'\
                SELECT tabname\
                FROM systables\
                WHERE tabtype='T'\
                AND tabid>99\
                ORDER BY tabname;" |\
                ${INFORMIXDIR}/bin/dbaccess ${DATABASE} 1>/dev/null 2>&1

        if [ -s /tmp/liste_tbl ]
        then
                cat /tmp/liste_tbl | sed -e 's,|$,,g' | sed -e 's,|,\t,g' \
                        >${DirBakIfx}/${INSTANCE}/${DATABASE}/liste_tables
                rm -f /tmp/liste_tbl
        else
                return 1
        fi

################################################################################
# BOUCLE des tables de la base de données courante
################################################################################
#...............................................................................
# Pour chaque table:
#        - on on calcule la taille du First extent et du Next extent
#        - on génère un shéma
#        - on décharge la table dans un fichier texte (.out)
#        - on compresse le fichier d'export s'il est non vide
#...............................................................................
        for TABLE in `cat ${DirBakIfx}/${INSTANCE}/${DATABASE}/liste_tables`
        do
                export TABLE
                Genere_IfxScript ${INSTANCE} ${DATABASE} ${TABLE}
                Unload_IfxTable ${INSTANCE} ${DATABASE} ${TABLE}
                Compress_IfxTable ${INSTANCE} ${DATABASE} ${TABLE}
        done
}
###############################################################################
# FONCTION        backup_informix
# LIBELLE        Fonction de sauvegarde
# TYPE          NORMAL
# ARGUMENTS        NON
# ENTREE        AUCUN
# RETOUR        AUCUN
# DESCRIPTION        Cette fonction permet de déclencher une sauvegarde des bases
#                de données Informix
###############################################################################
backup_informix()
{

unset DateNow
export DateNow=`date`
echo "DEBUT BACKUP INFORMIX du: ${DateNow}" >${LogBakIfx}
echo "" >>${LogBakIfx}

#...............................................................................
# Definition des variables informix
#...............................................................................
export INFORMIXDIR=/opt/informix
export PATH=${PATH}:${INFORMIXDIR}/bin:${INFORMIXDIR}/lib
export INFORMIXSQLHOSTS=${INFORMIXDIR}/etc/sqlhosts
export IFMX_HPKAIO_NUM_REQ=2000
export INFORMIXSTACKSIZE=128
export LD_LIBRARY_PATH=${INFORMIXDIR}/lib:${INFORMIXDIR}/lib/cli:${INFORMIXDIR}/lib/esql:${LD_LIBRARY_PATH}
export TERMCAP=/opt/informix/etc/termcap
export DBCENTURY=C
export DBDATE=DMY4/

unset Qui
export Qui=`uname -n`

unset MyIP
export MyIP=`cat /etc/hosts | grep "${Qui}" | awk '{print $1}'`

if [ ! -z "${MyIP}" ]
then
        unset INSTANCES
        INSTANCES=`cat ${INFORMIXSQLHOSTS} | grep -v '^#' | grep -v '^$' | grep "${MyIP}" | awk '{ print $1 }'`

################################################################################
# BOUCLE des Instances de base de données
################################################################################
        for INSTANCE in `echo ${INSTANCES}`
        do
                export INSTANCE
                if [ -s /home/shared/scripts/connexion/${INSTANCE}.var ]
                then
                        source /home/shared/scripts/connexion/${INSTANCE}.var
                else
                        export INFORMIXSERVER=${INSTANCE}
                        export ONCONFIG=onconfig.${INSTANCE}
                fi

                if [ ! -d ${DirBakIfx}/${INSTANCE} ]
                then
                        mkdir ${DirBakIfx}/${INSTANCE}
                fi

#...............................................................................
# On vient charge la liste des bases de l'instance courante
#...............................................................................
                if [ -f /tmp/liste_dtb ]
                then
                        rm -f /tmp/liste_dtb
                fi

                echo "UNLOAD TO '/tmp/liste_dtb' \
                        SELECT name \
                        FROM sysdatabases \
                        WHERE name NOT IN ('sysmaster','sysutils','sysuser');" |\
                        ${INFORMIXDIR}/bin/dbaccess sysmaster 1>/dev/null 2>&1

                if [ -s /tmp/liste_dtb ]
                then
                        cat /tmp/liste_dtb | sed -e 's,|$,,g' | sed -e 's,|,\t,g' \
                                >${DirBakIfx}/${INSTANCE}/liste_databases
                        rm -f /tmp/liste_dtb
                else
                        return 1
                fi

#...............................................................................
# Requete de lecture des noms des dbspaces
#...............................................................................
                echo "UNLOAD TO '/tmp/nom_dbs'\
                        SELECT dbinfo('DBSPACE',partnum) dbspace,name\
                        FROM sysdatabases\
                        ORDER BY dbspace,name ASC;" |\
                        ${INFORMIXDIR}/bin/dbaccess sysmaster 1>/dev/null 2>&1

                if [ -s /tmp/nom_dbs ]
                then
                        cat /tmp/nom_dbs | sed -e 's,|$,,g' | sed -e 's,|,\t,g' \
                                >${DirBakIfx}/${INSTANCE}/liste_dbspaces
                else
                        touch ${DirBakIfx}/${INSTANCE}/liste_dbspaces
                fi

                if [ -f /tmp/nom_dbs ]
                then
                        rm -f /tmp/nom_dbs
                fi

################################################################################
# BOUCLE des bases de données
################################################################################
                for DATABASE in `cat ${DirBakIfx}/${INSTANCE}/liste_databases`
                do
                        echo "###############################################################################" >>${LogBakIfx}
                        echo "# Base actuelle: ${DATABASE}" >>${LogBakIfx}
                        echo "###############################################################################" >>${LogBakIfx}
                        export DATABASE
                        backup_IfxBases ${INSTANCE} ${DATABASE} 1>>${LogBakIfx} 2>&1
                        Test_DblBackup ${DirBakIfx}/${INSTANCE}/${DATABASE} 1>>${LogBakIfx}2>&1
                done
        done

#...............................................................................
# Suppression des n sauvegardes précedentes
#...............................................................................
       Remove_Backup ${DirBak}/informix 8 >>${LogBakIfx}

#...............................................................................
#Historisation de la sauvegarde courante
#...............................................................................
        Histo_Dech ${DirBak}/informix 1>>${LogBakIfx} 2>&1

        unset DateNow
        export DateNow=`date`
        echo "FIN BACKUP INFORMIX du: ${DateNow}" >>${LogBakIfx}
fi

}
###############################################################################
# FONCTION        MAIN
# LIBELLE        Fonction principale
# TYPE          NORMAL
# ARGUMENTS        NON
# ENTREE        AUCUN
# RETOUR        AUCUN
# DESCRIPTION        entree du programme
###############################################################################
#...............................................................................
# Export des fonctions du script
#...............................................................................
export -f Genere_IfxScript
export -f Unload_IfxTable
export -f Compress_IfxTable
export -f Histo_Dech
export -f Test_DblBackup
export -f backup_IfxBases
export -f backup_informix

#...............................................................................
# Definition des variables de scripts
#...............................................................................
unset BakDate
export BakDate=`date --iso-8601`

unset DirBak
export DirBak=/home/backup

unset DirBakIfx
export DirBakIfx=${DirBak}/informix/${BakDate}

unset DirLog
export DirLog=/var/log/backup

unset LogBakIfx
export LogBakIfx=${DirLog}/informix/${BakDate}.log

#...............................................................................
# Vérification des variables de scripts
#...............................................................................
if [ -z "${BakDate}" ]
then
        exit 1
fi

if [ ! -d ${DirBak} ]
then
        mkdir ${DirBak}
        chown root:backup ${DirBak}
        mkdir ${DirBak}/informix
        chown informix:backup ${DirBak}/informix
fi

if [ ! -d ${DirBak}/informix ]
then
        mkdir ${DirBak}/informix
        chown informix:backup ${DirBak}/informix
fi

if [ ! -d ${DirBakIfx} ]
then
        mkdir ${DirBakIfx}
        chown informix:backup ${DirBakIfx}
fi

if [ ! -d ${DirLog} ]
then
        mkdir ${DirLog}
        chown root:backup ${DirLog}
        mkdir ${DirLog}/informix
        chown informix:backup ${DirLog}/informix
fi

if [ ! -d ${DirLog}/informix ]
then
        mkdir ${DirLog}/informix
        chown informix:backup ${DirLog}/informix
fi

#...............................................................................
# On passe en tant qu'utilisateur informix sans son environnement
#...............................................................................
su informix -p -c backup_informix

Voilà, vous aurez au final un dossier par jour dans /home/backup/informix, contenant un sous dossier par instance, lui-même contenant un sous dossier par base de données, lui-même contenant un fichier .cmd représentant le schéma de la table et le fichier .out.gz qui lui est associé et contenant les données BRUT en texte prêtes à être rechargées en base (fichier gzip).

1 commentaire

backup des bases des instances Informix 16 juillet 2007 Krimm
Un dbexport aurait suffit non ???
 

Poster un nouveau commentaire


Modération de ce forum :

Ce forum est modéré à priori : votre contribution n'apparaîtra qu'après avoir été validée par un administrateur du site.


Emoticones :

(Pour insérer un émoticone, cliquez simplement sur l'image.)

:Thumbs::aime::bof::clindoeil::diable::en_colere::etoile::exclamation::fleur::interrogation::langue::lol::lunettes::mouai::pas_content::pleure_de_rire::rigolo::sourire::surprit::triste::xtra:

Titre :

Texte de votre message :

(Pour créer des paragraphes, laissez simplement des lignes vides.)


Lien hypertexte (optionnel)

(Si votre message se réfère à un article publié sur le Web, ou à une page fournissant plus d'informations, vous pouvez indiquer ci-après le titre de la page et son adresse.)


Qui êtes-vous ? (optionnel)


Articles les plus consultés

Téléchargez Firefox !

Libricks.org est motorisé par le logiciel libre Spip 1.8.3 associé au squelette graphique BliP 0.91

16 rubriques ... 30 articles ... 18 commentaires ... 28 sites référencés ... 50 visiteurs par jour (99041 au total)

Haut de page | XHTML 1.0 | CSS 2