316c109d76fa526e0ad04a5e076f7654c04c473e
[matthijs/upstream/backupninja.git] / handlers / mysql.in
1 # -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*-
2 #
3 # mysql handler script for backupninja
4 #
5
6 getconf backupdir /var/backups/mysql
7 getconf databases all
8 getconf ignores
9 getconf nodata
10 getconf dbhost localhost
11 getconf hotcopy no
12 getconf sqldump no
13 getconf sqldumpoptions "--lock-tables --complete-insert --add-drop-table --quick --quote-names"
14 getconf compress yes
15 getconf vsname
16
17 # authentication:
18 getconf user
19 getconf dbusername
20 getconf dbpassword
21 getconf configfile /etc/mysql/debian.cnf
22
23
24 # Decide if the handler should operate on a vserver or on the host.
25 # In the former case, check that $vsname exists and is running.
26 local usevserver=no
27 local vroot
28 if [ $vservers_are_available = yes ]; then
29    if [ -n "$vsname" ]; then
30       # does it exist ?
31       if ! vservers_exist "$vsname" ; then
32          fatal "The vserver given in vsname ($vsname) does not exist."
33       fi
34       # is it running ?
35       vservers_running $vsname || fatal "The vserver $vsname is not running."
36       # everything ok
37       info "Using vserver '$vsname'."
38       usevserver=yes
39    else
40       info "No vserver name specified, actions will be performed on the host."
41    fi
42 else
43    [ -z "$vsname" ] || warning 'vservers support disabled in backupninja.conf, vsname configuration line will be ignored'
44 fi
45
46 ## Prepare ignore part of the command
47 ## This only works for mysqldump at the moment
48
49 ignore=''
50 for i in $ignores $nodata; do
51        ignore="$ignore --ignore-table=$i"
52 done
53
54 if [ $usevserver = yes ]; then
55    vroot="$VROOTDIR/$vsname"
56    vexec="$VSERVER $vsname exec"
57 else
58    vroot=""
59    vexec=""
60 fi
61
62 # create backup dirs, $vroot will be empty if no vsname was specified
63 # and we will instead proceed to operate on the host
64 [ -d $vroot$backupdir ] || mkdir -p $vroot$backupdir
65 [ -d $vroot$backupdir ] || fatal "Backup directory '$vroot$backupdir'"
66 hotdir="$backupdir/hotcopy"
67 dumpdir="$backupdir/sqldump"
68
69 [ "$sqldump" == "no" -o -d $vroot$dumpdir ] || mkdir -p $vroot$dumpdir
70 [ "$hotcopy" == "no" -o -d $vroot$hotdir ] || mkdir -p $vroot$hotdir
71
72 #######################################################################
73 ## AUTHENTICATION
74
75 #
76 # one of three authentication methods:
77 # 1. setting the user, so that /home/user/.my.cnf is used.
78 # 2. specifying the user and password in the handler config,
79 #    which generates a temporary .my.cnf in /root/.my.cnf
80 # 3. specify the config file with --defaults-extra-file
81 #    (this option DOESN'T WORK WITH MYSQLHOTCOPY)
82 #
83
84 # create .my.cnf
85 # only if dbusername and dbpassword specified.
86 # we create a tmp file because we don't want to
87 # specify the password on the command line.
88
89 defaultsfile=""
90
91 if [ "$dbusername" != "" -a "$dbpassword" != "" ]
92 then
93     vhome=`$vexec getent passwd "root" | @AWK@ -F: '{print $6}'`
94     home=$vroot$vhome
95
96     [ -d $home ] || fatal "Can't find root's home directory ($home)."
97     
98     mycnf="$home/.my.cnf"
99     
100     if [ -f $mycnf ]
101     then
102         # rename temporarily
103         tmpcnf="$home/my.cnf.disable"
104         debug "mv $mycnf $tmpcnf"
105         mv $mycnf $tmpcnf
106     fi
107     
108     oldmask=`umask`
109     umask 077
110     cat > $mycnf <<EOF
111 # auto generated backupninja mysql conf
112 [mysql]
113 host=$dbhost
114 user=$dbusername
115 password="$dbpassword"
116
117 [mysqldump]
118 host=$dbhost
119 user=$dbusername
120 password="$dbpassword"
121
122 [mysqlhotcopy]
123 host=$dbhost
124 user=$dbusername
125 password="$dbpassword"
126 EOF
127         umask $oldmask
128         defaultsfile="--defaults-extra-file=$vhome/.my.cnf"
129 fi
130
131 # if a user is not set, use $configfile, otherwise use $mycnf
132 if [ "$user" == "" ]; then
133         user=root;
134         defaultsfile="--defaults-extra-file=$configfile"
135 else
136         userset=true;
137         if [ $usevserver = yes ]
138         then
139             vuserhome=`$vexec getent passwd "$user" | @AWK@ -F: '{print $6}'`
140             if [ $? -eq 2 ]
141             then
142                 fatal "User $user not found in /etc/passwd"
143             fi
144             userhome="$vroot$vuserhome"
145         fi
146         
147         debug "User home set to: $userhome"
148         [ -f $userhome/.my.cnf ] || fatal "Can't find config file in $userhome/.my.cnf"
149         defaultsfile="--defaults-extra-file=$vuserhome/.my.cnf"
150         debug "using $defaultsfile"
151 fi
152
153 #######################################################################
154 ## HOT COPY
155
156 if [ "$hotcopy" == "yes" ]
157 then
158     info "Initializing hotcopy method"
159     if [ "$databases" == "all" ]
160     then
161         info "dbhost: $dbhost"
162         execstr="$vexec $MYSQLHOTCOPY -h $dbhost --quiet --allowold --regexp /.\*/./.\*/ $hotdir"
163
164         debug "su $user -c \"$execstr\""
165         if [ ! $test ]
166         then
167                 output=`su $user -c "$execstr" 2>&1`
168                 code=$?
169                 if [ "$code" == "0" ]
170                 then
171                         debug $output
172                         info "Successfully finished hotcopy of all mysql databases"
173                 else
174                         warning $output
175                         warning "Failed to hotcopy all mysql databases"
176                 fi
177         fi
178     else        
179         for db in $databases
180         do
181                 execstr="$vexec $MYSQLHOTCOPY -h $dbhost --allowold $db $hotdir"
182
183                 debug 'su $user -c \"$execstr\"'
184                 if [ ! $test ]
185                 then
186                         output=`su $user -c "$execstr" 2>&1`
187                         code=$?
188                         if [ "$code" == "0" ]
189                         then
190                                 debug $output
191                                 info "Successfully finished hotcopy of mysql database $db"
192                         else
193                                 warning $output
194                                 warning "Failed to hotcopy mysql database $db"
195                         fi
196                 fi
197         done
198      fi
199 fi
200
201 ##########################################################################
202 ## SQL DUMP
203
204 if [ "$sqldump" == "yes" ]
205 then
206     info "Initializing SQL dump method"
207     if [ "$databases" == "all" ]
208     then
209         debug "$vexec su $user -c \"$MYSQL $defaultsfile -N -B -e 'show databases'\" | sed 's/|//g;/\+----/d'"
210         # -N removes the column title and -B should remove the ASCII table borders, but doesn't always so we use sed to make sure.
211         databases=`$vexec su $user -c "$MYSQL $defaultsfile -N -B -e 'show databases'" | sed 's/|//g;/\+----/d'`
212         if [ $? -ne 0 ]
213         then
214             fatal "Authentication problem, maybe user/password is wrong or mysqld is not running?"
215         fi
216     fi
217
218         for db in $databases
219         do
220            DUMP_BASE="$MYSQLDUMP $defaultsfile $sqldumpoptions"
221
222            # Dumping structure and data
223            DUMP="$DUMP_BASE $ignore $db"
224
225            # If requested, dump only the table structure for this database
226            if echo "$nodata" | grep -E '(^|[[:space:]])'"$db\." >/dev/null
227            then
228               # Get the structure of the tables, without data
229               DUMP_STRUCT="$DUMP_BASE --no-data $db"
230               for qualified_table in $nodata
231               do
232                  table=$( expr match "$qualified_table" "$db\.\([^\w]*\)" )
233                  DUMP_STRUCT="$DUMP_STRUCT $table"
234               done
235               DUMP="( $DUMP; $DUMP_STRUCT )"
236            fi
237                 # Test to make sure mysqld is running, if it is not sqldump will not work
238                 $vexec su $user -c "$MYSQLADMIN $defaultsfile ping"
239                 if [ $? -ne 0 ]; then
240                    fatal "Either you have an authentication problem, or mysqld doesn't appear to be running!"
241                 fi
242                 if [ "$compress" == "yes" ]; then
243                    execstr="$vexec $DUMP | $GZIP > $vroot$dumpdir/${db}.sql.gz"
244                 else
245                    execstr="$vexec $DUMP -r $vroot$dumpdir/${db}.sql"
246                 fi
247
248                 debug "su $user -c \"$execstr\""
249                 if [ ! $test ]
250                 then
251                         output=`su $user -c "$execstr" 2>&1`
252                         code=$?
253                         if [ "$code" == "0" ]
254                         then
255                                 debug $output
256                                 info "Successfully finished dump of mysql database $db"
257                         else
258                                 warning $output
259                                 warning "Failed to dump mysql databases $db"
260                         fi
261                 fi
262         done
263 fi
264
265 # clean up tmp config file
266 if [ "$dbusername" != "" -a "$dbpassword" != "" ]
267 then
268         ## clean up tmp config file
269         debug "rm $mycnf"
270         rm $mycnf
271         if [ -f "$tmpcnf" ]
272         then
273                 debug "mv $tmpcnf $mycnf"
274                 mv $tmpcnf $mycnf
275         fi
276 fi
277
278 return 0