fixes for mysql handler for mysqld inside a vserver
[matthijs/upstream/backupninja.git] / handlers / mysql.in
index de4e4c3d2f920d8117c2e960e9c1f5e1619ccf22..6e894fee967d19a864e034e6bc5ba0fb48a25fda 100644 (file)
@@ -6,6 +6,7 @@
 getconf backupdir /var/backups/mysql
 getconf databases all
 getconf ignores
+getconf nodata
 getconf dbhost localhost
 getconf hotcopy no
 getconf sqldump no
@@ -30,10 +31,7 @@ if [ $vservers_are_available = yes ]; then
          fatal "The vserver given in vsname ($vsname) does not exist."
       fi
       # is it running ?
-      $VSERVERINFO -q $vsname RUNNING
-      if [ $? -ne 0 ]; then
-         fatal "The vserver $vsname is not running."
-      fi
+      vservers_running $vsname || fatal "The vserver $vsname is not running."
       # everything ok
       info "Using vserver '$vsname'."
       usevserver=yes
@@ -47,7 +45,7 @@ fi
 ## This only works for mysqldump at the moment
 
 ignore=''
-for i in $ignores; do
+for i in $ignores $nodata; do
        ignore="$ignore --ignore-table=$i"
 done
        
@@ -90,8 +88,7 @@ if [ "$dbusername" != "" -a "$dbpassword" != "" ]
 then
     if [ $usevserver = yes ]
     then
-       vhome=`$VSERVER $vsname exec getent passwd "root" | @AWK@ -F: '{print $6}'`
-       home="$vroot$vhome"
+       home=`$VSERVER $vsname exec getent passwd "root" | @AWK@ -F: '{print $6}'`
     else
        home=`getent passwd "root" | @AWK@ -F: '{print $6}'`
     fi
@@ -99,18 +96,25 @@ then
     [ -d $home ] || fatal "Can't find root's home directory ($home)."
     
     mycnf="$home/.my.cnf"
-    
-    if [ -f $mycnf ]
+
+    if [ $usevserver = yes ]
+    then
+      workcnf="$vroot$mycnf"
+    else
+      workcnf="$mycnf"
+    fi
+
+    if [ -f $workcnf ]
     then
-       # rename temporarily
-       tmpcnf="$home/my.cnf.disable"
-       debug "mv $mycnf $tmpcnf"
-       mv $mycnf $tmpcnf
+      # rename temporarily
+      tmpcnf="$workcnf.disable"
+      debug "mv $workcnf $tmpcnf"
+      mv $workcnf $tmpcnf
     fi
     
     oldmask=`umask`
     umask 077
-    cat > $mycnf <<EOF
+    cat > $workcnf <<EOF
 # auto generated backupninja mysql conf
 [mysql]
 host=$dbhost
@@ -126,14 +130,14 @@ password="$dbpassword"
 host=$dbhost
 user=$dbusername
 password="$dbpassword"
+
+[mysqladmin]
+host=$dbhost
+user=$dbusername
+password="$dbpassword"
 EOF
        umask $oldmask
-       if [ $usevserver = yes ] 
-       then
-           defaultsfile="--defaults-extra-file=$vhome/.my.cnf"
-       else
-           defaultsfile="--defaults-extra-file=$mycnf"
-       fi
+       defaultsfile="--defaults-extra-file=$mycnf"
 fi
 
 # if a user is not set, use $configfile, otherwise use $mycnf
@@ -144,22 +148,23 @@ else
        userset=true;
        if [ $usevserver = yes ]
        then
-           vuserhome=`$VSERVER $vsname exec getent passwd "$user" | @AWK@ -F: '{print $6}'`
+           userhome=`$VSERVER $vsname exec getent passwd "$user" | @AWK@ -F: '{print $6}'`
            if [ $? -eq 2 ]
            then
                fatal "User $user not found in /etc/passwd"
            fi
-           userhome="$vroot$vuserhome"
+           debug "User home set to: $vroot$userhome"
+           [ -f $vroot$userhome/.my.cnf ] || fatal "Can't find config file in $userhome/.my.cnf"
        else
            userhome=`getent passwd "$user" | @AWK@ -F: '{print $6}'`
            if [ $? -eq 2 ]
            then
                fatal "User $user not found in /etc/passwd"
            fi
