root/trunk/tools/zbackup.sh

Revision 10, 5.2 kB (checked in by jesus, 6 years ago)

netbackup zfs postgres symbiosis

  • Property svn:executable set to *
Line 
1 #!/bin/sh
2
3 BASESNAP=lastfull
4 INCREMENTAL=no
5 BACKUPCONF=/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
14 usage() {
15 cat <<EOF
16 $0: [-f] [-i] [-n] [-s] -l <label>
17         -n              just describe the process (don't do it).
18         -s              use ZFS send.
19         -f              force a backup even if one is running.
20         -i              perform an incremental since the last full (implies -s).
21         -l <label>      backup using label: <label>
22 EOF
23 }
24
25   set -- `getopt fisnl: $*`
26   if [ $? != 0 ]
27   then
28     usage
29     exit 2
30   fi
31   for i in $*
32   do
33     case $i in
34       -f)           FORCE=yes; shift;;
35       -s)           SEND=yes; shift;;
36       -i)           INCREMENTAL=yes; shift;;
37       -l)           BACKUPLABEL=$2; shift 2;;
38       -n)           RUN=false; shift;;
39       --)           shift; break;;
40     esac
41   done
42
43 if test -z "$BACKUPLABEL"; then
44   BACKUPLABEL=`date +%Y%m%d`
45 fi
46
47 echo "$0:"
48 echo "  backuplabel: $BACKUPLABEL"
49 if test "$INCREMENTAL" = "yes"; then
50   SNAPNAME=$BACKUPLABEL
51   BFILE="$BFILE.i"
52   echo "  incremental"
53 else
54   SNAPNAME=$BASESNAP
55   echo "  full"
56 fi
57
58 sanity() {
59   MATCHCNT=0
60   SNAPCNT=0
61   if test -f $BFILE -a "x$FORCE" != "xyes" ; then
62     echo "backup in progress ($BFILE exists)."
63     exit
64   fi
65   for line in `zfs list -H | awk '{print $1":"$5;}'`
66   do
67     ZFS=`echo $line | awk -F: '{print $1;}'`
68     MOUNT=`echo $line | awk -F: '{print $2;}'`
69     MATCH=`grep '^[YN] '$ZFS' '$MOUNT'$' $BACKUPCONF`
70     USE=`echo $MATCH | awk '{print $1;}'`
71     SNAP=`echo $ZFS | awk -F@ '{print $2;}'`
72     # Here, if we have the snap and we're in "full" node, we die
73     if test "X$SNAP" = "X$BASESNAP"; then
74       if test "$INCREMENTAL" != "yes" ; then
75         echo "Base snapshot already exists."
76         exit
77       fi
78       # These are the base snapshots off which we'll do incrementals
79       if test -z "$MATCH"; then
80         SNAPCNT=`expr $SNAPCNT + 1`
81       fi
82     fi
83     if test -z "$MATCH" -a -z "$SNAP" ; then
84       echo "WARNING: $ZFS on $MOUNT is not present in $BACKUPCONF"
85     fi
86     if test -z "$SNAP" -a "$USE" = "Y" ; then
87       # These are the "real" mounts we want to backup
88       MATCHCNT=`expr $MATCHCNT + 1`
89     fi
90   done
91
92   # or, if we don't have the snaps and we're in incremental mode, we die
93   if test "$SNAPCNT" != "$MATCHCNT" -a "$INCREMENTAL" = "yes"; then
94     echo "We don't have base snaps for incremental backups."
95     exit
96   fi
97 }
98
99 postgres_start_backup() {
100   echo "starting postgres backup on label $BACKUPLABEL"
101   $RUN && su - postgres -c "/bin/psql -c \"CHECKPOINT;\""
102   $RUN && su - postgres -c "/bin/psql -c \"SELECT pg_start_backup('$BACKUPLABEL');\""
103 }
104 postgres_stop_backup() {
105   echo "stopping postgres backup on label $BACKUPLABEL"
106   $RUN && su - postgres -c "/bin/psql -c \"SELECT pg_stop_backup();\""
107 }
108
109 snap() {
110   for line in `sed -e 's/ /:/g;' < $BACKUPCONF`
111   do
112     DO=`echo $line | awk -F: '{print $1;}'`
113     ZFS=`echo $line | awk -F: '{print $2;}'`
114     MOUNT=`echo $line | awk -F: '{print $3;}'`
115     if test "$DO" = "Y"; then
116       echo "zfs snapshot $ZFS@$SNAPNAME"
117       $RUN && /sbin/zfs snapshot $ZFS@$SNAPNAME
118     fi
119   done
120 }
121
122 clear_full() {
123   if test "$INCREMENTAL" != "yes"; then
124     for line in `sed -e 's/ /:/g;' < $BACKUPCONF`
125     do
126       DO=`echo $line | awk -F: '{print $1;}'`
127       ZFS=`echo $line | awk -F: '{print $2;}'`
128       if test "$DO" = "Y"; then
129         echo "zfs destroy $ZFS@$SNAPNAME"
130         $RUN && /sbin/zfs destroy $ZFS@$SNAPNAME
131       fi
132     done
133   fi
134 }
135
136 backup() {
137   BACKEDUP="no"
138   $RUN && touch $BFILE
139   for line in `sed -e 's/ /:/g;' < $BACKUPCONF`
140   do
141     DO=`echo $line | awk -F: '{print $1;}'`
142     ZFS=`echo $line | awk -F: '{print $2;}'`
143     MOUNT=`echo $line | awk -F: '{print $3;}'`
144     if test "$DO" = "Y"; then
145       if test "$INCREMENTAL" = "yes"; then
146         FILE=`echo $ZFS | sed -e 's/\//:/g;'`
147         echo "/sbin/zfs send -i $ZFS@$BASESNAP $ZFS@$SNAPNAME | /bin/bzip2 -3c >> $INCDUMPDIR/$FILE.$SNAPNAME.incremental"
148         $RUN && mkfifo $INCDUMPDIR/$FILE.$SNAPNAME.incremental
149         $RUN && /sbin/zfs send -i $ZFS@$BASESNAP $ZFS@$SNAPNAME >> $INCDUMPDIR/$FILE.$SNAPNAME.incremental &
150         $RUN && $BPCMD -w -c $BPCLASS -s $BPSCHED -L $BPLOG $INCDUMPDIR/$FILE.$SNAPNAME.incremental &
151       elif test "$SEND" = "yes"; then
152         FILE=`echo $ZFS | sed -e 's/\//:/g;'`
153         echo "/sbin/zfs send $ZFS@$SNAPNAME >> $INCDUMPDIR/$FILE.$SNAPNAME.full"
154         $RUN && mkfifo $INCDUMPDIR/$FILE.$SNAPNAME.full
155         $RUN && /sbin/zfs send $ZFS@$SNAPNAME >> $INCDUMPDIR/$FILE.$SNAPNAME.full &
156         $RUN && $BPCMD -w -c $BPCLASS -s $BPSCHED -L $BPLOG $INCDUMPDIR/$FILE.$SNAPNAME.full &
157       else
158         # Normal tar-like backups happen "on the spot" and in parallel
159         echo $MOUNT/.zfs/snapshot/$SNAPNAME
160         $RUN && $BPCMD -w -c $BPCLASS -s $BPSCHED -L $BPLOG $MOUNT/.zfs/snapshot/$SNAPNAME &
161       fi
162     fi
163   done
164
165   # Wait for our ZFS send commands to finish (they should be done already)
166   wait
167   $RUN && rm $BFILE
168 }
169
170 # This clears the full snapshot only if -i (and -n) isn't specified
171 clear_full
172 sanity
173 echo "Backing up as '$BACKUPLABEL'"
174 postgres_start_backup
175 snap
176 postgres_stop_backup
177 backup
178
Note: See TracBrowser for help on using the browser.