# HG changeset patch
# User Marian Marinov <[email protected]>
# Date 1267490738 -7200
# Branch mysql-ms
# Node ID 0c1c598c4f5ab4e758f7140b29aab86b2d8cd1a5
# Parent  7c35f7fc2d3765060579a7c2328d8dc7dc684835
Medium: RA: mysql: added preference points calculation

Added preference points calculation during start, stop and monitor actions
Added do_cmd function (copy from drbd RA).

Maybe it will be a good idea to move CRM_MASTER and do_cmd to .ocf-shellfuncs

diff -r 7c35f7fc2d37 -r 0c1c598c4f5a heartbeat/mysql
--- a/heartbeat/mysql   Mon Mar 01 16:04:33 2010 +0100
+++ b/heartbeat/mysql   Tue Mar 02 02:45:38 2010 +0200
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# 
+#
 # MySQL
 #
 # Description: Manages a MySQL database as Linux-HA resource
@@ -17,7 +17,7 @@
 # License:     GNU General Public License (GPL)
 # Copyright:   (C) 2002 - 2005 International Business Machines, Inc.
 #
-# An example usage in /etc/ha.d/haresources: 
+# An example usage in /etc/ha.d/haresources:
 #       node1  10.0.0.170 mysql
 #
 # See usage() function below for more details...
@@ -51,6 +51,7 @@
 # Fill in some defaults if no values are specified
 HOSTOS=`uname`
 HOSTNAME=`uname -n`
+CRM_MASTER="${HA_SBIN_DIR}/crm_master -l reboot "
 
 if [ "X${HOSTOS}" = "XOpenBSD" ];then
 OCF_RESKEY_binary_default="/usr/local/bin/mysqld_safe"
@@ -130,7 +131,7 @@
 <version>1.1</version>
 
 <longdesc lang="en">
-Resource script for MySQL. 
+Resource script for MySQL.
 It manages a MySQL Database instance as an HA resource.
 </longdesc>
 <shortdesc lang="en">Manages a MySQL database instance</shortdesc>
@@ -227,7 +228,7 @@
 
 <parameter name="enable_creation" unique="0" required="0">
 <longdesc lang="en">
-If the MySQL database does not exist, it will be created 
+If the MySQL database does not exist, it will be created
 </longdesc>
 <shortdesc lang="en">Create the database if it does not exist</shortdesc>
 <content type="integer" default="${OCF_RESKEY_enable_creation_default}"/>
@@ -235,7 +236,7 @@
 
 <parameter name="additional_parameters" unique="0" required="0">
 <longdesc lang="en">
-Additional parameters which are passed to the mysqld on startup. 
+Additional parameters which are passed to the mysqld on startup.
 (e.g. --skip-external-locking or --skip-grant-tables)
 </longdesc>
 <shortdesc lang="en">Additional parameters to pass to mysqld</shortdesc>
@@ -299,18 +300,18 @@
        ocf_log err "Config $OCF_RESKEY_config doesn't exist";
        return $OCF_ERR_CONFIGURED;
     fi
-    
+
     if [ ! -d $OCF_RESKEY_datadir ]; then
        ocf_log err "Datadir $OCF_RESKEY_datadir doesn't exist";
        return $OCF_ERR_CONFIGURED;
     fi
-    
+
     getent passwd $OCF_RESKEY_user >/dev/null 2>&1
     if [ ! $? -eq 0 ]; then
        ocf_log err "User $OCF_RESKEY_user doesn't exit";
        return $OCF_ERR_INSTALLED;
     fi
-    
+
     getent group $OCF_RESKEY_group >/dev/null 2>&1
     if [ ! $? -eq 0 ]; then
        ocf_log err "Group $OCF_RESKEY_group doesn't exist";
@@ -330,6 +331,27 @@
     true
 }
 
+do_cmd() {
+    local cmd="$*"
+    ocf_log debug "$RESOURCE: Calling $cmd"
+    local cmd_out
+    cmd_out=$($cmd 2>&1)
+    ret=$?
+
+    if [ $ret -ne 0 ]; then
+        ocf_log err "$RESOURCE: Called $cmd"
+        ocf_log err "$RESOURCE: Exit code $ret"
+        ocf_log err "$RESOURCE: Command output: $cmd_out"
+    else
+        ocf_log debug "$RESOURCE: Exit code $ret"
+        ocf_log debug "$RESOURCE: Command output: $cmd_out"
+    fi
+
+    echo $cmd_out
+
+    return $ret
+}
+
 is_slave() {
     master_host=''
     master_user=''
@@ -376,7 +398,7 @@
                ocf_log debug "MySQL is not running"
                return $OCF_NOT_RUNNING;
        fi
-       
+
        pid=`cat $OCF_RESKEY_pid`;
        if [ -d /proc -a -d /proc/1 ]; then
                [ "u$pid" != "u" -a -d /proc/$pid ]
@@ -386,7 +408,7 @@
 
        if [ $? -eq 0 ]; then
                return $OCF_SUCCESS;
-       else    
+       else
                ocf_log debug "MySQL not running: removing old PID file"
                rm -f $OCF_RESKEY_pid
                return $OCF_NOT_RUNNING;
@@ -415,6 +437,7 @@
        if ocf_is_ms &&
            [ "$OCF_RESKEY_CRM_meta_role" = "Slave" ] &&
            is_slave 1; then
+           calculate_preference
            return $OCF_SUCCESS
        fi
 
@@ -431,6 +454,7 @@
        if [ ! -z "$buf" ]; then ocf_log err $buf; fi
        return $OCF_ERR_GENERIC;
     else
+       calculate_preference
        ocf_log info "MySQL monitor succeeded";
        return $OCF_SUCCESS;
     fi
@@ -447,9 +471,9 @@
     chown $OCF_RESKEY_user:$OCF_RESKEY_group $OCF_RESKEY_log
     chmod 0640 $OCF_RESKEY_log
     [ -x /sbin/restorecon ] && /sbin/restorecon $OCF_RESKEY_log
-    
-    if [ "$OCF_RESKEY_enable_creation" = 1 -a ! -d $OCF_RESKEY_datadir/mysql ] 
; then  
-        ocf_log info "Initializing MySQL database: " 
+
+    if [ "$OCF_RESKEY_enable_creation" = 1 -a ! -d $OCF_RESKEY_datadir/mysql ] 
; then
+        ocf_log info "Initializing MySQL database: "
        $MYSQL_BINDIR/mysql_install_db --datadir=$OCF_RESKEY_datadir
         rc=$?
         if [ $rc -ne 0 ] ; then
@@ -490,12 +514,12 @@
                --datadir=$OCF_RESKEY_datadir \
                --user=$OCF_RESKEY_user $OCF_RESKEY_additional_parameters 
>/dev/null 2>&1 &
     rc=$?
-    
+
     if [ $rc != 0 ]; then
        ocf_log err "MySQL start command failed: $rc"
        return $rc
     fi
-    
+
     # Spin waiting for the server to come up.
     # Let the CRM/LRM time us out if required
     start_wait=1
@@ -511,7 +535,7 @@
        fi
         sleep 2
     done
-    
+
     ocf_log info "MySQL started"
     return $OCF_SUCCESS
 }
