You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1417 lines
43 KiB
1417 lines
43 KiB
From 591302a81c5961a03ffad70369433c20b31aebbe Mon Sep 17 00:00:00 2001 |
|
From: David Vossel <dvossel@redhat.com> |
|
Date: Fri, 18 Jul 2014 13:01:48 -0500 |
|
Subject: [PATCH] galera resource agent |
|
|
|
--- |
|
doc/man/Makefile.am | 1 + |
|
heartbeat/Makefile.am | 2 + |
|
heartbeat/galera | 693 ++++++++++++++++++++++++++++++++++++++++++++ |
|
heartbeat/mysql | 273 +---------------- |
|
heartbeat/mysql-common.sh | 279 ++++++++++++++++++ |
|
heartbeat/ocf-shellfuncs.in | 1 + |
|
6 files changed, 991 insertions(+), 258 deletions(-) |
|
create mode 100644 heartbeat/galera |
|
create mode 100644 heartbeat/mysql-common.sh |
|
|
|
diff --git a/doc/man/Makefile.am b/doc/man/Makefile.am |
|
index a3517aa..e97c7e9 100644 |
|
--- a/doc/man/Makefile.am |
|
+++ b/doc/man/Makefile.am |
|
@@ -102,6 +102,7 @@ man_MANS = ocf_heartbeat_AoEtarget.7 \ |
|
ocf_heartbeat_ethmonitor.7 \ |
|
ocf_heartbeat_exportfs.7 \ |
|
ocf_heartbeat_fio.7 \ |
|
+ ocf_heartbeat_galera.7 \ |
|
ocf_heartbeat_iSCSILogicalUnit.7 \ |
|
ocf_heartbeat_iSCSITarget.7 \ |
|
ocf_heartbeat_ids.7 \ |
|
diff --git a/heartbeat/Makefile.am b/heartbeat/Makefile.am |
|
index 65a2cfb..aab521f 100644 |
|
--- a/heartbeat/Makefile.am |
|
+++ b/heartbeat/Makefile.am |
|
@@ -73,6 +73,7 @@ ocf_SCRIPTS = ClusterMon \ |
|
exportfs \ |
|
Filesystem \ |
|
fio \ |
|
+ galera \ |
|
ids \ |
|
iscsi \ |
|
ICP \ |
|
@@ -140,6 +141,7 @@ ocfcommon_DATA = ocf-shellfuncs \ |
|
sapdb-nosha.sh \ |
|
sapdb.sh \ |
|
ora-common.sh \ |
|
+ mysql-common.sh \ |
|
findif.sh |
|
|
|
# Legacy locations |
|
diff --git a/heartbeat/galera b/heartbeat/galera |
|
new file mode 100644 |
|
index 0000000..6d8cf12 |
|
--- /dev/null |
|
+++ b/heartbeat/galera |
|
@@ -0,0 +1,693 @@ |
|
+#!/bin/sh |
|
+# |
|
+# Copyright (c) 2014 David Vossel <dvossel@redhat.com> |
|
+# All Rights Reserved. |
|
+# |
|
+# This program is free software; you can redistribute it and/or modify |
|
+# it under the terms of version 2 of the GNU General Public License as |
|
+# published by the Free Software Foundation. |
|
+# |
|
+# This program is distributed in the hope that it would be useful, but |
|
+# WITHOUT ANY WARRANTY; without even the implied warranty of |
|
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
|
+# |
|
+# Further, this software is distributed without any warranty that it is |
|
+# free of the rightful claim of any third person regarding infringement |
|
+# or the like. Any license provided herein, whether implied or |
|
+# otherwise, applies only to this software file. Patent licenses, if |
|
+# any, provided herein do not apply to combinations of this program with |
|
+# other software, or any other product whatsoever. |
|
+# |
|
+# You should have received a copy of the GNU General Public License |
|
+# along with this program; if not, write the Free Software Foundation, |
|
+# Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. |
|
+# |
|
+ |
|
+## |
|
+# README. |
|
+# |
|
+# This agent only supports being configured as a multistate Master |
|
+# resource. |
|
+# |
|
+# Slave vs Master role: |
|
+# |
|
+# During the 'Slave' role, galera instances are in read-only mode and |
|
+# will not attempt to connect to the cluster. This role exists only as |
|
+# a means to determine which galera instance is the most up-to-date. The |
|
+# most up-to-date node will be used to bootstrap a galera cluster that |
|
+# has no current members. |
|
+# |
|
+# The galera instances will only begin to be promoted to the Master role |
|
+# once all the nodes in the 'wsrep_cluster_address' connection address |
|
+# have entered read-only mode. At that point the node containing the |
|
+# database that is most current will be promoted to Master. Once the first |
|
+# Master instance bootstraps the galera cluster, the other nodes will be |
|
+# promoted to Master as well. |
|
+# |
|
+# Example: Create a galera cluster using nodes rhel7-node1 rhel7-node2 rhel7-node3 |
|
+# |
|
+# pcs resource create db galera enable_creation=true \ |
|
+# wsrep_cluster_address="gcomm://rhel7-auto1,rhel7-auto2,rhel7-auto3" meta master-max=3 --master |
|
+# |
|
+# By setting the 'enable_creation' option, the database will be automatically |
|
+# generated at startup. The meta attribute 'master-max=3' means that all 3 |
|
+# nodes listed in the wsrep_cluster_address list will be allowed to connect |
|
+# to the galera cluster and perform replication. |
|
+# |
|
+# NOTE: If you have more nodes in the pacemaker cluster then you wish |
|
+# to have in the galera cluster, make sure to use location contraints to prevent |
|
+# pacemaker from attempting to place a galera instance on a node that is |
|
+# not in the 'wsrep_cluster_address" list. |
|
+# |
|
+## |
|
+ |
|
+####################################################################### |
|
+# Initialization: |
|
+ |
|
+: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat} |
|
+. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs |
|
+. ${OCF_FUNCTIONS_DIR}/mysql-common.sh |
|
+ |
|
+# It is common for some galera instances to store |
|
+# check user that can be used to query status |
|
+# in this file |
|
+if [ -f "/etc/sysconfig/clustercheck" ]; then |
|
+ . /etc/sysconfig/clustercheck |
|
+fi |
|
+ |
|
+####################################################################### |
|
+ |
|
+usage() { |
|
+ cat <<UEND |
|
+usage: $0 (start|stop|validate-all|meta-data|monitor|promote|demote|notify) |
|
+ |
|
+$0 manages a galera Database as an HA resource. |
|
+ |
|
+The 'start' operation starts the database. |
|
+The 'stop' operation stops the database. |
|
+The 'status' operation reports whether the database is running |
|
+The 'monitor' operation reports whether the database seems to be working |
|
+The 'promote' operation makes this mysql server run as master |
|
+The 'demote' operation makes this mysql server run as slave |
|
+The 'validate-all' operation reports whether the parameters are valid |
|
+ |
|
+UEND |
|
+} |
|
+ |
|
+meta_data() { |
|
+ cat <<END |
|
+<?xml version="1.0"?> |
|
+<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd"> |
|
+<resource-agent name="galera"> |
|
+<version>1.0</version> |
|
+ |
|
+<longdesc lang="en"> |
|
+Resource script for managing galara database. |
|
+</longdesc> |
|
+<shortdesc lang="en">Manages a galara instance</shortdesc> |
|
+<parameters> |
|
+ |
|
+<parameter name="binary" unique="0" required="0"> |
|
+<longdesc lang="en"> |
|
+Location of the MySQL server binary |
|
+</longdesc> |
|
+<shortdesc lang="en">MySQL server binary</shortdesc> |
|
+<content type="string" default="${OCF_RESKEY_binary_default}" /> |
|
+</parameter> |
|
+ |
|
+<parameter name="client_binary" unique="0" required="0"> |
|
+<longdesc lang="en"> |
|
+Location of the MySQL client binary |
|
+</longdesc> |
|
+<shortdesc lang="en">MySQL client binary</shortdesc> |
|
+<content type="string" default="${OCF_RESKEY_client_binary_default}" /> |
|
+</parameter> |
|
+ |
|
+<parameter name="config" unique="0" required="0"> |
|
+<longdesc lang="en"> |
|
+Configuration file |
|
+</longdesc> |
|
+<shortdesc lang="en">MySQL config</shortdesc> |
|
+<content type="string" default="${OCF_RESKEY_config_default}" /> |
|
+</parameter> |
|
+ |
|
+<parameter name="datadir" unique="0" required="0"> |
|
+<longdesc lang="en"> |
|
+Directory containing databases |
|
+</longdesc> |
|
+<shortdesc lang="en">MySQL datadir</shortdesc> |
|
+<content type="string" default="${OCF_RESKEY_datadir_default}" /> |
|
+</parameter> |
|
+ |
|
+<parameter name="user" unique="0" required="0"> |
|
+<longdesc lang="en"> |
|
+User running MySQL daemon |
|
+</longdesc> |
|
+<shortdesc lang="en">MySQL user</shortdesc> |
|
+<content type="string" default="${OCF_RESKEY_user_default}" /> |
|
+</parameter> |
|
+ |
|
+<parameter name="group" unique="0" required="0"> |
|
+<longdesc lang="en"> |
|
+Group running MySQL daemon (for logfile and directory permissions) |
|
+</longdesc> |
|
+<shortdesc lang="en">MySQL group</shortdesc> |
|
+<content type="string" default="${OCF_RESKEY_group_default}"/> |
|
+</parameter> |
|
+ |
|
+<parameter name="log" unique="0" required="0"> |
|
+<longdesc lang="en"> |
|
+The logfile to be used for mysqld. |
|
+</longdesc> |
|
+<shortdesc lang="en">MySQL log file</shortdesc> |
|
+<content type="string" default="${OCF_RESKEY_log_default}"/> |
|
+</parameter> |
|
+ |
|
+<parameter name="pid" unique="0" required="0"> |
|
+<longdesc lang="en"> |
|
+The pidfile to be used for mysqld. |
|
+</longdesc> |
|
+<shortdesc lang="en">MySQL pid file</shortdesc> |
|
+<content type="string" default="${OCF_RESKEY_pid_default}"/> |
|
+</parameter> |
|
+ |
|
+<parameter name="socket" unique="0" required="0"> |
|
+<longdesc lang="en"> |
|
+The socket to be used for mysqld. |
|
+</longdesc> |
|
+<shortdesc lang="en">MySQL socket</shortdesc> |
|
+<content type="string" default="${OCF_RESKEY_socket_default}"/> |
|
+</parameter> |
|
+ |
|
+<parameter name="enable_creation" unique="0" required="0"> |
|
+<longdesc lang="en"> |
|
+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="boolean" default="${OCF_RESKEY_enable_creation_default}"/> |
|
+</parameter> |
|
+ |
|
+<parameter name="additional_parameters" unique="0" required="0"> |
|
+<longdesc lang="en"> |
|
+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> |
|
+<content type="string" default="${OCF_RESKEY_additional_parameters_default}"/> |
|
+</parameter> |
|
+ |
|
+ |
|
+<parameter name="wsrep_cluster_address" unique="0" required="1"> |
|
+<longdesc lang="en"> |
|
+The galera cluster address. This takes the form of: |
|
+gcomm://node,node,node |
|
+ |
|
+Only nodes present in this node list will be allowed to start a galera instance. |
|
+It is expected that the galera node names listed in this address match valid |
|
+pacemaker node names. |
|
+</longdesc> |
|
+<shortdesc lang="en">Galera cluster address</shortdesc> |
|
+<content type="string" default=""/> |
|
+</parameter> |
|
+ |
|
+<parameter name="check_user" unique="0" required="0"> |
|
+<longdesc lang="en"> |
|
+Cluster check user. |
|
+</longdesc> |
|
+<shortdesc lang="en">MySQL test user</shortdesc> |
|
+<content type="string" default="root" /> |
|
+</parameter> |
|
+ |
|
+<parameter name="check_passwd" unique="0" required="0"> |
|
+<longdesc lang="en"> |
|
+Cluster check user password |
|
+</longdesc> |
|
+<shortdesc lang="en">check password</shortdesc> |
|
+<content type="string" default="" /> |
|
+</parameter> |
|
+ |
|
+</parameters> |
|
+ |
|
+<actions> |
|
+<action name="start" timeout="120" /> |
|
+<action name="stop" timeout="120" /> |
|
+<action name="status" timeout="60" /> |
|
+<action name="monitor" depth="0" timeout="30" interval="20" /> |
|
+<action name="monitor" role="Master" depth="0" timeout="30" interval="10" /> |
|
+<action name="monitor" role="Slave" depth="0" timeout="30" interval="30" /> |
|
+<action name="promote" timeout="120" /> |
|
+<action name="demote" timeout="120" /> |
|
+<action name="notify" timeout="90" /> |
|
+<action name="validate-all" timeout="5" /> |
|
+<action name="meta-data" timeout="5" /> |
|
+</actions> |
|
+</resource-agent> |
|
+END |
|
+} |
|
+ |
|
+get_option_variable() |
|
+{ |
|
+ local key=$1 |
|
+ |
|
+ $MYSQL $MYSQL_OPTIONS_CHECK -e "SHOW VARIABLES like '$key';" | tail -1 |
|
+} |
|
+ |
|
+get_status_variable() |
|
+{ |
|
+ local key=$1 |
|
+ |
|
+ $MYSQL $MYSQL_OPTIONS_CHECK -e "show status like '$key';" | tail -1 |
|
+} |
|
+ |
|
+set_bootstrap_node() |
|
+{ |
|
+ local node=$1 |
|
+ |
|
+ ${HA_SBIN_DIR}/crm_attribute -N $node -l reboot --name "${INSTANCE_ATTR_NAME}-bootstrap" -v "true" |
|
+} |
|
+ |
|
+clear_bootstrap_node() |
|
+{ |
|
+ ${HA_SBIN_DIR}/crm_attribute -N $NODENAME -l reboot --name "${INSTANCE_ATTR_NAME}-bootstrap" -D |
|
+} |
|
+ |
|
+is_bootstrap() |
|
+{ |
|
+ ${HA_SBIN_DIR}/crm_attribute -N $NODENAME -l reboot --name "${INSTANCE_ATTR_NAME}-bootstrap" -Q 2>/dev/null |
|
+ |
|
+} |
|
+ |
|
+clear_last_commit() |
|
+{ |
|
+ ${HA_SBIN_DIR}/crm_attribute -N $NODENAME -l reboot --name "${INSTANCE_ATTR_NAME}-last-committed" -D |
|
+} |
|
+ |
|
+set_last_commit() |
|
+{ |
|
+ ${HA_SBIN_DIR}/crm_attribute -N $NODENAME -l reboot --name "${INSTANCE_ATTR_NAME}-last-committed" -v $1 |
|
+} |
|
+ |
|
+get_last_commit() |
|
+{ |
|
+ local node=$1 |
|
+ |
|
+ if [ -z "$node" ]; then |
|
+ ${HA_SBIN_DIR}/crm_attribute -N $NODENAME -l reboot --name "${INSTANCE_ATTR_NAME}-last-committed" -Q 2>/dev/null |
|
+ else |
|
+ ${HA_SBIN_DIR}/crm_attribute -N $node -l reboot --name "${INSTANCE_ATTR_NAME}-last-committed" -Q 2>/dev/null |
|
+ fi |
|
+} |
|
+ |
|
+wait_for_sync() |
|
+{ |
|
+ local state=$(get_status_variable "wsrep_local_state") |
|
+ |
|
+ ocf_log info "Waiting for database to sync with the cluster. " |
|
+ while [ "$state" != "4" ]; do |
|
+ sleep 1 |
|
+ state=$(get_status_variable "wsrep_local_state") |
|
+ done |
|
+ ocf_log info "Database synced." |
|
+} |
|
+ |
|
+is_primary() |
|
+{ |
|
+ cluster_status=$(get_status_variable "wsrep_cluster_status") |
|
+ if [ "$cluster_status" = "Primary" ]; then |
|
+ return 0 |
|
+ fi |
|
+ |
|
+ if [ -z "$cluster_status" ]; then |
|
+ ocf_log err "Unable to retrieve wsrep_cluster_status, verify check_user '$OCF_RESKEY_check_user' has permissions to view status" |
|
+ else |
|
+ ocf_log info "Galera instance wsrep_cluster_status=${cluster_status}" |
|
+ fi |
|
+ return 1 |
|
+} |
|
+ |
|
+is_readonly() |
|
+{ |
|
+ local res=$(get_option_variable "read_only") |
|
+ |
|
+ if ! ocf_is_true "$res"; then |
|
+ return 1 |
|
+ fi |
|
+ |
|
+ cluster_status=$(get_status_variable "wsrep_cluster_status") |
|
+ if ! [ "$cluster_status" = "Disconnected" ]; then |
|
+ return 1 |
|
+ fi |
|
+ |
|
+ return 0 |
|
+} |
|
+ |
|
+master_exists() |
|
+{ |
|
+ # determine if a master instance is already up and is healthy |
|
+ crm_mon --as-xml | grep "resource.*id=\"${OCF_RESOURCE_INSTANCE}\".*role=\"Master\".*active=\"true\".*orphaned=\"false\".*failed=\"false\"" > /dev/null 2>&1 |
|
+ return $? |
|
+} |
|
+ |
|
+clear_master_score() |
|
+{ |
|
+ local node=$1 |
|
+ if [ -z "$node" ]; then |
|
+ $CRM_MASTER -D |
|
+ else |
|
+ $CRM_MASTER -D -N $node |
|
+ fi |
|
+} |
|
+ |
|
+set_master_score() |
|
+{ |
|
+ local node=$1 |
|
+ |
|
+ if [ -z "$node" ]; then |
|
+ $CRM_MASTER -v 100 |
|
+ else |
|
+ $CRM_MASTER -N $node -v 100 |
|
+ fi |
|
+} |
|
+ |
|
+promote_everyone() |
|
+{ |
|
+ |
|
+ for node in $(echo "$OCF_RESKEY_wsrep_cluster_address" | sed 's/gcomm:\/\///g' | tr -d ' ' | tr -s ',' ' '); do |
|
+ |
|
+ set_master_score $node |
|
+ done |
|
+} |
|
+ |
|
+greater_than_equal_long() |
|
+{ |
|
+ # there are values we need to compare in this script |
|
+ # that are too large for shell -gt to process |
|
+ echo | awk -v n1="$1" -v n2="$2" '{if (n1>=n2) printf ("true"); else printf ("false");}' | grep -q "true" |
|
+} |
|
+ |
|
+detect_first_master() |
|
+{ |
|
+ local best_commit=0 |
|
+ local best_node="$NODENAME" |
|
+ local last_commit=0 |
|
+ local missing_nodes=0 |
|
+ |
|
+ for node in $(echo "$OCF_RESKEY_wsrep_cluster_address" | sed 's/gcomm:\/\///g' | tr -d ' ' | tr -s ',' ' '); do |
|
+ last_commit=$(get_last_commit $node) |
|
+ |
|
+ if [ -z "$last_commit" ]; then |
|
+ ocf_log info "Waiting on node <${node}> to report database status before Master instances can start." |
|
+ missing_nodes=1 |
|
+ continue |
|
+ fi |
|
+ |
|
+ # this means -1, or that no commit has occured yet. |
|
+ if [ "$last_commit" = "18446744073709551615" ]; then |
|
+ last_commit="0" |
|
+ fi |
|
+ |
|
+ greater_than_equal_long "$last_commit" "$best_commit" |
|
+ if [ $? -eq 0 ]; then |
|
+ best_node=$node |
|
+ best_commit=$last_commit |
|
+ fi |
|
+ |
|
+ done |
|
+ |
|
+ if [ $missing_nodes -eq 1 ]; then |
|
+ return |
|
+ fi |
|
+ |
|
+ ocf_log info "Promoting $best_node to be our bootstrap node" |
|
+ set_master_score $best_node |
|
+ set_bootstrap_node $best_node |
|
+} |
|
+ |
|
+# For galera, promote is really start |
|
+galera_promote() |
|
+{ |
|
+ local rc |
|
+ local extra_opts |
|
+ local bootstrap |
|
+ |
|
+ master_exists |
|
+ if [ $? -eq 0 ]; then |
|
+ # join without bootstrapping |
|
+ extra_opts="--wsrep-cluster-address=${OCF_RESKEY_wsrep_cluster_address}" |
|
+ else |
|
+ bootstrap=$(is_bootstrap) |
|
+ |
|
+ if ocf_is_true $bootstrap; then |
|
+ ocf_log info "Node <${NODENAME}> is bootstrapping the cluster" |
|
+ extra_opts="--wsrep-cluster-address=gcomm://" |
|
+ else |
|
+ ocf_log err "Failure, Attempted to promote Master instance of $OCF_RESOURCE_INSTANCE before bootstrap node has been detected." |
|
+ return $OCF_ERR_GENERIC |
|
+ fi |
|
+ |
|
+ fi |
|
+ |
|
+ # make sure the read only instance is stopped |
|
+ mysql_common_stop |
|
+ rc=$? |
|
+ if [ $rc -ne $OCF_SUCCESS ] && [ $rc -ne $OCF_NOT_RUNNING ]; then |
|
+ ocf_log err "Failed to stop read-only galera instance during promotion to Master" |
|
+ return $rc |
|
+ fi |
|
+ |
|
+ sleep 4 |
|
+ |
|
+ mysql_common_prepare_dirs |
|
+ mysql_common_start "$extra_opts" |
|
+ rc=$? |
|
+ if [ $rc != $OCF_SUCCESS ]; then |
|
+ return $rc |
|
+ fi |
|
+ |
|
+ galera_monitor |
|
+ rc=$? |
|
+ if [ $rc != $OCF_SUCCESS -a $rc != $OCF_RUNNING_MASTER ]; then |
|
+ ocf_log err "Failed initial monitor action" |
|
+ return $rc |
|
+ fi |
|
+ |
|
+ is_readonly |
|
+ if [ $? -eq 0 ]; then |
|
+ ocf_log err "Failure. Master instance started in read-only mode, check configuration." |
|
+ return $OCF_ERR_GENERIC |
|
+ fi |
|
+ |
|
+ is_primary |
|
+ if [ $? -ne 0 ]; then |
|
+ ocf_log err "Failure. Master instance started, but is not in Primary mode." |
|
+ return $OCF_ERR_GENERIC |
|
+ fi |
|
+ |
|
+ if ocf_is_true $bootstrap; then |
|
+ promote_everyone |
|
+ clear_bootstrap_node |
|
+ ocf_log info "Bootstrap complete, promoting the rest of the galera instances." |
|
+ else |
|
+ # if this is not the bootstrap node, make sure this instance |
|
+ # syncs with the rest of the cluster before promotion returns. |
|
+ wait_for_sync |
|
+ fi |
|
+ |
|
+ # last commit is no longer relevant once promoted |
|
+ clear_last_commit |
|
+ |
|
+ ocf_log info "Galera started" |
|
+ return $OCF_SUCCESS |
|
+} |
|
+ |
|
+galera_demote() |
|
+{ |
|
+ mysql_common_stop |
|
+ rc=$? |
|
+ if [ $rc -ne $OCF_SUCCESS ] && [ $rc -ne $OCF_NOT_RUNNING ]; then |
|
+ ocf_log err "Failed to stop Master galera instance during demotion to Master" |
|
+ return $rc |
|
+ fi |
|
+ |
|
+ # if this node was previously a bootstrap node, that is no longer the case. |
|
+ clear_bootstrap_node |
|
+ |
|
+ # start again in slave mode so the new last commit is recorded |
|
+ galera_start |
|
+} |
|
+ |
|
+galera_start() |
|
+{ |
|
+ local extra_opts='--read-only=true' |
|
+ local last_commit |
|
+ |
|
+ echo $OCF_RESKEY_wsrep_cluster_address | grep -q $NODENAME |
|
+ if [ $? -ne 0 ]; then |
|
+ ocf_log err "local node <${NODENAME}> must be a member of the wsrep_cluster_address <${OCF_RESKEY_wsrep_cluster_address}>to start this galera instance" |
|
+ return $OCF_ERR_CONFIGURED |
|
+ fi |
|
+ |
|
+ mysql_common_prepare_dirs |
|
+ mysql_common_start "$extra_opts" |
|
+ |
|
+ is_readonly |
|
+ if [ $? -ne 0 ]; then |
|
+ ocf_log err "Failure. Slave instance did not start correctly in read-only mode, Make sure local galera.cnf does not have wsrep_cluster_address set." |
|
+ return $OCF_ERR_GENERIC |
|
+ fi |
|
+ |
|
+ ocf_log info "attempting to detect last commit version" |
|
+ while [ -z "$last_commit" ]; do |
|
+ last_commit=$(get_status_variable "wsrep_last_committed") |
|
+ if [ -z "$last_commit" ]; then |
|
+ sleep 1 |
|
+ fi |
|
+ done |
|
+ ocf_log info "Last commit version found: $last_commit" |
|
+ |
|
+ set_last_commit $last_commit |
|
+ |
|
+ master_exists |
|
+ if [ $? -eq 0 ]; then |
|
+ ocf_log info "Master instances are already up, setting master score so this instance will join galera cluster." |
|
+ set_master_score $NODENAME |
|
+ else |
|
+ clear_master_score |
|
+ detect_first_master |
|
+ fi |
|
+ |
|
+ return $OCF_SUCCESS |
|
+} |
|
+ |
|
+galera_monitor() |
|
+{ |
|
+ local rc |
|
+ local status_loglevel="err" |
|
+ |
|
+ # Set loglevel to info during probe |
|
+ if ocf_is_probe; then |
|
+ status_loglevel="info" |
|
+ fi |
|
+ |
|
+ mysql_common_status $status_loglevel |
|
+ rc=$? |
|
+ |
|
+ # If status returned an error, return that immediately |
|
+ if [ $rc -ne $OCF_SUCCESS ]; then |
|
+ return $rc |
|
+ fi |
|
+ |
|
+ echo $OCF_RESKEY_wsrep_cluster_address | grep -q $NODENAME |
|
+ if [ $? -ne 0 ]; then |
|
+ ocf_log err "local node <${NODENAME}> is started, but is not a member of the wsrep_cluster_address <${OCF_RESKEY_wsrep_cluster_address}>" |
|
+ return $OCF_ERR_GENERIC |
|
+ fi |
|
+ |
|
+ is_readonly |
|
+ if [ $? -ne 0 ]; then |
|
+ is_primary |
|
+ if [ $? -ne 0 ]; then |
|
+ ocf_log err "local node <${NODENAME}> is neither in primary mode nor in read_only mode. Unknown state." |
|
+ return $OCF_ERR_GENERIC |
|
+ fi |
|
+ |
|
+ if ocf_is_probe; then |
|
+ # restore master score during probe |
|
+ # if we detect this is a master instance |
|
+ set_master_score |
|
+ fi |
|
+ rc=$OCF_RUNNING_MASTER |
|
+ else |
|
+ master_exists |
|
+ if [ $? -ne 0 ]; then |
|
+ detect_first_master |
|
+ else |
|
+ # a master instance exists and is healthy, promote this |
|
+ # local read only instance |
|
+ # so it can join the master galera cluster. |
|
+ set_master_score |
|
+ fi |
|
+ fi |
|
+ # TODO look at what is done in the wait script |
|
+ |
|
+ return $rc |
|
+} |
|
+ |
|
+galera_stop() |
|
+{ |
|
+ local rc |
|
+ # make sure the process is stopped |
|
+ mysql_common_stop |
|
+ rc=$1 |
|
+ |
|
+ clear_last_commit |
|
+ clear_master_score |
|
+ clear_bootstrap_node |
|
+ return $rc |
|
+} |
|
+ |
|
+galera_validate() |
|
+{ |
|
+ if ! ocf_is_ms; then |
|
+ ocf_log err "Galera must be configured as a multistate Master/Slave resource." |
|
+ return $OCF_ERR_CONFIGURED |
|
+ fi |
|
+ |
|
+ if [ -z "$OCF_RESKEY_wsrep_cluster_address" ]; then |
|
+ ocf_log err "Galera must be configured with a wsrep_cluster_address value." |
|
+ return $OCF_ERR_CONFIGURED |
|
+ fi |
|
+ |
|
+ mysql_common_validate |
|
+} |
|
+ |
|
+case "$1" in |
|
+ meta-data) meta_data |
|
+ exit $OCF_SUCCESS;; |
|
+ usage|help) usage |
|
+ exit $OCF_SUCCESS;; |
|
+esac |
|
+ |
|
+galera_validate |
|
+rc=$? |
|
+LSB_STATUS_STOPPED=3 |
|
+if [ $rc -ne 0 ]; then |
|
+ case "$1" in |
|
+ stop) exit $OCF_SUCCESS;; |
|
+ monitor) exit $OCF_NOT_RUNNING;; |
|
+ status) exit $LSB_STATUS_STOPPED;; |
|
+ *) exit $rc;; |
|
+ esac |
|
+fi |
|
+ |
|
+if [ -z "${OCF_RESKEY_check_passwd}" ]; then |
|
+ # This value is automatically sourced from /etc/sysconfig/checkcluster if available |
|
+ OCF_RESKEY_check_passwd=${MYSQL_PASSWORD} |
|
+fi |
|
+if [ -z "${OCF_RESKEY_check_user}" ]; then |
|
+ # This value is automatically sourced from /etc/sysconfig/checkcluster if available |
|
+ OCF_RESKEY_check_user=${MYSQL_USERNAME} |
|
+fi |
|
+: ${OCF_RESKEY_check_user="root"} |
|
+ |
|
+MYSQL_OPTIONS_CHECK="-nNE --user=${OCF_RESKEY_check_user}" |
|
+if [ -n "${OCF_RESKEY_check_passwd}" ]; then |
|
+ MYSQL_OPTIONS_CHECK="$MYSQL_OPTIONS_CHECK --password=${MYSQL_PASSWORD}" |
|
+fi |
|
+ |
|
+# What kind of method was invoked? |
|
+case "$1" in |
|
+ start) galera_start;; |
|
+ stop) galera_stop;; |
|
+ status) mysql_common_status err;; |
|
+ monitor) galera_monitor;; |
|
+ promote) galera_promote;; |
|
+ demote) galera_demote;; |
|
+ notify) galera_notify;; |
|
+ validate-all) exit $OCF_SUCCESS;; |
|
+ |
|
+ *) usage |
|
+ exit $OCF_ERR_UNIMPLEMENTED;; |
|
+esac |
|
+ |
|
+# vi:sw=4:ts=4:et: |
|
diff --git a/heartbeat/mysql b/heartbeat/mysql |
|
index f7eb9f2..41287d0 100755 |
|
--- a/heartbeat/mysql |
|
+++ b/heartbeat/mysql |
|
@@ -51,97 +51,7 @@ |
|
|
|
: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat} |
|
. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs |
|
- |
|
-####################################################################### |
|
- |
|
-# Attempt to detect a default binary |
|
-OCF_RESKEY_binary_default=$(which mysqld_safe 2> /dev/null) |
|
-if [ "$OCF_RESKEY_binary_default" = "" ]; then |
|
- OCF_RESKEY_binary_default=$(which safe_mysqld 2> /dev/null) |
|
-fi |
|
- |
|
-# Fill in some defaults if no values are specified |
|
-HOSTOS=`uname` |
|
-if [ "X${HOSTOS}" = "XOpenBSD" ];then |
|
- if [ "$OCF_RESKEY_binary_default" = "" ]; then |
|
- OCF_RESKEY_binary_default="/usr/local/bin/mysqld_safe" |
|
- fi |
|
- OCF_RESKEY_config_default="/etc/my.cnf" |
|
- OCF_RESKEY_datadir_default="/var/mysql" |
|
- OCF_RESKEY_user_default="_mysql" |
|
- OCF_RESKEY_group_default="_mysql" |
|
- OCF_RESKEY_log_default="/var/log/mysqld.log" |
|
- OCF_RESKEY_pid_default="/var/mysql/mysqld.pid" |
|
- OCF_RESKEY_socket_default="/var/run/mysql/mysql.sock" |
|
-else |
|
- if [ "$OCF_RESKEY_binary_default" = "" ]; then |
|
- OCF_RESKEY_binary_default="/usr/bin/safe_mysqld" |
|
- fi |
|
- OCF_RESKEY_config_default="/etc/my.cnf" |
|
- OCF_RESKEY_datadir_default="/var/lib/mysql" |
|
- OCF_RESKEY_user_default="mysql" |
|
- OCF_RESKEY_group_default="mysql" |
|
- OCF_RESKEY_log_default="/var/log/mysqld.log" |
|
- OCF_RESKEY_pid_default="/var/run/mysql/mysqld.pid" |
|
- OCF_RESKEY_socket_default="/var/lib/mysql/mysql.sock" |
|
-fi |
|
-OCF_RESKEY_client_binary_default="mysql" |
|
-OCF_RESKEY_test_user_default="root" |
|
-OCF_RESKEY_test_table_default="mysql.user" |
|
-OCF_RESKEY_test_passwd_default="" |
|
-OCF_RESKEY_enable_creation_default=0 |
|
-OCF_RESKEY_additional_parameters_default="" |
|
-OCF_RESKEY_replication_port_default="3306" |
|
-OCF_RESKEY_max_slave_lag_default="3600" |
|
-OCF_RESKEY_evict_outdated_slaves_default="false" |
|
-OCF_RESKEY_reader_attribute_default="readable" |
|
- |
|
-: ${OCF_RESKEY_binary=${OCF_RESKEY_binary_default}} |
|
-MYSQL_BINDIR=`dirname ${OCF_RESKEY_binary}` |
|
- |
|
-: ${OCF_RESKEY_client_binary=${OCF_RESKEY_client_binary_default}} |
|
- |
|
-: ${OCF_RESKEY_config=${OCF_RESKEY_config_default}} |
|
-: ${OCF_RESKEY_datadir=${OCF_RESKEY_datadir_default}} |
|
- |
|
-: ${OCF_RESKEY_user=${OCF_RESKEY_user_default}} |
|
-: ${OCF_RESKEY_group=${OCF_RESKEY_group_default}} |
|
- |
|
-: ${OCF_RESKEY_log=${OCF_RESKEY_log_default}} |
|
-: ${OCF_RESKEY_pid=${OCF_RESKEY_pid_default}} |
|
-: ${OCF_RESKEY_socket=${OCF_RESKEY_socket_default}} |
|
- |
|
-: ${OCF_RESKEY_test_user=${OCF_RESKEY_test_user_default}} |
|
-: ${OCF_RESKEY_test_table=${OCF_RESKEY_test_table_default}} |
|
-: ${OCF_RESKEY_test_passwd=${OCF_RESKEY_test_passwd_default}} |
|
- |
|
-: ${OCF_RESKEY_enable_creation=${OCF_RESKEY_enable_creation_default}} |
|
-: ${OCF_RESKEY_additional_parameters=${OCF_RESKEY_additional_parameters_default}} |
|
- |
|
-: ${OCF_RESKEY_replication_user=${OCF_RESKEY_replication_user_default}} |
|
-: ${OCF_RESKEY_replication_passwd=${OCF_RESKEY_replication_passwd_default}} |
|
-: ${OCF_RESKEY_replication_port=${OCF_RESKEY_replication_port_default}} |
|
- |
|
-: ${OCF_RESKEY_max_slave_lag=${OCF_RESKEY_max_slave_lag_default}} |
|
-: ${OCF_RESKEY_evict_outdated_slaves=${OCF_RESKEY_evict_outdated_slaves_default}} |
|
- |
|
-: ${OCF_RESKEY_reader_attribute=${OCF_RESKEY_reader_attribute_default}} |
|
- |
|
-####################################################################### |
|
-# Convenience variables |
|
- |
|
-MYSQL=$OCF_RESKEY_client_binary |
|
-MYSQL_OPTIONS_LOCAL="-S $OCF_RESKEY_socket --connect_timeout=10" |
|
-MYSQL_OPTIONS_REPL="$MYSQL_OPTIONS_LOCAL --user=$OCF_RESKEY_replication_user --password=$OCF_RESKEY_replication_passwd" |
|
-MYSQL_OPTIONS_TEST="$MYSQL_OPTIONS_LOCAL --user=$OCF_RESKEY_test_user --password=$OCF_RESKEY_test_passwd" |
|
-MYSQL_TOO_MANY_CONN_ERR=1040 |
|
- |
|
-CRM_MASTER="${HA_SBIN_DIR}/crm_master -l reboot " |
|
-NODENAME=$(ocf_local_nodename) |
|
-CRM_ATTR="${HA_SBIN_DIR}/crm_attribute -N $NODENAME " |
|
-INSTANCE_ATTR_NAME=`echo ${OCF_RESOURCE_INSTANCE}| awk -F : '{print $1}'` |
|
-CRM_ATTR_REPL_INFO="${HA_SBIN_DIR}/crm_attribute --type crm_config --name ${INSTANCE_ATTR_NAME}_REPL_INFO -s mysql_replication" |
|
- |
|
+. ${OCF_FUNCTIONS_DIR}/mysql-common.sh |
|
####################################################################### |
|
|
|
usage() { |
|
@@ -794,57 +704,6 @@ get_local_ip() { |
|
|
|
# Functions invoked by resource manager actions |
|
|
|
-mysql_validate() { |
|
- check_binary $OCF_RESKEY_binary |
|
- check_binary $OCF_RESKEY_client_binary |
|
- |
|
- if [ ! -f $OCF_RESKEY_config ]; then |
|
- ocf_log err "Config $OCF_RESKEY_config doesn't exist"; |
|
- return $OCF_ERR_INSTALLED; |
|
- fi |
|
- |
|
- if [ ! -d $OCF_RESKEY_datadir ]; then |
|
- ocf_log err "Datadir $OCF_RESKEY_datadir doesn't exist"; |
|
- return $OCF_ERR_INSTALLED; |
|
- 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"; |
|
- return $OCF_ERR_INSTALLED; |
|
- fi |
|
- |
|
- true |
|
-} |
|
- |
|
-mysql_status() { |
|
- if [ ! -e $OCF_RESKEY_pid ]; then |
|
- ocf_log $1 "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 ] |
|
- else |
|
- kill -s 0 $pid >/dev/null 2>&1 |
|
- fi |
|
- |
|
- if [ $? -eq 0 ]; then |
|
- return $OCF_SUCCESS; |
|
- else |
|
- ocf_log $1 "MySQL not running: removing old PID file" |
|
- rm -f $OCF_RESKEY_pid |
|
- return $OCF_NOT_RUNNING; |
|
- fi |
|
-} |
|
- |
|
mysql_monitor() { |
|
local rc |
|
local status_loglevel="err" |
|
@@ -854,7 +713,7 @@ mysql_monitor() { |
|
status_loglevel="info" |
|
fi |
|
|
|
- mysql_status $status_loglevel |
|
+ mysql_common_status $status_loglevel |
|
|
|
rc=$? |
|
|
|
@@ -865,7 +724,6 @@ mysql_monitor() { |
|
return $rc |
|
fi |
|
|
|
- |
|
if [ $OCF_CHECK_LEVEL -gt 0 -a -n "$OCF_RESKEY_test_table" ]; then |
|
# Check if this instance is configured as a slave, and if so |
|
# check slave status |
|
@@ -894,58 +752,20 @@ mysql_monitor() { |
|
} |
|
|
|
mysql_start() { |
|
- local rc pid |
|
+ local rc |
|
|
|
if ocf_is_ms; then |
|
# Initialize the ReaderVIP attribute, monitor will enable it |
|
set_reader_attr 0 |
|
fi |
|
|
|
- mysql_status info |
|
+ mysql_common_status info |
|
if [ $? = $OCF_SUCCESS ]; then |
|
ocf_log info "MySQL already running" |
|
return $OCF_SUCCESS |
|
fi |
|
|
|
- touch $OCF_RESKEY_log |
|
- 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_is_true "$OCF_RESKEY_enable_creation" && [ ! -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 |
|
- ocf_log err "Initialization failed: $rc"; |
|
- exit $OCF_ERR_GENERIC |
|
- fi |
|
- chown -R $OCF_RESKEY_user:$OCF_RESKEY_group $OCF_RESKEY_datadir |
|
- fi |
|
- |
|
- pid_dir=`dirname $OCF_RESKEY_pid` |
|
- if [ ! -d $pid_dir ] ; then |
|
- ocf_log info "Creating PID dir: $pid_dir" |
|
- mkdir -p $pid_dir |
|
- chown $OCF_RESKEY_user:$OCF_RESKEY_group $pid_dir |
|
- fi |
|
- |
|
- socket_dir=`dirname $OCF_RESKEY_socket` |
|
- if [ ! -d $socket_dir ] ; then |
|
- ocf_log info "Creating socket dir: $socket_dir" |
|
- mkdir -p $socket_dir |
|
- chown $OCF_RESKEY_user:$OCF_RESKEY_group $socket_dir |
|
- fi |
|
- |
|
- # Regardless of whether we just created the directory or it |
|
- # already existed, check whether it is writable by the configured |
|
- # user |
|
- for dir in $pid_dir $socket_dir; do |
|
- if ! su -s /bin/sh - $OCF_RESKEY_user -c "test -w $dir"; then |
|
- ocf_log err "Directory $dir is not writable by $OCF_RESKEY_user" |
|
- exit $OCF_ERR_PERM; |
|
- fi |
|
- done |
|
+ mysql_common_prepare_dirs |
|
|
|
# Uncomment to perform permission clensing |
|
# - not convinced this should be enabled by default |
|
@@ -958,34 +778,11 @@ mysql_start() { |
|
mysql_extra_params="--skip-slave-start" |
|
fi |
|
|
|
- ${OCF_RESKEY_binary} --defaults-file=$OCF_RESKEY_config \ |
|
- --pid-file=$OCF_RESKEY_pid \ |
|
- --socket=$OCF_RESKEY_socket \ |
|
- --datadir=$OCF_RESKEY_datadir \ |
|
- --log-error=$OCF_RESKEY_log \ |
|
- --user=$OCF_RESKEY_user $OCF_RESKEY_additional_parameters \ |
|
- $mysql_extra_params >/dev/null 2>&1 & |
|
- pid=$! |
|
- |
|
- # Spin waiting for the server to come up. |
|
- # Let the CRM/LRM time us out if required. |
|
- start_wait=1 |
|
- while [ $start_wait = 1 ]; do |
|
- if ! ps $pid > /dev/null 2>&1; then |
|
- wait $pid |
|
- ocf_log err "MySQL server failed to start (rc=$?), please check your installation" |
|
- return $OCF_ERR_GENERIC |
|
- fi |
|
- mysql_status info |
|
- rc=$? |
|
- if [ $rc = $OCF_SUCCESS ]; then |
|
- start_wait=0 |
|
- elif [ $rc != $OCF_NOT_RUNNING ]; then |
|
- ocf_log info "MySQL start failed: $rc" |
|
- return $rc |
|
- fi |
|
- sleep 2 |
|
- done |
|
+ mysql_common_start $mysql_extra_params |
|
+ rc=$? |
|
+ if [ $rc != $OCF_SUCCESS ]; then |
|
+ return $rc |
|
+ fi |
|
|
|
if ocf_is_ms; then |
|
# We're configured as a stateful resource. We must start as |
|
@@ -1035,7 +832,6 @@ mysql_start() { |
|
} |
|
|
|
mysql_stop() { |
|
- |
|
if ocf_is_ms; then |
|
# clear preference for becoming master |
|
$CRM_MASTER -D |
|
@@ -1044,52 +840,13 @@ mysql_stop() { |
|
set_reader_attr 0 |
|
fi |
|
|
|
- if [ ! -f $OCF_RESKEY_pid ]; then |
|
- ocf_log info "MySQL is not running" |
|
- return $OCF_SUCCESS |
|
- fi |
|
- |
|
- pid=`cat $OCF_RESKEY_pid 2> /dev/null ` |
|
- /bin/kill $pid > /dev/null |
|
- rc=$? |
|
- if [ $rc != 0 ]; then |
|
- ocf_log err "MySQL couldn't be stopped" |
|
- return $OCF_ERR_GENERIC |
|
- fi |
|
- # stop waiting |
|
- shutdown_timeout=15 |
|
- if [ -n "$OCF_RESKEY_CRM_meta_timeout" ]; then |
|
- shutdown_timeout=$((($OCF_RESKEY_CRM_meta_timeout/1000)-5)) |
|
- fi |
|
- count=0 |
|
- while [ $count -lt $shutdown_timeout ] |
|
- do |
|
- mysql_status info |
|
- rc=$? |
|
- if [ $rc = $OCF_NOT_RUNNING ]; then |
|
- break |
|
- fi |
|
- count=`expr $count + 1` |
|
- sleep 1 |
|
- ocf_log debug "MySQL still hasn't stopped yet. Waiting..." |
|
- done |
|
- |
|
- mysql_status info |
|
- if [ $? != $OCF_NOT_RUNNING ]; then |
|
- ocf_log info "MySQL failed to stop after ${shutdown_timeout}s using SIGTERM. Trying SIGKILL..." |
|
- /bin/kill -KILL $pid > /dev/null |
|
- fi |
|
- |
|
- ocf_log info "MySQL stopped"; |
|
- rm -f /var/lock/subsys/mysqld |
|
- rm -f $OCF_RESKEY_socket |
|
- return $OCF_SUCCESS |
|
+ mysql_common_stop |
|
} |
|
|
|
mysql_promote() { |
|
local master_info |
|
|
|
- if ( ! mysql_status err ); then |
|
+ if ( ! mysql_common_status err ); then |
|
return $OCF_NOT_RUNNING |
|
fi |
|
ocf_run $MYSQL $MYSQL_OPTIONS_REPL \ |
|
@@ -1115,7 +872,7 @@ mysql_promote() { |
|
} |
|
|
|
mysql_demote() { |
|
- if ! mysql_status err; then |
|
+ if ! mysql_common_status err; then |
|
return $OCF_NOT_RUNNING |
|
fi |
|
|
|
@@ -1244,7 +1001,7 @@ case "$1" in |
|
exit $OCF_SUCCESS;; |
|
esac |
|
|
|
-mysql_validate |
|
+mysql_common_validate |
|
rc=$? |
|
LSB_STATUS_STOPPED=3 |
|
if [ $rc -ne 0 ]; then |
|
@@ -1260,7 +1017,7 @@ fi |
|
case "$1" in |
|
start) mysql_start;; |
|
stop) mysql_stop;; |
|
- status) mysql_status err;; |
|
+ status) mysql_common_status err;; |
|
monitor) mysql_monitor;; |
|
promote) mysql_promote;; |
|
demote) mysql_demote;; |
|
diff --git a/heartbeat/mysql-common.sh b/heartbeat/mysql-common.sh |
|
new file mode 100644 |
|
index 0000000..5b6a991 |
|
--- /dev/null |
|
+++ b/heartbeat/mysql-common.sh |
|
@@ -0,0 +1,279 @@ |
|
+#!/bin/sh |
|
+ |
|
+####################################################################### |
|
+ |
|
+# Attempt to detect a default binary |
|
+OCF_RESKEY_binary_default=$(which mysqld_safe 2> /dev/null) |
|
+if [ "$OCF_RESKEY_binary_default" = "" ]; then |
|
+ OCF_RESKEY_binary_default=$(which safe_mysqld 2> /dev/null) |
|
+fi |
|
+ |
|
+# Fill in some defaults if no values are specified |
|
+HOSTOS=`uname` |
|
+if [ "X${HOSTOS}" = "XOpenBSD" ];then |
|
+ if [ "$OCF_RESKEY_binary_default" = "" ]; then |
|
+ OCF_RESKEY_binary_default="/usr/local/bin/mysqld_safe" |
|
+ fi |
|
+ OCF_RESKEY_config_default="/etc/my.cnf" |
|
+ OCF_RESKEY_datadir_default="/var/mysql" |
|
+ OCF_RESKEY_user_default="_mysql" |
|
+ OCF_RESKEY_group_default="_mysql" |
|
+ OCF_RESKEY_log_default="/var/log/mysqld.log" |
|
+ OCF_RESKEY_pid_default="/var/mysql/mysqld.pid" |
|
+ OCF_RESKEY_socket_default="/var/run/mysql/mysql.sock" |
|
+else |
|
+ if [ "$OCF_RESKEY_binary_default" = "" ]; then |
|
+ OCF_RESKEY_binary_default="/usr/bin/safe_mysqld" |
|
+ fi |
|
+ OCF_RESKEY_config_default="/etc/my.cnf" |
|
+ OCF_RESKEY_datadir_default="/var/lib/mysql" |
|
+ OCF_RESKEY_user_default="mysql" |
|
+ OCF_RESKEY_group_default="mysql" |
|
+ OCF_RESKEY_log_default="/var/log/mysqld.log" |
|
+ OCF_RESKEY_pid_default="/var/run/mysql/mysqld.pid" |
|
+ OCF_RESKEY_socket_default="/var/lib/mysql/mysql.sock" |
|
+fi |
|
+OCF_RESKEY_client_binary_default="mysql" |
|
+OCF_RESKEY_test_user_default="root" |
|
+OCF_RESKEY_test_table_default="mysql.user" |
|
+OCF_RESKEY_test_passwd_default="" |
|
+OCF_RESKEY_enable_creation_default=0 |
|
+OCF_RESKEY_additional_parameters_default="" |
|
+OCF_RESKEY_replication_port_default="3306" |
|
+OCF_RESKEY_max_slave_lag_default="3600" |
|
+OCF_RESKEY_evict_outdated_slaves_default="false" |
|
+OCF_RESKEY_reader_attribute_default="readable" |
|
+ |
|
+: ${OCF_RESKEY_binary=${OCF_RESKEY_binary_default}} |
|
+MYSQL_BINDIR=`dirname ${OCF_RESKEY_binary}` |
|
+ |
|
+: ${OCF_RESKEY_client_binary=${OCF_RESKEY_client_binary_default}} |
|
+ |
|
+: ${OCF_RESKEY_config=${OCF_RESKEY_config_default}} |
|
+: ${OCF_RESKEY_datadir=${OCF_RESKEY_datadir_default}} |
|
+ |
|
+: ${OCF_RESKEY_user=${OCF_RESKEY_user_default}} |
|
+: ${OCF_RESKEY_group=${OCF_RESKEY_group_default}} |
|
+ |
|
+: ${OCF_RESKEY_log=${OCF_RESKEY_log_default}} |
|
+: ${OCF_RESKEY_pid=${OCF_RESKEY_pid_default}} |
|
+: ${OCF_RESKEY_socket=${OCF_RESKEY_socket_default}} |
|
+ |
|
+: ${OCF_RESKEY_test_user=${OCF_RESKEY_test_user_default}} |
|
+: ${OCF_RESKEY_test_table=${OCF_RESKEY_test_table_default}} |
|
+: ${OCF_RESKEY_test_passwd=${OCF_RESKEY_test_passwd_default}} |
|
+ |
|
+: ${OCF_RESKEY_enable_creation=${OCF_RESKEY_enable_creation_default}} |
|
+: ${OCF_RESKEY_additional_parameters=${OCF_RESKEY_additional_parameters_default}} |
|
+ |
|
+: ${OCF_RESKEY_replication_user=${OCF_RESKEY_replication_user_default}} |
|
+: ${OCF_RESKEY_replication_passwd=${OCF_RESKEY_replication_passwd_default}} |
|
+: ${OCF_RESKEY_replication_port=${OCF_RESKEY_replication_port_default}} |
|
+ |
|
+: ${OCF_RESKEY_max_slave_lag=${OCF_RESKEY_max_slave_lag_default}} |
|
+: ${OCF_RESKEY_evict_outdated_slaves=${OCF_RESKEY_evict_outdated_slaves_default}} |
|
+ |
|
+: ${OCF_RESKEY_reader_attribute=${OCF_RESKEY_reader_attribute_default}} |
|
+ |
|
+####################################################################### |
|
+# Convenience variables |
|
+ |
|
+MYSQL=$OCF_RESKEY_client_binary |
|
+MYSQL_OPTIONS_LOCAL="-S $OCF_RESKEY_socket --connect_timeout=10" |
|
+MYSQL_OPTIONS_REPL="$MYSQL_OPTIONS_LOCAL --user=$OCF_RESKEY_replication_user --password=$OCF_RESKEY_replication_passwd" |
|
+MYSQL_OPTIONS_TEST="$MYSQL_OPTIONS_LOCAL --user=$OCF_RESKEY_test_user --password=$OCF_RESKEY_test_passwd" |
|
+MYSQL_TOO_MANY_CONN_ERR=1040 |
|
+ |
|
+CRM_MASTER="${HA_SBIN_DIR}/crm_master -l reboot " |
|
+NODENAME=$(ocf_local_nodename) |
|
+CRM_ATTR="${HA_SBIN_DIR}/crm_attribute -N $NODENAME " |
|
+INSTANCE_ATTR_NAME=`echo ${OCF_RESOURCE_INSTANCE}| awk -F : '{print $1}'` |
|
+CRM_ATTR_REPL_INFO="${HA_SBIN_DIR}/crm_attribute --type crm_config --name ${INSTANCE_ATTR_NAME}_REPL_INFO -s mysql_replication" |
|
+ |
|
+####################################################################### |
|
+ |
|
+mysql_common_validate() |
|
+{ |
|
+ check_binary $OCF_RESKEY_binary |
|
+ check_binary $OCF_RESKEY_client_binary |
|
+ |
|
+ if [ ! -f $OCF_RESKEY_config ]; then |
|
+ ocf_log err "Config $OCF_RESKEY_config doesn't exist"; |
|
+ return $OCF_ERR_INSTALLED; |
|
+ fi |
|
+ |
|
+ if [ ! -d $OCF_RESKEY_datadir ]; then |
|
+ ocf_log err "Datadir $OCF_RESKEY_datadir doesn't exist"; |
|
+ return $OCF_ERR_INSTALLED; |
|
+ 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"; |
|
+ return $OCF_ERR_INSTALLED; |
|
+ fi |
|
+ |
|
+ return $OCF_SUCCESS |
|
+} |
|
+ |
|
+mysql_common_status() { |
|
+ local loglevel=$1 |
|
+ local pid=$2 |
|
+ if [ -z "$pid" ]; then |
|
+ if [ ! -e $OCF_RESKEY_pid ]; then |
|
+ ocf_log $loglevel "MySQL is not running" |
|
+ return $OCF_NOT_RUNNING; |
|
+ fi |
|
+ |
|
+ pid=`cat $OCF_RESKEY_pid`; |
|
+ fi |
|
+ if [ -d /proc -a -d /proc/1 ]; then |
|
+ [ "u$pid" != "u" -a -d /proc/$pid ] |
|
+ else |
|
+ kill -s 0 $pid >/dev/null 2>&1 |
|
+ fi |
|
+ |
|
+ if [ $? -eq 0 ]; then |
|
+ return $OCF_SUCCESS; |
|
+ else |
|
+ ocf_log $loglevel "MySQL not running: removing old PID file" |
|
+ rm -f $OCF_RESKEY_pid |
|
+ return $OCF_NOT_RUNNING; |
|
+ fi |
|
+} |
|
+ |
|
+mysql_common_prepare_dirs() |
|
+{ |
|
+ local rc |
|
+ |
|
+ touch $OCF_RESKEY_log |
|
+ 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_is_true "$OCF_RESKEY_enable_creation" && [ ! -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 |
|
+ ocf_log err "Initialization failed: $rc"; |
|
+ exit $OCF_ERR_GENERIC |
|
+ fi |
|
+ chown -R $OCF_RESKEY_user:$OCF_RESKEY_group $OCF_RESKEY_datadir |
|
+ fi |
|
+ |
|
+ pid_dir=`dirname $OCF_RESKEY_pid` |
|
+ if [ ! -d $pid_dir ] ; then |
|
+ ocf_log info "Creating PID dir: $pid_dir" |
|
+ mkdir -p $pid_dir |
|
+ chown $OCF_RESKEY_user:$OCF_RESKEY_group $pid_dir |
|
+ fi |
|
+ |
|
+ socket_dir=`dirname $OCF_RESKEY_socket` |
|
+ if [ ! -d $socket_dir ] ; then |
|
+ ocf_log info "Creating socket dir: $socket_dir" |
|
+ mkdir -p $socket_dir |
|
+ chown $OCF_RESKEY_user:$OCF_RESKEY_group $socket_dir |
|
+ fi |
|
+ |
|
+ # Regardless of whether we just created the directory or it |
|
+ # already existed, check whether it is writable by the configured |
|
+ # user |
|
+ for dir in $pid_dir $socket_dir; do |
|
+ if ! su -s /bin/sh - $OCF_RESKEY_user -c "test -w $dir"; then |
|
+ ocf_log err "Directory $dir is not writable by $OCF_RESKEY_user" |
|
+ exit $OCF_ERR_PERM; |
|
+ fi |
|
+ done |
|
+} |
|
+ |
|
+mysql_common_start() |
|
+{ |
|
+ local mysql_extra_params="$1" |
|
+ local pid |
|
+ |
|
+ ${OCF_RESKEY_binary} --defaults-file=$OCF_RESKEY_config \ |
|
+ --pid-file=$OCF_RESKEY_pid \ |
|
+ --socket=$OCF_RESKEY_socket \ |
|
+ --datadir=$OCF_RESKEY_datadir \ |
|
+ --log-error=$OCF_RESKEY_log \ |
|
+ --user=$OCF_RESKEY_user $OCF_RESKEY_additional_parameters \ |
|
+ $mysql_extra_params >/dev/null 2>&1 & |
|
+ pid=$! |
|
+ |
|
+ # Spin waiting for the server to come up. |
|
+ # Let the CRM/LRM time us out if required. |
|
+ start_wait=1 |
|
+ while [ $start_wait = 1 ]; do |
|
+ if ! ps $pid > /dev/null 2>&1; then |
|
+ wait $pid |
|
+ ocf_log err "MySQL server failed to start (pid=$pid) (rc=$?), please check your installation" |
|
+ return $OCF_ERR_GENERIC |
|
+ fi |
|
+ mysql_common_status info |
|
+ rc=$? |
|
+ if [ $rc = $OCF_SUCCESS ]; then |
|
+ start_wait=0 |
|
+ elif [ $rc != $OCF_NOT_RUNNING ]; then |
|
+ ocf_log info "MySQL start failed: $rc" |
|
+ return $rc |
|
+ fi |
|
+ sleep 2 |
|
+ done |
|
+ |
|
+ return $OCF_SUCCESS |
|
+} |
|
+ |
|
+mysql_common_stop() |
|
+{ |
|
+ local pid |
|
+ local rc |
|
+ |
|
+ if [ ! -f $OCF_RESKEY_pid ]; then |
|
+ ocf_log info "MySQL is not running" |
|
+ return $OCF_SUCCESS |
|
+ fi |
|
+ |
|
+ pid=`cat $OCF_RESKEY_pid 2> /dev/null ` |
|
+ /bin/kill $pid > /dev/null |
|
+ rc=$? |
|
+ if [ $rc != 0 ]; then |
|
+ ocf_log err "MySQL couldn't be stopped" |
|
+ return $OCF_ERR_GENERIC |
|
+ fi |
|
+ # stop waiting |
|
+ shutdown_timeout=15 |
|
+ if [ -n "$OCF_RESKEY_CRM_meta_timeout" ]; then |
|
+ shutdown_timeout=$((($OCF_RESKEY_CRM_meta_timeout/1000)-5)) |
|
+ fi |
|
+ count=0 |
|
+ while [ $count -lt $shutdown_timeout ] |
|
+ do |
|
+ mysql_common_status info $pid |
|
+ rc=$? |
|
+ if [ $rc = $OCF_NOT_RUNNING ]; then |
|
+ break |
|
+ fi |
|
+ count=`expr $count + 1` |
|
+ sleep 1 |
|
+ ocf_log debug "MySQL still hasn't stopped yet. Waiting..." |
|
+ done |
|
+ |
|
+ mysql_common_status info $pid |
|
+ if [ $? != $OCF_NOT_RUNNING ]; then |
|
+ ocf_log info "MySQL failed to stop after ${shutdown_timeout}s using SIGTERM. Trying SIGKILL..." |
|
+ /bin/kill -KILL $pid > /dev/null |
|
+ fi |
|
+ |
|
+ ocf_log info "MySQL stopped"; |
|
+ rm -f /var/lock/subsys/mysqld |
|
+ rm -f $OCF_RESKEY_socket |
|
+ return $OCF_SUCCESS |
|
+ |
|
+} |
|
diff --git a/heartbeat/ocf-shellfuncs.in b/heartbeat/ocf-shellfuncs.in |
|
index 8820961..254da57 100644 |
|
--- a/heartbeat/ocf-shellfuncs.in |
|
+++ b/heartbeat/ocf-shellfuncs.in |
|
@@ -518,6 +518,7 @@ ocf_local_nodename() { |
|
which pacemakerd > /dev/null 2>&1 |
|
if [ $? -eq 0 ]; then |
|
local version=$(pacemakerd -$ | grep "Pacemaker .*" | awk '{ print $2 }') |
|
+ version=$(echo $version | awk -F- '{ print $1 }') |
|
ocf_version_cmp "$version" "1.1.8" |
|
if [ $? -eq 2 ]; then |
|
which crm_node > /dev/null 2>&1 |
|
-- |
|
1.8.4.2 |
|
|
|
|