Skip to content

Commit

Permalink
Merge pull request #61 from percona/v1.3.9-dev
Browse files Browse the repository at this point in the history
V1.3.9 dev
  • Loading branch information
rameshvs02 authored Aug 14, 2017
2 parents 4ccf34f + 8f4bd48 commit bc964e9
Show file tree
Hide file tree
Showing 5 changed files with 511 additions and 49 deletions.
18 changes: 17 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ Options:
--node-check-interval=3000 Interval for monitoring node checker script (in milliseconds)
--mode=[loadbal|singlewrite] ProxySQL read/write configuration mode, currently supporting: 'loadbal' and 'singlewrite' (the default) modes
--write-node=host_name:port Writer node to accept write statments. This option is supported only when using --mode=singlewrite
Can accept comma delimited list with the first listed being the highest priority.
--include-slaves=host_name:port Add specified slave node(s) to ProxySQL, these nodes will go into the reader hostgroup and will only be put into
the writer hostgroup if all cluster nodes are down. Slaves must be read only. Can accept comma delimited list.
If this is used make sure 'read_only=1' is in the slave's my.cnf
--adduser Adds the Percona XtraDB Cluster application user to the ProxySQL database
--syncusers Sync user accounts currently configured in MySQL to ProxySQL (deletes ProxySQL users not in MySQL)
--version, -v Print version info
Expand Down Expand Up @@ -110,8 +114,14 @@ ___Extra options___
__i) --mode__
This option allows you to setup read/write mode for cluster nodes in ProxySQL database based on the hostgroup. For now, the only supported modes are _loadbal_ and _singlewrite_. _singlewrite_ is the default mode, and it will configure Percona Cluster to only accept writes on one single node only (and this node can be provided either interactively or instead by using the --write-node option to specify the hostname and the port number for the one single write node). All other remaining nodes will be read-only and accept only read statements. The mode _loadbal_ on the other hand is a load balanced set of evenly weighted read/write nodes.
This option allows you to setup read/write mode for cluster nodes in ProxySQL database based on the hostgroup. For now, the only supported modes are _loadbal_ and _singlewrite_. _singlewrite_ is the default mode, and it will configure Percona Cluster to only accept writes on one single node only. All other remaining nodes will be read-only and accept only read statements.
With --write-node option we can control a priority order of what host is most desired to be the writer at any given time.
When used the feature will create the config file which is by default "/var/lib/proxysql/host_priority.conf", this is configurable in proxysql-admin.cnf. Servers can be specified comma delimited - 10.0.0.51:3306, 10.0.0.52:3306 - The 51 node will always be in the writer hostgroup if it is ONLINE, if it is OFFLINE the 52 node will go into the writer hostgroup, and if it goes down a node from the remaining nodes will be randomly chosen for the writer hostgroup.
This new config file will be deleted when --disable is used. This will ensure a specified writer-node will always be the writer node while it is ONLINE.
The mode _loadbal_ on the other hand is a load balanced set of evenly weighted read/write nodes.
_singlewrite_ mode setup:
```bash
$ sudo grep "MODE" /etc/proxysql-admin.cnf
Expand Down Expand Up @@ -291,3 +301,9 @@ mysql> select hostgroup_id,hostname,port,status,comment from mysql_servers;
mysql>
```
__vi) --include-slaves=host_name:port__
This option will help us to include specified slave node(s) to ProxySQL database. These nodes will go into the reader hostgroup and will only be put into the writer hostgroup if all cluster nodes are down. Slaves must be read only. Can accept comma delimited list. If this is used make sure 'read_only=1' is in the slave's my.cnf.

