Reputation: 127
I made this script to backup and restore an Informix database. It's a menu with two functions that will give you two choices: to backup or restore a database.
The script will use dbexport then archive the backup to a directory.
To restore the database, I used dbimport.
#!/bin/sh
###################################################################################
#Usage ./impexp.sh BASE USER ARCHIVE
###################################################################################
LOGO="DB IMPEXP"
#------------------------------------------------------
# Definition des variables
#------------------------------------------------------
BASE=$1
USER=$2
ARCHIVE=$3
export DBSTOR=/stored/bdd
export TEMPOF=/stored/tmp
ADATE=`date +%Y%m%d`
size_dbs=$(du "$BASE".exp | sed -e 's/\t.*$//')
size_dbs2=$((size_dbs*4))
#------------------------------------------------------
# MENU PROMPTS
#------------------------------------------------------
ymenu="y. backup BDD" ;
zmenu="z. restore archive " ;
#------------------------------------------------------
# MENU FUNCTION DEFINITIONS
#------------------------------------------------------
badchoice () { MSG="Invalid Selection ... Please Try Again" ; }
ypick () { echo "Backup BDD"
#------------------------------------------------
dbexport $BASE
mkdir -m 0777 -p "$DBSTOR"
tar -czvf $DBSTOR/$BASE.exp.$ADATE.tgz ./$BASE.exp && chmod 777 $DBSTOR/*
rm -rf ./$BASE.exp
rm -f ./dbexport.out
}
zpick () { echo "Restoring archive"
#---------------------------------------
cd $DBPATH
tar -xzvf $ARCHIVE
onspaces -a dbs_"$BASE"_01 -p /bases_data/data_"$BASE"_01.dbs -o 0 -s ${size_dbs2}
dbimport -q "$BASE" -d dbs_"$BASE"_01
echo "Import done"
}
#------------------------------------------------------
# DISPLAY FUNCTION DEFINITION
#------------------------------------------------------
themenu () {
# clear the screen
clear
echo `date`
echo
echo " " $LOGO
echo
echo " Please Select:"
echo
echo " " $ymenu
echo " " $zmenu
echo " "
echo " "
echo " x. Exit"
echo
echo $MSG
echo
echo Select by pressing the letter and then ENTER ;
}
MSG=
while true
do
themenu
read answer
MSG=
case $answer in
y|Y) ypick;;
z|Z) zpick;;
x|X) break;;
*) badchoice;;
esac
echo ""
echo "Press <ENTER> to return to the menu..."
read junk
clear
done
Sadly it doesn't work properly, especially the backup part where i have these error messages :
create database
225 - Cannot create file for system catalog (systables).
131 - ISAM error: no free disk space
./impexp.sh: line 61: import_erreur: command not found
Thank you.
Upvotes: 1
Views: 1208
Reputation: 754450
After some discussion in comments and amendments to the question, the problem appears to be primarily in the 'recover' stage, and it may be that the trouble is with creating enough space in the dbspace.
I'm going to mention here that I find DB-Access distressing to use. So distressing that I wrote a program now called sqlcmd
to work the way I wish DB-Access did. Consider using SQLCMD (available from the IIUG Software
Archive), which
I wrote to behave consistently in shell scripting contexts whereas
DB-Access doesn't.
It dates back to 1986 (before there was dbaccess
; in those days, you
used isql
instead — DB-Access was carved out of isql
in an
evening) and was originally called rdsql
.
It bears no relation to Microsoft's johnny-come-lately program of the
same name — except for the name and having the same general purpose
(manipulate SQL databases).
I mention it because scripting for "is there already a dbspace called 'xyz'?" becomes trivial:
dbspace="xyz"
if [ -n "$(sqlcmd -d sysmaster "select name from sysdbspaces where name = '$dbspace'") ]
then : dbspace exists - add space to it
else : dbspace does not exist - create it
fi
With DB-Access, this is harder. What should work is something along the lines of:
dbspace="xyz"
result=$(dbaccess sysmaster - 2>/dev/null <<EOF
select name from sysdbspaces where name = '$dbspace';
EOF
)
if [ -n "$result" ]
then : dbspace exists - add space to it
else : dbspace does not exist - create it
fi
This code should be encapsulated into a shell function or a shell script called dbspace_exists
that can be used by scripts. It should return 0 or exit with status 0 if the dbspace exists; it should return a non-zero value or exit with a non-zero status if the dbspace does not exist. (And it shouldn't generate any output by default!) I'd use a script because the performance impact is negligible and the clarity and reusability is much simpler. YMMV!
Chunk files must exist and have appropriate permissions before running onspaces
. The following works if the user running the script is root
or has system administrator privileges. Drop the
chown
line if necessary, but note that if the owner is not user informix, group informix, the new chunk path may not work at all.
cp /dev/null "$chunkpath"
chown informix:informix "$chunkpath"
chmod 660 "$chunkpath"
Your code keeps repeating some constructs — use variables so you stay DRY ("Don't Repeat Yourself").
You have something along the lines of:
cd $DBSTOR # Changed from DBPATH
tar -xzvf $ARCHIVE
onspaces -c -d dbs_"$BASE"_01 -p /bases_data/data_"$BASE"_01.dbs -o 0 -s ${size_dbs2}
dbimport -q "$BASE" -d dbs_"$BASE"_01
echo "Import done"
I think you need something more like:
cd "${DBSTOR}" || exit 1
tar -xzvf "${ARCHIVE}"
dbspace_name="dbs_${BASE}_01"
dbspace_path="/bases_data/${dbspace_name}.dbs"
if [ -f "$dbspace_path" ]
then
echo "$0: dbspace chunk file $dbspace_path already exists" >&2
exit 1
fi
cp /dev/null "$dbspace_path"
chown informix:informix "$dbspace_path"
chmod 660 "$dbspace_path"
if dbspace_exists "$dbspace_name"
then onspaces -a "$dbspace_name" -p "$dbspace_path" -o 0 -s "${size_dbs2}"
else onspaces -c -d "$dbspace_name" -p "$dbspace_path" -o 0 -s "${size_dbs2}"
fi
if [ "$?" != 0 ]
then
echo "$0: failed to create/expand dbspace $dbspace_name" >&2
exit 1
fi
if dbimport -q "$BASE" -d "$dbspace_name"
then echo "Import of $BASE done"
else
echo "Import of $BASE failed" >&2
exit 1
fi
# Remove the files extracted from the tar file
rm -fr …
exit 0
You should do an archive before trying to use the new dbspace — I've not integrated that into the script. Without the archive, the extra chunk may not be available.
There is still a lot of polishing to do.
Note the use of the braces in dbspace_name="dbs_${BASE}_01"
. This ensures that the variable name is ${BASE}
and not $BASE_01
. Your circumvention is effective but clumsy and not idiomatic shell. I usually quote variables, and often embed the variable names in braces `"${dbspace_name}". If you don't have spaces or strings touching the variable name, you can do without the extra punctuation, but it helps in the long run.
Upvotes: 1