-               fi
+           debug "User home set to: $userhome"
+           [ -f $userhome/.my.cnf ] || fatal "Can't find config file in $userhome/.my.cnf"
+       fi
        
-       debug "User home set to: $userhome"
-       [ -f $userhome/.my.cnf ] || fatal "Can't find config file in $userhome/.my.cnf"
        defaultsfile="--defaults-extra-file=$userhome/.my.cnf"
        debug "using $defaultsfile"
 fi
@@ -237,16 +242,33 @@ then
                fatal "Authentication problem, maybe user/password is wrong or mysqld is not running?"
            fi
        else
-               databases=`echo 'show databases' | su $user -c "$MYSQL $defaultsfile" | grep -v Database`
+               databases=$(su $user -c "$MYSQL $defaultsfile -N -B -e 'show databases'" | sed 's/|//g;/\+----/d')
                if [ $? -ne 0 ]
                then
                    fatal "Authentication problem, maybe user/password is wrong or mysqld is not running?"
                fi
        fi
-fi
+    fi
 
        for db in $databases
        do
+           DUMP_BASE="$MYSQLDUMP $defaultsfile --lock-tables --complete-insert --add-drop-table --quick --quote-names"
+
+           # Dumping structure and data
+           DUMP="$DUMP_BASE $ignore $db"
+
+           # If requested, dump only the table structure for this database
+           if echo "$nodata" | grep -E '(^|[[:space:]])'"$db\." >/dev/null
+           then
+              # Get the structure of the tables, without data
+              DUMP_STRUCT="$DUMP_BASE --no-data $db"
+              for qualified_table in $nodata
+              do
+                 table=$( expr match "$qualified_table" "$db\.\([^\w]*\)" )
+                 DUMP_STRUCT="$DUMP_STRUCT $table"
+              done
+              DUMP="( $DUMP; $DUMP_STRUCT )"
+           fi
                if [ $usevserver = yes ]
                then
                    # Test to make sure mysqld is running, if it is not sqldump will not work
@@ -255,9 +277,9 @@ fi
                       fatal "Either you have an authentication problem, or mysqld doesn't appear to be running!"
                    fi
                    if [ "$compress" == "yes" ]; then
-                      execstr="$VSERVER $vsname exec $MYSQLDUMP $defaultsfile --lock-tables --complete-insert --add-drop-table --quick --quote-names $ignore $db | $GZIP > $vroot$dumpdir/${db}.sql.gz"
+                      execstr="$VSERVER $vsname exec $DUMP | $GZIP > $vroot$dumpdir/${db}.sql.gz"
                    else
-                      execstr="$VSERVER $vsname exec $MYSQLDUMP $defaultsfile --lock-tables --complete-insert --add-drop-table --quick --quote-names $ignore $db -r $vroot$dumpdir/${db}.sql"
+                      execstr="$VSERVER $vsname exec $DUMP -r $vroot$dumpdir/${db}.sql"
                    fi
                else
                    # Test to make sure mysqld is running, if it is not sqldump will not work
@@ -266,9 +288,9 @@ fi
                       fatal "Either you have an authentication problem, or mysqld doesn't appear to be running!"
                    fi
                    if [ "$compress" == "yes" ]; then
-                      execstr="$MYSQLDUMP $defaultsfile --lock-tables --complete-insert --add-drop-table --quick --quote-names $ignore $db | $GZIP > $dumpdir/${db}.sql.gz"
+                      execstr="$DUMP | $GZIP > $dumpdir/${db}.sql.gz"
                    else
-                      execstr="$MYSQLDUMP $defaultsfile --lock-tables --complete-insert --add-drop-table --quick --quote-names $ignore $db -r $dumpdir/${db}.sql"
+                      execstr="$DUMP -r $dumpdir/${db}.sql"
                    fi
                fi
                debug "su $user -c \"$execstr\""
@@ -292,12 +314,12 @@ fi
 if [ "$dbusername" != "" -a "$dbpassword" != "" ]
 then
        ## clean up tmp config file
-       debug "rm $mycnf"
-       rm $mycnf
+       debug "rm $workcnf"
+       rm $workcnf
        if [ -f "$tmpcnf" ]
        then
-               debug "mv $tmpcnf $mycnf"
-               mv $tmpcnf $mycnf
+               debug "mv $tmpcnf $workcnf"
+               mv $tmpcnf $workcnf
        fi
 fi