PS : With _loadbal_ mode slave hosts only accepts read/write requests when all cluster nodes are down.
118 changes: 104 additions & 14 deletions proxysql-admin
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ usage () {
echo " --node-check-interval=3000 Interval for monitoring node checker script (in milliseconds)"
echo " --mode=[loadbal|singlewrite] ProxySQL read/write configuration mode, currently supporting: 'loadbal' and 'singlewrite' (the default) modes"
echo " --write-node=host_name:port Writer node to accept write statments. This option is supported only when using --mode=singlewrite"
echo " Can accept comma delimited list with the first listed being the highest priority."
### Consider adding a select or prompt option for --write-node that will let you select from discovered nodes during setup ###
echo " --include-slaves=host_name:port Add specified slave node(s) to ProxySQL, these nodes will go into the reader hostgroup and will only be put into"
echo " the writer hostgroup if all cluster nodes are down. Slaves must be read only. Can accept comma delimited list."
echo " If this is used make sure 'read_only=1' is in the slave's my.cnf"
echo " --adduser Adds the Percona XtraDB Cluster application user to the ProxySQL database"
echo " --syncusers Sync user accounts currently configured in MySQL to ProxySQL (deletes ProxySQL users not in MySQL)"
echo " --version, -v Print version info"
Expand All @@ -66,7 +71,7 @@ usage () {
# Check if we have a functional getopt(1)
if ! getopt --test
then
go_out="$(getopt --options=edv --longoptions=config-file:,proxysql-username:,proxysql-password::,proxysql-hostname:,proxysql-port:,cluster-username:,cluster-password::,cluster-hostname:,cluster-port:,monitor-username:,monitor-password:,cluster-app-username:,cluster-app-password:,node-check-interval:,quick-demo,mode:,write-node:,enable,disable,adduser,syncusers,version,help \
go_out="$(getopt --options=edv --longoptions=config-file:,proxysql-username:,proxysql-password::,proxysql-hostname:,proxysql-port:,cluster-username:,cluster-password::,cluster-hostname:,cluster-port:,monitor-username:,monitor-password:,cluster-app-username:,cluster-app-password:,node-check-interval:,quick-demo,mode:,write-node:,include-slaves:,enable,disable,adduser,syncusers,version,help \
--name="$(basename "$0")" -- "$@")"
test $? -eq 0 || exit 1
eval set -- "$go_out"
Expand Down Expand Up @@ -215,7 +220,17 @@ do
fi
;;
--write-node )
WRITE_NODE="$2"
# if [ `grep -o ',' <<< $2 | wc -l` -gt 0 ];then
WRITE_NODES=`echo "$2" | sed 's/,/ /g'`
WRITE_NODE=`echo "$WRITE_NODES" | cut -d' ' -f1`
enable_priority=1
# else
# WRITE_NODE="$2"
# fi
shift 2
;;
--include-slaves )
SLAVE_NODES=`echo "$2" | sed 's/,/ /g'`
shift 2
;;
--quick-demo )
Expand All @@ -224,7 +239,7 @@ do
ENABLE=1
;;
-v | --version )
echo "proxysql-admin version 1.3.7"
echo "proxysql-admin version 1.3.9"
exit 0
;;
--help )
Expand Down Expand Up @@ -358,15 +373,18 @@ else
fi
fi

# Set default hostgroup values if not set in the config file
if [ -z $WRITE_HOSTGROUP_ID ];then WRITE_HOSTGROUP_ID=10;fi
if [ -z $READ_HOSTGROUP_ID ];then READ_HOSTGROUP_ID=11;fi

if [ $MODE == "loadbal" ]; then
WRITE_HOSTGROUP_ID=10
READ_HOSTGROUP_ID=10
SLAVEREAD_HOSTGROUP_ID=$READ_HOSTGROUP_ID
READ_HOSTGROUP_ID=$WRITE_HOSTGROUP_ID
if [ -e "${CONFIG_FILE}" ]; then
sudo sed -i "0,/^[ \t]*export MODE[ \t]*=.*$/s|^[ \t]*export MODE[ \t]*=.*$|export MODE=\"loadbal\"|" "${CONFIG_FILE}"
fi
elif [ $MODE == "singlewrite" ]; then
WRITE_HOSTGROUP_ID=10
READ_HOSTGROUP_ID=11
SLAVEREAD_HOSTGROUP_ID=$READ_HOSTGROUP_ID
if [ -e "${CONFIG_FILE}" ]; then
sudo sed -i "0,/^[ \t]*export MODE[ \t]*=.*$/s|^[ \t]*export MODE[ \t]*=.*$|export MODE=\"singlewrite\"|" "${CONFIG_FILE}"
fi
Expand All @@ -387,6 +405,12 @@ mysql_exec() {
mysql --defaults-file=/dev/stdin --protocol=tcp -Bse "${query}" 2>/dev/null
}

slave_exec() {
query=$1
printf "[client]\nuser=${CLUSTER_USERNAME}\npassword=${CLUSTER_PASSWORD}\nhost=${SLAVE_HOSTNAME}\nport=${SLAVE_PORT}\n" | \
mysql --defaults-file=/dev/stdin --protocol=tcp -Bse "${query}" 2>/dev/null
}

