forked from percona/proxysql-admin-tool
-
Notifications
You must be signed in to change notification settings - Fork 0
/
proxysql-admin
executable file
·975 lines (914 loc) · 44.6 KB
/
proxysql-admin
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
#!/bin/bash
# This script will assist with configuring ProxySQL (currently only Percona XtraDB cluster in combination with ProxySQL is supported)
# Version 1.0
###############################################################################################
# This program is copyright 2016-2017 Percona LLC and/or its affiliates.
#
# THIS PROGRAM IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
# WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation, version 2 or later
#
# You should have received a copy of the GNU General Public License version 2
# along with this program; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
# Make sure only root can run this script
if [ "$(id -u)" -ne 0 ]; then
echo "ERROR: This script must be run as root!" 1>&2
exit 1
fi
#bash prompt internal configuration
BD=$(tput bold)
NBD=$(tput sgr0)
# Internal variables
if [ -e "/dummypathnonexisting/.mylogin.cnf" ]; then
echo "ERROR! /dummypathnonexisting/.mylogin.cnf found. This should not happen. Terminating";
exit 1
else
export HOME="/dummypathnonexisting"
fi
# Dispay script usage details
usage () {
echo "Usage: [ options ]"
echo "Options:"
echo " --config-file=<config-file> Read login credentials from a configuration file (overrides any login credentials specified on the command line)"
echo " --quick-demo Setup a quick demo with no authentication"
echo " --proxysql-datadir=<datadir> Specify proxysql data directory location"
echo " --proxysql-username=user_name Username for connecting to the ProxySQL service"
echo " --proxysql-password[=password] Password for connecting to the ProxySQL service"
echo " --proxysql-port=port_num Port Nr. for connecting to the ProxySQL service"
echo " --proxysql-hostname=host_name Hostname for connecting to the ProxySQL service"
echo " --cluster-username=user_name Username for connecting to the Percona XtraDB Cluster node"
echo " --cluster-password[=password] Password for connecting to the Percona XtraDB Cluster node"
echo " --cluster-port=port_num Port Nr. for connecting to the Percona XtraDB Cluster node"
echo " --cluster-hostname=host_name Hostname for connecting to the Percona XtraDB Cluster node"
echo " --cluster-app-username=user_name Application username for connecting to the Percona XtraDB Cluster node"
echo " --cluster-app-password[=password] Application password for connecting to the Percona XtraDB Cluster node"
echo " --without-cluster-app-user Configure Percona XtraDB Cluster without application user"
echo " --monitor-username=user_name Username for monitoring Percona XtraDB Cluster nodes through ProxySQL"
echo " --monitor-password[=password] Password for monitoring Percona XtraDB Cluster nodes through ProxySQL"
echo " --enable, -e Auto-configure Percona XtraDB Cluster nodes into ProxySQL"
echo " --disable, -d Remove any Percona XtraDB Cluster configurations from ProxySQL"
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"
}
# Check if we have a functional getopt(1)
if ! getopt --test
then
go_out="$(getopt --options=edv --longoptions=config-file:,proxysql-datadir:,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:,without-cluster-app-user,enable,disable,adduser,syncusers,version,help \
--name="$(basename "$0")" -- "$@")"
test $? -eq 0 || exit 1
eval set -- "$go_out"
fi
if [[ $go_out == " --" ]];then
usage
exit 1
fi
if ! echo "$go_out" | grep -q 'config-file'; then
if ! echo "$go_out" | grep -q 'quick-demo'; then
# Reading default variables from default configuration file location.
if [ -e "/etc/proxysql-admin.cnf" ]; then
# Loading default configuration from /etc/proxysql-admin.cnf
source /etc/proxysql-admin.cnf
CONFIG_FILE="/etc/proxysql-admin.cnf"
else
echo "WARNING! Default configuration file (/etc/proxysql-admin.cnf) does not exist"
fi
fi
fi
for arg
do
case "$arg" in
-- ) shift; break;;
--config-file )
CONFIG_FILE="$2"
shift 2
if [ -z "${CONFIG_FILE}" ]; then
echo "ERROR: The configuration file location (--config-file) was not provided. Terminating."
exit 1
fi
if [ -e "${CONFIG_FILE}" ]; then
# Loading configuration from ${CONFIG_FILE}
source "${CONFIG_FILE}"
else
echo "ERROR: The configuration file ${CONFIG_FILE} specified by --config-file does not exist. Terminating."
exit 1
fi
;;
--proxysql-datadir )
PROXYSQL_DATADIR="$2"
shift 2
;;
--proxysql-username )
PROXYSQL_USERNAME="$2"
shift 2
;;
--proxysql-password )
case "$2" in
"")
read -r -s -p "Enter ProxySQL password:" INPUT_PASS
if [ -z "$INPUT_PASS" ]; then
PROXYSQL_PASSWORD=""
printf "\nContinuing without ProxySQL password...\n";
else
PROXYSQL_PASSWORD="$INPUT_PASS"
fi
printf "\n"
;;
*)
PROXYSQL_PASSWORD="$2"
;;
esac
shift 2
;;
--proxysql-hostname )
PROXYSQL_HOSTNAME="$2"
shift 2
;;
--proxysql-port )
PROXYSQL_PORT="$2"
shift 2
;;
--cluster-username )
CLUSTER_USERNAME="$2"
shift 2
;;
--cluster-password )
case "$2" in
"")
read -r -s -p "Enter Percona XtraDB Cluster password:" INPUT_PASS
if [ -z "$INPUT_PASS" ]; then
CLUSTER_PASSWORD=""
printf "\nContinuing without Percona XtraDB Cluster password...\n";
else
CLUSTER_PASSWORD="$INPUT_PASS"
fi
printf "\n"
;;
*)
CLUSTER_PASSWORD="$2"
;;
esac
shift 2
;;
--cluster-hostname )
CLUSTER_HOSTNAME="$2"
shift 2
;;
--cluster-port )
CLUSTER_PORT="$2"
shift 2
;;
--monitor-username )
MONITOR_USERNAME="$2"
shift 2
;;
--monitor-password )
MONITOR_PASSWORD="$2"
shift 2
;;
--cluster-app-username )
CLUSTER_APP_USERNAME="$2"
shift 2
;;
--cluster-app-password )
CLUSTER_APP_PASSWORD="$2"
shift 2
;;
--without-cluster-app-user )
shift
WITHOUT_CLUSTER_APP_USER=1
;;
-e | --enable )
shift
ENABLE=1
;;
--adduser )
shift
ADDUSER=1
;;
--syncusers )
shift
SYNCUSERS=1
;;
-d | --disable )
shift
DISABLE=1
;;
--node-check-interval )
NODE_CHECK_INTERVAL="$2"
shift 2
;;
--mode )
MODE="$2"
shift 2
if [ "$MODE" != "loadbal" ] && [ "$MODE" != "singlewrite" ]; then
echo "ERROR: Invalid --mode passed:"
echo " Please choose any of these modes: loadbal, singlewrite"
exit 1
fi
;;
--write-node )
# 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 )
shift
QUICK_DEMO="YES"
ENABLE=1
;;
-v | --version )
echo "proxysql-admin version 1.4.8"
exit 0
;;
--help )
usage
exit 0
;;
esac
done
if [ ! -z "$QUICK_DEMO" ]; then
echo -e "\nThis script will assist with configuring ProxySQL (currently only Percona XtraDB cluster in combination with ProxySQL is supported)"
echo -e "\nYou have selected the dry test run mode. WARNING: This will create a test user (with all privileges) in the Percona XtraDB Cluster & ProxySQL installations.\n"
echo -e "You may want to delete this user after you complete your testing!\n"
read -r -p "Would you like to proceed with '--quick-demo' [y/n] ? " check_param
case $check_param in
y|Y)
echo -e "\nSetting up proxysql test configuration!\n"
;;
n|N)
echo -e "\nYou have selected No. Terminating.\n"
exit 1
;;
*)
echo "Please type [y/n]! Terminating."
exit 1
;;
esac
fi
if [[ ! -e $(which mysql 2> /dev/null) ]] ;then
echo "The mysql client was not found, please install the mysql client package using your OS packaging manager!"
exit 1
fi
# Check the options gathered from the command line
if [ -z "$QUICK_DEMO" ]; then
if [ -z "$PROXYSQL_USERNAME" ];then
echo "The ProxySQL username is required!"
usage
exit 1
fi
if [[ -z "$PROXYSQL_HOSTNAME" ]]; then
PROXYSQL_HOSTNAME="127.0.0.1"
fi
if [[ -z "$PROXYSQL_PORT" ]]; then
PROXYSQL_PORT="6032"
fi
if [ -z "$CLUSTER_USERNAME" ];then
echo "The Percona XtraDB Cluster username is required!"
usage
exit 1
fi
if [[ -z "$CLUSTER_HOSTNAME" ]]; then
CLUSTER_HOSTNAME="localhost"
fi
if [[ -z "$CLUSTER_PORT" ]]; then
CLUSTER_PORT="localhost"
fi
else
read -r -p "Do you want to use the default ProxySQL credentials (admin:admin:6032:127.0.0.1) [y/n] ? " check_param
case $check_param in
y|Y)
PROXYSQL_USERNAME="admin"
PROXYSQL_PASSWORD="admin"
PROXYSQL_PORT="6032"
PROXYSQL_HOSTNAME="127.0.0.1"
;;
n|N)
echo ""
echo -n "Enter the ProxySQL user name: "
read -r PROXYSQL_USERNAME
read -r -s -p "Enter the ProxySQL user password: " PROXYSQL_PASSWORD;echo ""
echo -n "Enter the ProxySQL port: "
read -r PROXYSQL_PORT
echo -n "Enter the ProxySQL hostname: "
read -r PROXYSQL_HOSTNAME
echo ""
;;
*)
echo "Please type [y/n]! Terminating."
exit 1
;;
esac
read -r -p "Do you want to use the default Percona XtraDB Cluster credentials (root::3306:127.0.0.1) [y/n] ? " check_param
case $check_param in
y|Y)
CLUSTER_USERNAME="root"
CLUSTER_PASSWORD=""
CLUSTER_PORT="3306"
CLUSTER_HOSTNAME="127.0.0.1"
;;
n|N)
echo ""
echo -n "Enter the Percona XtraDB Cluster username (super user): "
read -r CLUSTER_USERNAME
read -r -s -p "Enter the Percona XtraDB Cluster user password: " CLUSTER_PASSWORD; echo ""
echo -n "Enter the Percona XtraDB Cluster port: "
read -r CLUSTER_PORT
echo -n "Enter the Percona XtraDB Cluster hostname: "
read -r CLUSTER_HOSTNAME
echo ""
;;
*)
echo "Please type [y/n]! Terminating."
exit 1
;;
esac
MONITOR_USERNAME='monitor'
MONITOR_PASSWORD='monitor'
CLUSTER_APP_USERNAME='pxc_test_user'
CLUSTER_APP_PASSWORD=''
fi
if [[ -z "$PROXYSQL_DATADIR" ]]; then
PROXYSQL_DATADIR='/var/lib/proxysql'
fi
if [[ -z "$NODE_CHECK_INTERVAL" ]]; then
NODE_CHECK_INTERVAL=3000
fi
if [[ -z "$MODE" ]]; then
MODE="singlewrite"
else
if [ "$MODE" != "loadbal" ] && [ "$MODE" != "singlewrite" ]; then
echo "ERROR: Invalid --mode passed:"
echo " Please choose any of these modes: loadbal, singlewrite"
exit 1
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
SLAVEREAD_HOSTGROUP_ID=$READ_HOSTGROUP_ID
READ_HOSTGROUP_ID=$WRITE_HOSTGROUP_ID
if [ -e "${CONFIG_FILE}" ]; then
sed -i "0,/^[ \t]*export MODE[ \t]*=.*$/s|^[ \t]*export MODE[ \t]*=.*$|export MODE=\"loadbal\"|" "${CONFIG_FILE}"
fi
elif [ $MODE == "singlewrite" ]; then
SLAVEREAD_HOSTGROUP_ID=$READ_HOSTGROUP_ID
if [ -e "${CONFIG_FILE}" ]; then
sed -i "0,/^[ \t]*export MODE[ \t]*=.*$/s|^[ \t]*export MODE[ \t]*=.*$|export MODE=\"singlewrite\"|" "${CONFIG_FILE}"
fi
fi
export PIDFILE="/tmp/cluster-proxysql-monitor.pid"
proxysql_exec() {
query=$1
args=$2
printf "[client]\nuser=${PROXYSQL_USERNAME}\npassword=\"${PROXYSQL_PASSWORD}\"\nhost=${PROXYSQL_HOSTNAME}\nport=${PROXYSQL_PORT}\n" | \
mysql --defaults-file=/dev/stdin --protocol=tcp -"${args}"e "${query}" 2>/dev/null
}
mysql_exec() {
query=$1
printf "[client]\nuser=${CLUSTER_USERNAME}\npassword=\"${CLUSTER_PASSWORD}\"\nhost=${CLUSTER_HOSTNAME}\nport=${CLUSTER_PORT}\n" | \
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
echo "$CONNECTION_MSG"
echo "Please check the ProxySQL connection parameters! Terminating."
exit 1
fi
}
cluster_connection_check(){
CONNECTION_MSG=$( { printf "[client]\nuser=${CLUSTER_USERNAME}\npassword=\"${CLUSTER_PASSWORD}\"\nhost=${CLUSTER_HOSTNAME}\nport=${CLUSTER_PORT}\n" | mysql --defaults-file=/dev/stdin --protocol=tcp -Bse "select @@port" >/dev/null; } 2>&1 )
if [[ ! -z $CONNECTION_MSG ]]; then
echo "$CONNECTION_MSG"
echo "Please check the Percona XtraDB Cluster connection parameters! Terminating."
exit 1
fi
}
check_cmd(){
MPID=$1
ERROR_MSG=$2
if [ "${MPID}" -ne 0 ]; then echo -e "\nERROR: $ERROR_MSG. Terminating!"; exit 1; fi
}
check_proxysql(){
if ! pidof proxysql >/dev/null ; then
echo "ProxySQL is not running, please check the error log at $PROXYSQL_DATADIR/proxysql.log"
exit 1
fi
}
CLUSTER_NAME=$(mysql_exec "select @@wsrep_cluster_name;")
rm -rf ${PROXYSQL_DATADIR}/${CLUSTER_NAME}_mode
echo "$MODE" > ${PROXYSQL_DATADIR}/${CLUSTER_NAME}_mode
user_input_check(){
USER_CATEGORY=$1
USER_DESCRIPTION=$2
HOSTGROUP_ID=$3
USERNAME=$(eval "echo \$${USER_CATEGORY}_USERNAME")
PASSWORD=$(eval "echo \$${USER_CATEGORY}_PASSWORD")
if [[ -z "$USERNAME" ]]; then
read -r -p "Enter ${USER_DESCRIPTION}name : " ${USER_CATEGORY}_USERNAME
while [[ -z "${USER_CATEGORY}_USERNAME" ]]
do
echo -n "No input entered, Enter ${USER_DESCRIPTION}name: "
read -r ${USER_CATEGORY}_USERNAME
done
else
if [ -z "$QUICK_DEMO" ]; then
echo -e "${USER_DESCRIPTION}name as per command line/config-file is ${BD}$(eval "echo \$${USER_CATEGORY}_USERNAME")${NBD}"
fi
fi
if [[ -z $PASSWORD ]]; then
if [ -z "$QUICK_DEMO" ]; then
read -r -s -p "Enter ${USER_DESCRIPTION} password: " ${USER_CATEGORY}_PASSWORD
while [[ -z "${USER_CATEGORY}_PASSWORD" ]]
do
read -r -s -p "No input entered, Enter ${USER_DESCRIPTION} password: " ${USER_CATEGORY}_PASSWORD
done
fi
fi
USERNAME=$(eval "echo \$${USER_CATEGORY}_USERNAME")
PASSWORD=$(eval "echo \$${USER_CATEGORY}_PASSWORD")
if [ "$USER_CATEGORY" != "MONITOR" ]; then
check_user=$(mysql_exec "SELECT user,host FROM mysql.user where user='$USERNAME' and host='$USER_HOST_RANGE';")
if [[ -z "$check_user" ]]; then
precheck_user=$(proxysql_exec "SELECT username FROM mysql_users where username='$USERNAME'")
if [[ -z "$precheck_user" ]]; then
mysql_exec "CREATE USER $USERNAME@'$USER_HOST_RANGE' IDENTIFIED BY '$PASSWORD';"
check_cmd $? "Failed to add Percona XtraDB Cluster application user: '$USERNAME'. Please check '$CLUSTER_USERNAME'@'$CLUSTER_HOSTNAME' has proper permission to create montioring user"
if [ ! -z "$QUICK_DEMO" ]; then
mysql_exec "GRANT ALL ON *.* to $USERNAME@'$USER_HOST_RANGE'"
check_cmd $? "$CLUSTER_USERNAME@'$CLUSTER_HOSTNAME' does not have the GRANT privilege required to assign the requested permissions"
fi
proxysql_exec "INSERT INTO mysql_users (username,password,active,default_hostgroup) values ('$USERNAME','$PASSWORD',1,$HOSTGROUP_ID);LOAD MYSQL USERS TO RUNTIME;SAVE MYSQL USERS FROM RUNTIME;SAVE MYSQL USERS TO DISK;"
check_cmd $? "Failed to add Percona XtraDB Cluster application user: '$USERNAME' in ProxySQL database. Please check username, password and other options for connecting to ProxySQL database"
if [ -z "$QUICK_DEMO" ]; then
echo -e "\nPercona XtraDB Cluster application user '${BD}$USERNAME'@'$USER_HOST_RANGE${NBD}' has been added with the USAGE privilege, please make sure to the grant appropriate privileges"
else
echo -e "\nPercona XtraDB Cluster application user '${BD}$USERNAME'@'$USER_HOST_RANGE${NBD}' has been added with ${BD}ALL${NBD} privileges, ${BD}this user is created for testing purposes${NBD}"
fi
else
echo -e "\nERROR: The application user ${BD}$USERNAME${NBD} is already present in ProxySQL database. Terminating!"
echo -e " Note: ProxySQL do not allow duplicate username."
exit 1
fi
else
check_user=$(proxysql_exec "SELECT username FROM mysql_users where username='$USERNAME'")
if [[ -z "$check_user" ]]; then
echo -e "\nApplication user '${BD}${USERNAME}'@'$USER_HOST_RANGE${NBD}' already present in Percona XtraDB Cluster."
proxysql_exec "INSERT INTO mysql_users (username,password,active,default_hostgroup) values ('$USERNAME','$PASSWORD',1,$HOSTGROUP_ID);LOAD MYSQL USERS TO RUNTIME;SAVE MYSQL USERS FROM RUNTIME;SAVE MYSQL USERS TO DISK;"
check_cmd $? "Failed to add Percona XtraDB Cluster application user: '$USERNAME' in ProxySQL database. Please check username, password and other options for connecting to ProxySQL database"
else
echo -e "\nERROR: The application user ${BD}$USERNAME${NBD} is already present in ProxySQL database. Terminating!"
echo -e " Note: ProxySQL do not allow duplicate username."
exit 1
fi
fi
fi
}
# Auto configure Percona XtraDB Cluster nodes into ProxySQL
enable_proxysql(){
# Checking proxysql binary location
if [[ ! -e $(which proxysql 2> /dev/null) ]]; then
echo "The proxysql binary was not found, please install the ProxySQL package"
exit 1
elif [[ ! -e $(which proxysql_galera_checker 2> /dev/null) ]] ;then
echo "The proxysql_galera_checker binary was not found, please check the ProxySQL package installation"
exit 1
elif [[ ! -e $(which proxysql_node_monitor 2> /dev/null) ]]; then
echo "The proxysql_node_monitor binary was not found, please check the ProxySQL package installation"
exit 1
else
PROXYSQL=$(which proxysql)
PROXYSQL_GALERA_CHECK=$(which proxysql_galera_checker)
PROXYSQL_NODE_MONITOR=$(which proxysql_node_monitor)
fi
# Check for existing proxysql process
if ! pidof proxysql >/dev/null ; then
echo "ProxySQL is not running; please start the proxysql service"
exit 1
fi
proxysql_connection_check
# Checking an existing host priority file if its there
if [ -f $HOST_PRIORITY_FILE ]; then
echo ""
read -p "Host priority file ($HOST_PRIORITY_FILE) is already present. Would you like to replace with the new file [y/n] ? " check_param
case $check_param in
y|Y)
rm -f $HOST_PRIORITY_FILE
;;
n|N)
echo -e "\nHost priority file is not deleted. Please make sure you have properly configured $HOST_PRIORITY_FILE"
;;
*)
echo "Please type [y/n]! Terminating."
exit 1
;;
esac
fi
#modifying proxysql-admin.cnf file with command line proxysql user credentials if you dont use --config-file option.
#if [ -z "${CONFIG_FILE}" ]; then
# sed -i "s|[ \t]*PROXYSQL_USERNAME[ \t]*=.*$| PROXYSQL_USERNAME=\"${PROXYSQL_USERNAME}\"|" /etc/proxysql-admin.cnf
# sed -i "s|[ \t]*PROXYSQL_PASSWORD[ \t]*=.*$| PROXYSQL_PASSWORD=\"${PROXYSQL_PASSWORD}\"|" /etc/proxysql-admin.cnf
# sed -i "s|[ \t]*PROXYSQL_HOSTNAME[ \t]*=.*$| PROXYSQL_HOSTNAME=\"${PROXYSQL_HOSTNAME}\"|" /etc/proxysql-admin.cnf
# sed -i "s|[ \t]*PROXYSQL_PORT[ \t]*=.*$| PROXYSQL_PORT=\"${PROXYSQL_PORT}\"|" /etc/proxysql-admin.cnf
#fi
cluster_connection_check
check_hgs=$(proxysql_exec "SELECT hostgroup_id FROM mysql_servers where hostgroup_id in ($READ_HOSTGROUP_ID,$WRITE_HOSTGROUP_ID)")
if [[ ! -z "$check_hgs" ]]; then
echo -e "\nERROR: READ/WRITE hostgroups($READ_HOSTGROUP_ID,$WRITE_HOSTGROUP_ID) are already present in ProxySQL database. Terminating!"
exit 1
fi
CLUSTER_NETWORK=$(mysql_exec "show status like 'wsrep_incoming_addresses'" | awk '{print $2}' | cut -d'.' -f1)
if [[ "$CLUSTER_NETWORK" =~ ^[0-9]+$ ]]; then
USER_HOST_RANGE="$CLUSTER_NETWORK.%"
else
USER_HOST_RANGE="%"
fi
echo -e "\nConfiguring ProxySQL monitoring user.."
user_input_check MONITOR "ProxySQL monitor user"
check_user=$(mysql_exec "SELECT user,host FROM mysql.user where user='$MONITOR_USERNAME' and host='$USER_HOST_RANGE';")
if [[ -z "$check_user" ]]; then
mysql_exec "CREATE USER '$MONITOR_USERNAME'@'$USER_HOST_RANGE' IDENTIFIED BY '$MONITOR_PASSWORD';"
check_cmd $? "Failed to create the ProxySQL monitoring user. Please check '$CLUSTER_USERNAME'@'$CLUSTER_HOSTNAME' has proper permission to create montioring user"
proxysql_exec "update global_variables set variable_value='$MONITOR_USERNAME' where variable_name='mysql-monitor_username'; update global_variables set variable_value='$MONITOR_PASSWORD' where variable_name='mysql-monitor_password'; "
check_cmd $? "Failed to set the mysql-monitor variables in ProxySQL. Please check username, password and other options for connecting to ProxySQL database"
proxysql_exec "LOAD MYSQL VARIABLES TO RUNTIME;SAVE MYSQL VARIABLES TO DISK;"
echo -e "\nUser '${BD}$MONITOR_USERNAME'@'$USER_HOST_RANGE${NBD}' has been added with USAGE privilege"
else
echo ""
read -p "The monitoring user is already present in Percona XtraDB Cluster. Would you like to proceed with the existing username and password [y/n] ? " check_param
case $check_param in
y|Y)
if [ -z "$QUICK_DEMO" ]; then
read -r -s -p "Please enter the password you have assigned to monitoring user '$MONITOR_USERNAME': " MONITOR_PASSWORD
proxysql_exec "update global_variables set variable_value='$MONITOR_USERNAME' where variable_name='mysql-monitor_username'; update global_variables set variable_value='$MONITOR_PASSWORD' where variable_name='mysql-monitor_password'; "
check_cmd $? "Failed to set the mysql-monitor variables in ProxySQL. Please check username, password and other options for connecting to ProxySQL database"
proxysql_exec "LOAD MYSQL VARIABLES TO RUNTIME;SAVE MYSQL VARIABLES TO DISK;"
fi
;;
n|N)
proxysql_exec "update global_variables set variable_value='$MONITOR_USERNAME' where variable_name='mysql-monitor_username'; update global_variables set variable_value='$MONITOR_PASSWORD' where variable_name='mysql-monitor_password'; "
check_cmd $? "Failed to set the mysql-monitor variables in ProxySQL. Please check username, password and other options for connecting to ProxySQL database"
proxysql_exec "LOAD MYSQL VARIABLES TO RUNTIME;SAVE MYSQL VARIABLES TO DISK;"
echo -e "\nUser '${BD}$MONITOR_USERNAME'@'$USER_HOST_RANGE${NBD}' has been updated in ProxySQL database. Please make sure the credentials are the same in Percona XtraDB Cluster"
;;
*)
echo "Please type [y/n]! Terminating."
exit 1
;;
esac
fi
if [ "$WITHOUT_CLUSTER_APP_USER" != 1 ]; then
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
fi
# 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"
if [ $MODE == "loadbal" ]; then
proxysql_exec "DELETE FROM mysql_servers WHERE hostgroup_id=$WRITE_HOSTGROUP_ID"
for i in "${wsrep_address[@]}"; 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',$WRITE_HOSTGROUP_ID,$ws_port,1000,'READWRITE');"
check_cmd $? "Failed to add the Percona XtraDB Cluster server node $ws_ip:$ws_port. Please check username, password and other options for connecting to ProxySQL database"
done
proxysql_exec "LOAD MYSQL SERVERS TO RUNTIME; SAVE MYSQL SERVERS TO DISK;"
elif [ $MODE == "singlewrite" ]; then
proxysql_exec "DELETE FROM mysql_servers WHERE hostgroup_id in ($WRITE_HOSTGROUP_ID,$READ_HOSTGROUP_ID)"
proxysql_exec "DELETE FROM mysql_query_rules WHERE destination_hostgroup in ($WRITE_HOSTGROUP_ID,$READ_HOSTGROUP_ID)"
if [ -z "$QUICK_DEMO" ]; then
if [ -z "$WRITE_NODE" ]; then
writer_ws_ip=$(mysql_exec "show variables like 'wsrep_provider_options'" | grep -o -P '(?<=base_host =).*(?=; base_port)' | xargs)
writer_ws_port=$CLUSTER_PORT
else
writer_ws_ip=$(echo "$WRITE_NODE" | awk -F':' '{print $1}')
writer_ws_port=$(echo "$WRITE_NODE" | awk -F':' '{print $2}')
if [ -z "$writer_ws_port" ];then
writer_ws_port=3306
fi
printf "[client]\nuser=${CLUSTER_USERNAME}\npassword=${CLUSTER_PASSWORD}\nhost=${writer_ws_ip}\nport=${writer_ws_port}\n" | mysql --defaults-file=/dev/stdin --protocol=tcp -Bse "select @@port" >/dev/null 2>/dev/null
if [ $? -ne 0 ]; then
echo -e "\nERROR: Failed to establish connection to write node $writer_ws_ip:$writer_ws_port. Please check write node is alive and username, password and other options for connecting to server.... Terminating!\n";
proxysql_exec "DELETE FROM mysql_users WHERE default_hostgroup in ($WRITE_HOSTGROUP_ID,$READ_HOSTGROUP_ID);"
check_cmd $? "Failed to delete Percona XtraDB Cluster user from ProxySQL. Please check username, password and other options for connecting to ProxySQL database"
exit 1
fi
fi
else
writer_ws_ip=$(mysql_exec "show variables like 'wsrep_provider_options'" | grep -o -P '(?<=base_host =).*(?=; base_port)' | xargs)
writer_ws_port=$CLUSTER_PORT
fi
proxysql_exec "DELETE FROM mysql_servers WHERE hostgroup_id=$WRITE_HOSTGROUP_ID"
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)
if [ "$ws_ip" == "$writer_ws_ip" ] && [ "$ws_port" == "$writer_ws_port" ]; then
proxysql_exec "INSERT INTO mysql_servers (hostname,hostgroup_id,port,weight,comment) VALUES ('$writer_ws_ip',$WRITE_HOSTGROUP_ID,$writer_ws_port,1000000,'WRITE');"
check_cmd $? "Failed to add the Percona XtraDB Cluster server node $writer_ws_ip:$writer_ws_port. Please check username, password and other options for connecting to ProxySQL database"
echo -e "\nWrite node info"
proxysql_exec "SELECT hostname,hostgroup_id,port,weight,comment FROM mysql_servers WHERE hostgroup_id=$WRITE_HOSTGROUP_ID" "t"
else
proxysql_exec "INSERT INTO mysql_servers (hostname,hostgroup_id,port,weight,comment) VALUES ('$ws_ip',$READ_HOSTGROUP_ID,$ws_port,1000,'READ');"
check_cmd $? "Failed to add the Percona XtraDB Cluster server node $ws_ip:$ws_port. Please check username, password and other options for connecting to ProxySQL database"
fi
done
if [ "$WITHOUT_CLUSTER_APP_USER" != 1 ]; then
proxysql_exec "INSERT INTO mysql_query_rules (username,destination_hostgroup,active,match_digest,apply) values('$CLUSTER_APP_USERNAME',$WRITE_HOSTGROUP_ID,1,'^SELECT.*FOR UPDATE',1),('$CLUSTER_APP_USERNAME',$READ_HOSTGROUP_ID,1,'^SELECT ',1);"
check_cmd $? "Failed to add the read query rule. Please check username, password and other options for connecting to ProxySQL database"
fi
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 COMMENT='$CLUSTER_NAME';"
check_cmd $? "Failed to delete the Percona XtraDB Cluster nodes from ProxySQL. Please check username, password and other options for connecting to ProxySQL database"
if [ $MODE == "singlewrite" ]; then
NUMBER_WRITERS=1
else
NUMBER_WRITERS=0
fi
proxysql_exec "INSERT INTO SCHEDULER (active,interval_ms,filename,arg1,arg2,arg3,arg4,arg5,comment) VALUES (1,$NODE_CHECK_INTERVAL,'$PROXYSQL_GALERA_CHECK',$WRITE_HOSTGROUP_ID,$READ_HOSTGROUP_ID,$NUMBER_WRITERS,1,'$PROXYSQL_DATADIR/${CLUSTER_NAME}_proxysql_galera_check.log','$CLUSTER_NAME');"
check_cmd $? "Failed to add the Percona XtraDB Cluster monitoring scheduler in ProxySQL. Please check username, password and other options for connecting to ProxySQL database"
proxysql_exec "LOAD SCHEDULER TO RUNTIME;SAVE SCHEDULER TO DISK;"
}
# Removing Percona XtraDB Cluster configuration from proxysql
disable_proxysql(){
proxysql_connection_check
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"
echo "Removing scheduler script from ProxySQL database."
proxysql_exec "DELETE FROM SCHEDULER WHERE COMMENT='$CLUSTER_NAME';"
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(){
proxysql_connection_check
cluster_connection_check
echo -e "\nAdding Percona XtraDB Cluster application user to the ProxySQL database"
echo -n "Enter the Percona XtraDB Cluster application user name: "
read -r CLUSTER_APP_WRITE_USERNAME
while [[ -z "$CLUSTER_APP_WRITE_USERNAME" ]]
do
echo -n "No input entered. Enter the Percona XtraDB Cluster application user name: "
read -r CLUSTER_APP_WRITE_USERNAME
done
read -r -s -p "Enter the Percona XtraDB Cluster application user password: " CLUSTER_APP_WRITE_PASSWORD
while [[ -z "$CLUSTER_APP_WRITE_PASSWORD" ]]
do
read -r -s -p "No input entered. Enter the Percona XtraDB Cluster application user password: " CLUSTER_APP_WRITE_PASSWORD
done
check_user=$(proxysql_exec "SELECT username FROM mysql_users where username='$CLUSTER_APP_WRITE_USERNAME'")
if [[ -z "$check_user" ]]; then
check_cluster_user=$(mysql_exec "SELECT user,host FROM mysql.user where user='$CLUSTER_APP_WRITE_USERNAME'")
if [[ -z "$check_cluster_user" ]]; then
echo -e "\n\n"
read -r -p "The application user '$CLUSTER_APP_WRITE_USERNAME' does not exist in Percona XtraDB Cluster. Would you like to proceed [y/n] ? " check_param
case $check_param in
y|Y)
proxysql_exec "INSERT INTO mysql_users (username,password,active,default_hostgroup) values ('$CLUSTER_APP_WRITE_USERNAME','$CLUSTER_APP_WRITE_PASSWORD',1,$WRITE_HOSTGROUP_ID);LOAD MYSQL USERS TO RUNTIME;SAVE MYSQL USERS FROM RUNTIME;SAVE MYSQL USERS TO DISK;"
check_cmd $? "Failed to add the Percona XtraDB Cluster application user: '$CLUSTER_APP_WRITE_USERNAME' to ProxySQL database. Please check username, password and other options for connecting to ProxySQL database"
echo -e "\nPlease create the user ${BD}$CLUSTER_APP_WRITE_USERNAME${NBD} in Percona XtraDB Cluster to access the application through ProxySQL"
;;
n|N)
exit 1
;;
*)
echo "Please type [y/n]! Terminating."
exit 1
;;
esac
else
proxysql_exec "INSERT INTO mysql_users (username,password,active,default_hostgroup) values ('$CLUSTER_APP_WRITE_USERNAME','$CLUSTER_APP_WRITE_PASSWORD',1,$WRITE_HOSTGROUP_ID);LOAD MYSQL USERS TO RUNTIME;SAVE MYSQL USERS FROM RUNTIME;SAVE MYSQL USERS TO DISK;"
check_cmd $? "Failed to add the Percona XtraDB Cluster application user: '$CLUSTER_APP_WRITE_USERNAME' to ProxySQL database. Please check username, password and other options for connecting to ProxySQL database"
fi
else
echo -e "\nERROR: The application user '$CLUSTER_APP_WRITE_USERNAME' already exist in ProxySQL database. Terminating."
exit 1
fi
}
syncusers() {
# This function was created to auto sync all the existing users already in MySQL to proxySQL's
# mysql_users table. As there is not much point in having users in ProxySQL that don't exist in
# MySQL this function with delete any users from ProxySQL that were not found in MySQL. Going
# forward you can add/remove application users in MySQL then rerun proxysql-admin with the
# --syncusers switch to replicate the changes to ProxySQL.
# LIMITATIONS: Will not work properly in cases where the same user name exists in MySQL with
# several hosts and different passwords. This will cause ProxySQL to throw a
# "UNIQUE constraint failed" error message.
proxysql_connection_check
cluster_connection_check
# Get current MySQL users, filter out header row and mysql.sys user
MYSQLVER=$(mysql_exec "SELECT VERSION();" | tail -1 | cut -d'.' -f1,2 )
case $MYSQLVER in
5.6)
password_field="Password";;
5.7)
password_field="authentication_string";;
10.2)
password_field="Password";;
esac
mysql_users=$(mysql_exec "SELECT User,${password_field} FROM mysql.user where ${password_field}!=''" | sed 's/\t/,/g' | egrep -v "User,${password_field}|mysql.sys" | sort | uniq )
check_cmd $? "Failed to load user list from Percona XtraDB Cluster. Please check username, password and other options for connecting to Percona XtraDB Cluster"
#Checking whether user is part of proxysql admin user list
proxysql_admin_user_check(){
userchk=$1
proxysql_admin_users=($(proxysql_exec "select variable_value from global_variables where variable_name like 'admin-%_credentials'" | cut -d':' -f1 | grep -v variable_value))
if [[ " ${proxysql_admin_users[@]} " =~ " $userchk " ]];then
is_proxysql_admin_user=1
else
is_proxysql_admin_user=0
fi
}
# Get current ProxySQL users and filter out header row
get_proxysql_users() {
local proxysql_users=$(proxysql_exec "SELECT username,password FROM mysql_users where password!=''" | sed 's/\t/,/g' | egrep -v "username,password" | sort | uniq )
check_cmd $? "Failed to load user list from ProxySQL database. Please check username, password and other options for connecting to ProxySQL database"
echo "$proxysql_users"
}
proxysql_users=$(get_proxysql_users)
echo -e "\nSyncing user accounts from Percona XtraDB Cluster to ProxySQL"
# TEST FOR USERS THAT EXIST IN MYSQL BUT NOT IN PROXYSQL HERE AND ADD
for mysql_user in $mysql_users;do
match=0
for proxysql_user in $proxysql_users;do
if [ "$proxysql_user" == "$mysql_user" ];then
match=1
fi
done
if [ "$match" == 0 ];then
user=`echo $mysql_user | cut -d, -f1`
password=`echo $mysql_user | cut -d, -f2`
# Check if same username exists with a different password, delete the user to recreate.
for proxysql_user in $proxysql_users;do
echo $proxysql_user | grep "^${user}," > /dev/null
if [ "$?" == 0 ];then
# Remove the user
echo "Deleting existing user: $user"
proxysql_exec "DELETE FROM mysql_users WHERE username='${user}'"
check_cmd $? "Failed to delete the user ($user) from ProxySQL database. Please check username, password and other options for connecting to ProxySQL database"
fi
done
proxysql_admin_user_check $user
if [[ "$is_proxysql_admin_user" == "1" ]];then
echo -e "\nNote : '$user' is in proxysql admin user list, cannot not add this user to proxysql database( For more info https://github.com/sysown/proxysql/issues/709)"
else
proxysql_exec "INSERT INTO mysql_users (username, password, active, default_hostgroup) VALUES ('${user}', '${password}', 1, 10)"
check_cmd $? "Failed to add the user ($user) from Percona XtraDB Cluster to ProxySQL database. Please check username, password and other options for connecting to ProxySQL database"
fi
fi
done
# TEST FOR USERS THAT EXIST IN PROXYSQL BUT NOT IN MYSQL HERE AND REMOVE
# Again get all users
proxysql_users=$(get_proxysql_users)
for proxysql_user in $proxysql_users;do
match=0
for mysql_user in $mysql_users;do
if [ "$proxysql_user" == "$mysql_user" ];then
match=1
fi
done
if [ "$match" == 0 ];then
# Delete the ProxySQL user
user=`echo $proxysql_user | cut -d, -f1`
echo -e "\nRemoving $proxysql_user from ProxySQL"
proxysql_exec "DELETE FROM mysql_users WHERE username='${user}'"
check_cmd $? "Failed to delete the user ($user) from ProxySQL database. Please check username, password and other options for connecting to ProxySQL database"
fi
done
proxysql_exec "SAVE MYSQL USERS TO DISK;LOAD MYSQL USERS TO RUNTIME;"
}
if [ "$ENABLE" == 1 ] || [ "$DISABLE" == 1 ] || [ "$ADDUSER" == 1 ] || [ "$SYNCUSERS" == 1 ]; then
if [ "$ENABLE" == 1 ];then
if [ -z "$QUICK_DEMO" ]; then
echo -e "\nThis script will assist with configuring ProxySQL (currently only Percona XtraDB cluster in combination with ProxySQL is supported)"
fi
echo -e "\nProxySQL read/write configuration mode is ${BD}$MODE${NBD}"
enable_proxysql
echo -e "\nProxySQL configuration completed!\n"
PROXYSQL_CLIENT_PORT=$(proxysql_exec "SELECT * FROM runtime_global_variables WHERE variable_name='mysql-interfaces'" | awk '{print $2}' | grep -o -P '(?<=:).*' | cut -d';' -f1 )
echo -e "ProxySQL has been successfully configured to use with Percona XtraDB Cluster\n"
echo -e "You can use the following login credentials to connect your application through ProxySQL\n"
if [ -z "$QUICK_DEMO" ]; then
echo -e "${BD}mysql --user=$CLUSTER_APP_USERNAME -p --host=$PROXYSQL_HOSTNAME --port=$PROXYSQL_CLIENT_PORT --protocol=tcp ${NBD}\n"
else
echo -e "${BD}mysql --user=$CLUSTER_APP_USERNAME --host=$PROXYSQL_HOSTNAME --port=$PROXYSQL_CLIENT_PORT --protocol=tcp ${NBD}\n"
fi
fi
if [ "$DISABLE" == 1 ];then
disable_proxysql
echo "ProxySQL configuration removed!"
fi
if [ "$ADDUSER" == 1 ];then
adduser
echo -e "\nAdded Percona XtraDB Cluster application user to the ProxySQL database!"
fi
if [ "$SYNCUSERS" == 1 ];then
# Check for existing proxysql process
syncusers
echo -e "\nSynced Percona XtraDB Cluster users to the ProxySQL database!"
fi
else
echo "Usage: proxysql-admin <user credentials> {enable|disable}"
usage
fi