root/trunk/tools/zbackup.sh

Revision 190, 7.5 kB (checked in by ssteinpreis, 4 years ago)

tid13485 consolidated version of various zbackup.sh scripts

  • Property svn:executable set to *
Line 
1 #!/bin/sh
2
3 BASESNAP=lastfull
4 INCREMENTAL=no
5 BACKUPCONF=/export/home/postgres/etc/zbackup.conf
6 BFILE=/var/log/pgods-backup.filelist
7 BPCMD=/usr/openv/netbackup/bin/bpbackup
8 BPLOG=/var/log/netbackup_backup.log
9 BPCLASS=PGods
10 BPSCHED=PGODS.UserBackup
11 RUN=true
12 INCDUMPDIR=/tmp
13 BMODE=ONLINE
14 DATAPREFIX=''
15 #DATAPREFIX=data/zfs_backups/userscape/
16 SEND=''
17 TARGET=''
18 PATH=$PATH:/usr/sbin
19 PGBINDIR=/opt/pgsql8311/bin
20 DATABASE_PORT=5432
21
22 Usage() {
23 cat <<EOF
24 $0: [-f] [-i] [-n] -p <port_number> -m <online> <offline> -s <netbackup> <zfs> -t <zfs send target> -l <label>
25         -m              backup mode <online> or <offline>  (default online)
26         -n              just describe the process (don't do it).
27         -p              port which database runs on (default 5432)
28         -s              use Netbackup or ZFS send.
29         -t              target for ZFS send.
30         -f              force a backup even if one is running.
31         -i              perform an incremental since the last full (implies -s).
32         -l <label>      backup using label: <label>
33 EOF
34 }
35
36   set -- `getopt fis:t:m:np:l: $*`
37   if [ $? != 0 ]
38   then
39     Usage
40     exit 2
41   fi
42   for i in $*
43   do
44     case $i in
45       -f)           FORCE=yes; shift;;
46       -s)           SEND=`echo $2 | tr '[:lower:]' '[:upper:]'`; shift 2;;
47       -t)           TARGET=$2; shift 2;;
48       -i)           INCREMENTAL=yes; shift;;
49       -l)           BACKUPLABEL=$2; shift 2;;
50       -p)           DATABASE_PORT=$2; shift 2;;
51       -m)           BMODE=`echo $2 | tr '[:lower:]' '[:upper:]'`; shift 2;;
52       -n)           RUN=false; shift;;
53       --)           shift; break;;
54     esac
55   done
56
57 if test "$SEND" = "ZFS" -a -z "$TARGET"; then
58         echo "\nZFS send requires -t TARGET\n"
59         Usage
60         exit 1
61 fi
62
63 if test -z "$BACKUPLABEL"; then
64   BACKUPLABEL=`date +%Y%m%d`
65 fi
66
67 echo "$0:"
68 echo "  backuplabel: $BACKUPLABEL"
69 if test "$INCREMENTAL" = "yes"; then
70   SNAPNAME="incremental"_$BACKUPLABEL
71   HISNAP=`zfs list -t snapshot -o name | egrep -i 'lastfull|incremental' | cut -f2 -d"@" | cut -f2 -d'_' | uniq | sort | tail -1`
72   BASESNAP=`zfs list -t snapshot -o name | grep $HISNAP | cut -f2 -d"@" | tail -1`
73   BFILE="$BFILE.i"
74   echo "  incremental"
75 else
76   SNAPNAME=${BASESNAP}_${BACKUPLABEL}
77   echo "  full"
78 fi
79
80 sanity() {
81   if test -f $BFILE -a "x$FORCE" != "xyes" ; then
82     echo "backup in progress ($BFILE exists)."
83     exit
84   fi
85
86   for ZPOOL in `zfs list -o name,mountpoint | sed '/^NAME/d;s/  */:/g' | grep -v '@'`
87         do
88             REPORT_POOL=`echo ${ZPOOL} | cut -f1 -d':'`
89             REPORT_MOUNT=`echo ${ZPOOL} | cut -f2 -d':'`
90             FOUND=`grep "${REPORT_POOL} ${REPORT_MOUNT}" $BACKUPCONF`
91             if test -z "$FOUND"; then
92                 echo "WARNING: ${REPORT_POOL} on ${REPORT_MOUNT} is not present in $BACKUPCONF"
93             fi
94         done
95
96
97   for LINE in `grep "^Y" $BACKUPCONF | sed 's/ /:/'g | cut -f2 -d':'`
98   do
99         FULL_EXISTS=`zfs list -t snapshot -o name | grep -i lastfull | grep ${LINE}`
100         if test "$INCREMENTAL" != "yes" -a "$FULL_EXISTS"  ; then
101         echo "Base snapshot for "${LINE}" already exists."
102         exit
103         fi
104         if test "$INCREMENTAL" = "yes" -a -z "$FULL_EXISTS"; then
105         echo "We don't have a base snap for "${LINE}" for incremental backups."
106         exit
107         fi
108   done
109 }
110
111 postgres_start_backup() {
112   echo "starting postgres backup on label $BACKUPLABEL"
113   $RUN && su - postgres -c "${PGBINDIR}/psql -p $DATABASE_PORT -c \"CHECKPOINT;\""
114   $RUN && su - postgres -c "${PGBINDIR}/psql -p $DATABASE_PORT -c \"SELECT pg_start_backup('$BACKUPLABEL');\""
115 }
116 postgres_stop_backup() {
117   echo "stopping postgres backup on label $BACKUPLABEL"
118   $RUN && su - postgres -c "${PGBINDIR}/psql -p $DATABASE_PORT -c \"SELECT pg_stop_backup();\""
119 }
120
121 snap() {
122   for line in `sed -e 's/ /:/g;' < $BACKUPCONF`
123   do
124     DO=`echo $line | awk -F: '{print $1;}'`
125     ZFS=`echo $line | awk -F: '{print $2;}'`
126 #    MOUNT=`echo $line | awk -F: '{print $3;}'`
127     if test "$DO" = "Y"; then
128       echo "zfs snapshot $ZFS@$SNAPNAME"
129       $RUN && /sbin/zfs snapshot $ZFS@$SNAPNAME
130     fi
131   done
132 }
133
134 clear_full() {
135   if test "$INCREMENTAL" != "yes"; then
136     FULL_DATE=`date +%Y%m%d`
137     for line in `sed -e 's/ /:/g;' < $BACKUPCONF | grep "^Y"`
138         do
139           ZFS=`echo $line | awk -F: '{print $2;}'`
140           for OLD_SNAPNAME in `zfs list -t snapshot -o name | grep -i lastfull | grep -i ${ZFS} |  grep -v ${FULL_DATE}`
141         do
142           echo "zfs destroy $OLD_SNAPNAME"
143           $RUN && /sbin/zfs destroy $OLD_SNAPNAME
144         done
145         done
146   fi
147 }
148
149 clear_incrementals() {
150   zfs list -t snapshot -o name,creation | grep "incremental_" | cut -f1 -d' ' | grep -v $BACKUPLABEL |
151    while read SNAPLABEL
152        do
153              echo "zfs destroy $SNAPLABEL";
154              $RUN && /sbin/zfs destroy $SNAPLABEL
155        done
156 }
157
158 backup() {
159   BACKEDUP="no"
160   $RUN && touch $BFILE
161   for line in `sed -e 's/ /:/g;' < $BACKUPCONF`
162   do
163     DO=`echo $line | awk -F: '{print $1;}'`
164     ZFS=`echo $line | awk -F: '{print $2;}'`
165     MOUNT=`echo $line | awk -F: '{print $3;}'`
166     if test "$DO" = "Y"; then
167       if test "$INCREMENTAL" = "yes"; then
168         FILE=`echo $ZFS | sed -e 's/\//:/g;'`
169         echo "/sbin/zfs send -i $ZFS@$BASESNAP $ZFS@$SNAPNAME  >> $INCDUMPDIR/$FILE.$SNAPNAME.incremental"
170         $RUN && mkfifo $INCDUMPDIR/$FILE.$SNAPNAME.incremental
171         $RUN && /sbin/zfs send -i $ZFS@$BASESNAP $ZFS@$SNAPNAME  >> $INCDUMPDIR/$FILE.$SNAPNAME.incremental &
172         $RUN && $BPCMD -w -c $BPCLASS -s $BPSCHED -k "INCREMENTAL" -L $BPLOG $INCDUMPDIR/$FILE.$SNAPNAME.incremental &
173         elif test "$INCREMENTAL" != "yes"; then
174 #elif test "$SEND" = "NETBACKUP"; then
175         FILE=`echo $ZFS | sed -e 's/\//:/g;'`
176         echo "/sbin/zfs send $ZFS@$SNAPNAME  >> $INCDUMPDIR/$FILE.$SNAPNAME.full"
177         $RUN && mkfifo $INCDUMPDIR/$FILE.$SNAPNAME.full
178         $RUN && /sbin/zfs send $ZFS@$SNAPNAME  >> $INCDUMPDIR/$FILE.$SNAPNAME.full &
179         $RUN && $BPCMD -w -c $BPCLASS -s $BPSCHED -k "FULL" -L $BPLOG $INCDUMPDIR/$FILE.$SNAPNAME.full &
180       else
181         # Normal tar-like backups happen "on the spot" and in parallel
182         echo $MOUNT/.zfs/snapshot/$SNAPNAME
183         $RUN && $BPCMD -w -c $BPCLASS -s $BPSCHED -k "FULL" -L $BPLOG $MOUNT/.zfs/snapshot/$SNAPNAME &
184       fi
185     fi
186   done
187
188   # Wait for our ZFS send commands to finish (they should be done already)
189   wait
190   $RUN && rm $BFILE
191 }
192
193 zfs_send() {
194     for line in `sed -e 's/ /:/g;' < $BACKUPCONF`
195     do
196       DO=`echo $line | awk -F: '{print $1;}'`
197       ZFS=`echo $line | awk -F: '{print $2;}'`
198       if test "$DO" = "Y"; then
199         if test "$SEND" = "ZFS"; then
200         if test "$INCREMENTAL" = "yes"; then
201           echo "ssh $TARGET zfs rollback -r $DATAPREFIX$ZFS@$BASESNAP"
202           echo "zfs send -i $ZFS@$BASESNAP $ZFS@$SNAPNAME | ssh $TARGET zfs receive -F $DATAPREFIX$ZFS@$SNAPNAME"
203           $RUN && ssh $TARGET zfs rollback -r $DATAPREFIX$ZFS@$BASESNAP
204           $RUN && /sbin/zfs send -i $ZFS@$BASESNAP $ZFS@$SNAPNAME | ssh $TARGET zfs receive -F $DATAPREFIX$ZFS@$SNAPNAME
205         else
206           echo "zfs send $ZFS@$SNAPNAME | ssh $TARGET zfs receive -F $DATAPREFIX$ZFS@$SNAPNAME"
207           $RUN && /sbin/zfs send $ZFS@$SNAPNAME | ssh $TARGET zfs receive -F $DATAPREFIX$ZFS@$SNAPNAME
208         fi
209         fi
210       fi
211     done
212 }
213
214
215 # This clears the full snapshot only if -i (and -n) isn't specified
216
217 clear_full
218 sanity
219 echo "Backing up as '$BACKUPLABEL'"
220
221 if test "$BMODE" = "ONLINE" ; then
222         postgres_start_backup
223         snap
224         postgres_stop_backup
225 else
226         snap
227 fi
228
229 if test "$SEND" = "NETBACKUP" -a -f $BPCMD; then
230 backup
231 fi
232
233 if test "$SEND" = "ZFS"; then
234 zfs_send
235 fi
236
237 clear_incrementals
Note: See TracBrowser for help on using the browser.