proxysql_connection_check(){
CONNECTION_MSG=$( { printf "[client]\nuser=${PROXYSQL_USERNAME}\npassword=${PROXYSQL_PASSWORD}\nhost=${PROXYSQL_HOSTNAME}\nport=${PROXYSQL_PORT}\n" | mysql --defaults-file=/dev/stdin --protocol=tcp -e "show tables" >/dev/null; } 2>&1 )
if [[ ! -z $CONNECTION_MSG ]]; then
Expand Down Expand Up @@ -556,11 +580,47 @@ enable_proxysql(){
echo -e "\nConfiguring the Percona XtraDB Cluster application user to connect through ProxySQL"
user_input_check CLUSTER_APP "Percona XtraDB Cluster application user" $WRITE_HOSTGROUP_ID

# Get the nodes in the cluster
wsrep_address=($(mysql_exec "show status like 'wsrep_incoming_addresses'" | awk '{print $2}' | sed 's|,| |g'))

# If any slave nodes were specified, verify they are replicating from a valid cluster node
if [ -n "$SLAVE_NODES" ];then
echo -e "\nVerifying specified slave nodes"
for i in $SLAVE_NODES;do
SLAVE_HOSTNAME=`echo $i | cut -d: -f1`
SLAVE_PORT=`echo $i | cut -d: -f2`
# Verify we can connect to the slave
slave_exec 'show slave status\G' > /dev/null
check_cmd $? "Failed to connect to $i, please check username, password and other options for connecting to the slave"
# Check each of the specified slaves and verify they are a slave of one of the XtraDB cluster nodes
slave_master=$(slave_exec 'show slave status\G'| egrep "Master_Host|Master_Port" | sed 's/ //g' | cut -d: -f2 | tr '\n' ':' | sed 's/:$//g')
if [[ ${wsrep_address[*]} != *"$slave_master"* ]]; then
echo -e "\nERROR: The slave node's master ($slave_master) does not exist in WSREP incoming address(${wsrep_address[*]})."
echo -e "The specified slave is not replicating from any of the XDtraDB cluster nodes, this is not supported"
echo -e "Please configure ProxySQL manually.. Terminating!"
exit 1
fi
# Verify the slave read-only variable is set to '1'
slave_ro=$(slave_exec 'SELECT @@read_only')
if [ "$slave_ro" != "1" ];then
echo -e "\nERROR: The slave $i is not set to read only. Add 'read_only=1' to the my.cnf on the slave"
echo -e "and restart MySQL. Execute 'SET GLOBAL read_only = 1' on the slave to avoid the restart"
echo -e "Correct this on slave nodes and run proxysql-admin again. Terminating!"
exit 1
fi
done
# GRANT REPLICATION CLIENT permissions to the monitoring user account
echo -e "\nGranting 'REPLICATION CLIENT' privilege to $MONITOR_USERNAME@$USER_HOST_RANGE"
mysql_exec "GRANT REPLICATION CLIENT ON *.* TO $MONITOR_USERNAME@'$USER_HOST_RANGE';"
check_cmd $? "$CLUSTER_USERNAME@'$CLUSTER_HOSTNAME' does not have the GRANT privilege required to assign the requested permissions"
fi

# Adding Percona XtraDB Cluster nodes to ProxySQL
echo -e "\nAdding the Percona XtraDB Cluster server nodes to ProxySQL"
# Delete an existing host priority file if its there
rm -f $HOST_PRIORITY_FILE
if [ $MODE == "loadbal" ]; then
proxysql_exec "DELETE FROM mysql_servers WHERE hostgroup_id=$WRITE_HOSTGROUP_ID"
wsrep_address=($(mysql_exec "show status like 'wsrep_incoming_addresses'" | awk '{print $2}' | sed 's|,| |g'))
for i in "${wsrep_address[@]}"; do
ws_ip=$(echo "$i" | cut -d':' -f1)
ws_port=$(echo "$i" | cut -d':' -f2)
Expand Down Expand Up @@ -595,13 +655,27 @@ enable_proxysql(){
writer_ws_port=$CLUSTER_PORT
fi
proxysql_exec "DELETE FROM mysql_servers WHERE hostgroup_id=$WRITE_HOSTGROUP_ID"
wsrep_address=($(mysql_exec "show status like 'wsrep_incoming_addresses'" | awk '{print $2}' | sed 's|,| |g'))
if [[ ${wsrep_address[*]} != *"$writer_ws_ip:$writer_ws_port"* ]]; then
echo -e "\nERROR: Writer node cluster address($writer_ws_ip:$writer_ws_port) does not exist in WSREP incoming address(${wsrep_address[*]})."
echo -e "Different wsrep incoming and cluster IP addresses are not supported by proxysql-admin at this time"
echo -e "Please configure ProxySQL manually.. Terminating!"
exit 1
fi

# Create the host priority file if multiple write nodes were specified
if [ -n $enable_priority ];then
# Create empty priority config file
echo '# ProxySQL Host Priority File' > $HOST_PRIORITY_FILE
echo '# Specify nodes in order from highest priority to lowest' >> $HOST_PRIORITY_FILE
check_cmd $? "Failed to create the host priority file, verify the directory permissions: $HOST_PRIORITY_FILE"
# Add the specified hosts to the file
echo -e "\nConfiguring $MODE mode with the following nodes designated as priority order:"
for i in $WRITE_NODES;do
echo $i >> $HOST_PRIORITY_FILE
echo " $i"
done
fi

for i in "${wsrep_address[@]}"; do
ws_ip=$(echo "$i" | cut -d':' -f1)
ws_port=$(echo "$i" | cut -d':' -f2)
Expand All @@ -620,6 +694,19 @@ enable_proxysql(){
proxysql_exec "LOAD MYSQL SERVERS TO RUNTIME; SAVE MYSQL SERVERS TO DISK;LOAD MYSQL QUERY RULES TO RUNTIME;SAVE MYSQL QUERY RULES TO DISK;"
fi

# Adding slave nodes here if specified
if [ -n "$SLAVE_NODES" ];then
echo -e "\nAdding the following slave server nodes to ProxySQL:"
for i in $SLAVE_NODES;do
ws_ip=$(echo "$i" | cut -d':' -f1)
ws_port=$(echo "$i" | cut -d':' -f2)
proxysql_exec "INSERT INTO mysql_servers (hostname,hostgroup_id,port,weight,comment) VALUES ('$ws_ip',$SLAVEREAD_HOSTGROUP_ID,$ws_port,1000,'SLAVEREAD');"
check_cmd $? "Failed to add the slave node $ws_ip:$ws_port. Please check username, password and other options for connecting to ProxySQL database"
proxysql_exec "LOAD MYSQL SERVERS TO RUNTIME; SAVE MYSQL SERVERS TO DISK;"
echo " $i"
done
fi

# Adding Percona XtraDB Cluster monitoring scripts
# Adding proxysql galera check scheduler
proxysql_exec "DELETE FROM SCHEDULER WHERE ID=10;"
Expand All @@ -644,18 +731,21 @@ enable_proxysql(){
# Removing Percona XtraDB Cluster configuration from proxysql
disable_proxysql(){
proxysql_connection_check
proxysql_exec "DELETE FROM mysql_users WHERE default_hostgroup in ($WRITE_HOSTGROUP_ID,$READ_HOSTGROUP_ID);"
check_cmd $? "Failed to delete the Percona XtraDB Cluster user from ProxySQL. Please check username, password and other options for connecting to ProxySQL database"
echo "Removing default cluster application user from ProxySQL database."
proxysql_exec "DELETE FROM mysql_users WHERE username='$CLUSTER_APP_USERNAME';"
check_cmd $? "Failed to delete the Percona XtraDB Cluster user ($CLUSTER_APP_USERNAME) from ProxySQL. Please check username, password and other options for connecting to ProxySQL database"
echo "Removing cluster nodes from ProxySQL database."
proxysql_exec "DELETE FROM mysql_servers WHERE hostgroup_id in ($WRITE_HOSTGROUP_ID,$READ_HOSTGROUP_ID);"
check_cmd $? "Failed to delete the Percona XtraDB Cluster nodes from ProxySQL. Please check username, password and other options for connecting to ProxySQL database"
#proxysql_exec "DELETE FROM SCHEDULER WHERE ID IN (10,11);"
#check_cmd $? "Failed to delete the Galera checker and node monitoring scheduler from ProxySQL"
echo "Removing scheduler script from ProxySQL database."
proxysql_exec "DELETE FROM SCHEDULER WHERE ID IN (10);"
check_cmd $? "Failed to delete the Galera checker from ProxySQL. Please check username, password and other options for connecting to ProxySQL database"
echo "Removing query rules from ProxySQL database if any."
proxysql_exec "DELETE FROM mysql_query_rules WHERE destination_hostgroup in ($WRITE_HOSTGROUP_ID,$READ_HOSTGROUP_ID)"
check_cmd $? "Failed to delete the query rules from ProxySQL. Please check username, password and other options for connecting to ProxySQL database"
proxysql_exec "LOAD MYSQL USERS TO RUNTIME;SAVE MYSQL USERS TO DISK;LOAD SCHEDULER TO RUNTIME;SAVE SCHEDULER TO DISK;LOAD MYSQL SERVERS TO RUNTIME; SAVE MYSQL SERVERS TO DISK;LOAD MYSQL QUERY RULES TO RUNTIME;SAVE MYSQL QUERY RULES TO DISK;"

# Delete the host priority file
rm -f $HOST_PRIORITY_FILE
}

adduser(){
Expand Down
3 changes: 3 additions & 0 deletions proxysql-admin.cnf
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,6 @@ export READ_HOSTGROUP_ID="11"

# ProxySQL read/write configuration mode.
export MODE="singlewrite"

# ProxySQL Cluster Node Priority File
export HOST_PRIORITY_FILE="/var/lib/proxysql/host_priority.conf"
Loading

0 comments on commit bc964e9

Please sign in to comment.