@@ -521,9 +545,10 @@
        ocf_log info "MySQL is not running"
         return $OCF_SUCCESS
     fi
-
+    # Clear preference for becoming master
+    do_cmd $CRM_MASTER -D
     pid=`cat $OCF_RESKEY_pid 2> /dev/null `
-    /bin/kill $pid > /dev/null 
+       /bin/kill $pid > /dev/null
     rc=$?
     if [ $rc != 0 ]; then
         ocf_log err "MySQL couldn't be stopped"
@@ -572,8 +597,8 @@
 
 mysql_demote() {
        master_host=''
-       if ( echo "$OCF_RESKEY_CRM_meta_notify_master_uname"|grep '^\s*$' > 
/dev/null) 
-               ( echo "$OCF_RESKEY_CRM_meta_notify_promote_uname"|grep '^\s*$' 
> /dev/null); then 
+       if ( echo "$OCF_RESKEY_CRM_meta_notify_master_uname"|grep '^\s*$' > 
/dev/null)
+               ( echo "$OCF_RESKEY_CRM_meta_notify_promote_uname"|grep '^\s*$' 
> /dev/null); then
                ocf_log err "unable to demote (No master or promote uname 
found)"
                return $OCF_ERR_GENERIC
        fi
@@ -635,6 +660,67 @@
        fi
 }
 
+calculate_preference() {
+       master_file=''
+       master_pos=''
+       mysql --password=$OCF_RESKEY_replication_passwd \
+               --user=$OCF_RESKEY_replication_user \
+               -h $master_host \
+               -O connect_timeout=1 \
+               -e 'SHOW MASTER STATUS\G'|while read k v; do
+               if [ "$k" = 'File:' ]; then master_file="$v"; fi
+               if [ "$k" = 'Position:' ]; then master_pos="$v"; fi
+       done
+
+       if [ -z "$master_file" ] || [ -z "$master_pos" ]; then
+               ocf_log err "unable to find master file or master position"
+               return $OCF_ERR_GENERIC;
+       fi
+
+       local_log=''
+       local_pos=''
+       exec_pos=''
+       mysql --socket=$OCF_RESKEY_socket -O connect_timeout=1 \
+               -e 'SHOW SLAVE STATUS\G'|grep Master_Log|while read k v; do
+               if [ "$k" = 'Master_Log_File:' ]; then local_log="$v"; fi
+               if [ "$k" = 'Read_Master_Log_Pos:' ]; then local_pos="$v"; fi
+               if [ "$k" = 'Exec_Master_Log_Pos:' ]; then exec_pos="$v"; fi
+       done
+
+       if [ -z "$local_log" ] || [ -z "$local_pos" ] || [ -z "$exec_pos" ]; 
then
+               ocf_log err "unable to get slave status values"
+               return $OCF_ERR_GENERIC
+       fi
+
+       # no preference for very old slaves
+       if [ "$master_file" != "$local_log" ]; then
+               do_cmd $CRM_MASTER -v 0
+               return 1;
+       fi
+
+       # calculate preference points depending on how far behind the master 
are we
+       let local_diff=master_pos-local_pos
+       if [ "$local_diff" -ge 1000 ]; then
+           points=0;
+       elif [ "$local_diff" -ge 150 ]; then
+           let points+=5;
+       elif [ "$local_diff" -ge 50 ]; then
+           let points+=25;
+       elif [ "$local_diff" -ge 25 ]; then
+           let points+=50;
+       elif [ "$local_diff" -ge 5 ]; then
+           let points+=75;
+       elif [ "$local_diff" -ge 0 ]; then
+           if [ $local_pos -eq $exec_pos ]; then
+               let points+=100
+       else
+               let points+=90
+           fi
+       fi
+
+       do_cmd $CRM_MASTER -v $points
+}
+
 mysql_notify() {
        if [ "$OCF_RESKEY_CRM_meta_notify_type" != 'post' ]; then
                return $OCF_SUCCESS
@@ -654,7 +740,7 @@
                ;;
                *) return $OCF_SUCCESS ;;
        esac
-
+       calculate_preference
 }
 
 case "$1" in
_______________________________________________________
Linux-HA-Dev: [email protected]
http://lists.linux-ha.org/mailman/listinfo/linux-ha-dev
Home Page: http://linux-ha.org/

Reply via email to