Logoj0ke.net Open Build Service > Projects > internetx:mysql5 > proxysql > proxysql_galera_checker
Sign Up | Log In

File proxysql_galera_checker of Package proxysql

 
1
#!/bin/bash
2
## inspired by Percona clustercheck.sh
3
4
ERR_FILE="${5:-/dev/null}"
5
6
if [ -f /etc/proxysql-admin.cnf ]; then
7
  source /etc/proxysql-admin.cnf
8
else
9
  echo "Assert! proxysql-admin configuration file :/etc/proxysql-admin.cnf does not exists, Terminating!" >> $ERR_FILE
10
  exit 1
11
fi
12
#
13
14
if [[ -z "$PROXYSQL_DATADIR" ]]; then
15
  PROXYSQL_DATADIR='/var/lib/proxysql'
16
fi
17
18
function usage()
19
{
20
  cat << EOF
21
22
Usage: $0 <hostgroup_id write> [hostgroup_id read] [number writers] [writers are readers 0|1] [log_file]
23
24
- HOSTGROUP WRITERS   (required)  (0..)   The hostgroup_id that contains nodes that will server 'writes'
25
- HOSTGROUP READERS   (optional)  (0..)   The hostgroup_id that contains nodes that will server 'reads'
26
- NUMBER WRITERS      (optional)  (0..)   Maximum number of write hostgroup_id node that can be marked ONLINE
27
                                          When 0 (default), all nodes can be marked ONLINE
28
- WRITERS ARE READERS (optional)  (0|1)   When 1 (default), ONLINE nodes in write hostgroup_id will prefer not
29
                                          to be ONLINE in read hostgroup_id
30
- LOG_FILE            (optional)  file    logfile where node state checks & changes are written to (verbose)
31
32
33
Notes about the mysql_servers in ProxySQL:
34
35
- WEIGHT           Hosts with a higher weight will be prefered to be put ONLINE
36
- NODE STATUS      * Nodes that are in status OFFLINE_HARD will not be checked nor will their status be changed
37
                   * SHUNNED nodes are not to be used with Galera based systems, they will be checked and status
38
                     will be changed to either ONLINE or OFFLINE_SOFT.
39
40
41
When no nodes were found to be in wsrep_local_state=4 (SYNCED) for either
42
read or write nodes, then the script will try 5 times for each node to try
43
to find nodes wsrep_local_state=4 (SYNCED) or wsrep_local_state=2 (DONOR/DESYNC)
44
45
This is to avoid $0 to mark all nodes as OFFLINE_SOFT
46
47
EOF
48
}
49
50
51
# DEFAULTS
52
HOSTGROUP_WRITER_ID="${1}"
53
HOSTGROUP_READER_ID="${2:--1}"
54
NUMBER_WRITERS="${3:-0}"
55
WRITER_IS_READER="${4:-1}"
56
57
proxysql_exec() {
58
  local query="$1"
59
  printf "%s\n" \
60
      "[client]" \
61
      "user=${PROXYSQL_USERNAME}" \
62
      "password=${PROXYSQL_PASSWORD}" \
63
      "host=${PROXYSQL_HOSTNAME}" \
64
      "port=${PROXYSQL_PORT}"  \
65
      | mysql --defaults-file=/dev/stdin --protocol=tcp -Nse "${query}"
66
}
67
68
CLUSTER_NAME=$(proxysql_exec "select comment from scheduler where arg1=$HOSTGROUP_WRITER_ID")
69
RELOAD_CHECK_FILE="${PROXYSQL_DATADIR}/${CLUSTER_NAME}_reload"
70
71
echo "0" > ${RELOAD_CHECK_FILE}
72
#Timeout exists for instances where mysqld may be hung
73
TIMEOUT=10
74
75
mysql_exec() {
76
  local query="$1"
77
  printf "%s\n" \
78
      "[client]" \
79
      "user=${MYSQL_USERNAME}" \
80
      "password=${MYSQL_PASSWORD}" \
81
      "host=${server}" \
82
      "port=${port}"  \
83
      | timeout $TIMEOUT mysql --defaults-file=/dev/stdin --protocol=tcp -nNE -e "${query}"
84
}
85
86
#Running proxysql_node_monitor script.
87
if [ ! -f /usr/bin/proxysql_node_monitor ] ;then
88
  echo "`date` ERROR! Could not run /usr/bin/proxysql_node_monitor. Monitoring script does not exists in default location. Terminating" >> ${ERR_FILE}
89
  exit 1
90
else
91
  /usr/bin/proxysql_node_monitor $HOSTGROUP_WRITER_ID $HOSTGROUP_READER_ID ${PROXYSQL_DATADIR}/${CLUSTER_NAME}_proxysql_node_monitor.log
92
fi
93
94
if [ "$1" = '-h' -o "$1" = '--help'  -o -z "$1" ]
95
then
96
  usage
97
  exit 0
98
fi
99
100
test $HOSTGROUP_WRITER_ID -ge 0 &> /dev/null
101
if [ $? -ne 0 ]; then
102
  echo "ERROR: writer hostgroup_id is not an integer"
103
  usage
104
  exit 1
105
fi
106
107
test $HOSTGROUP_READER_ID -ge -1 &> /dev/null
108
if [ $? -ne 0 ]; then
109
  echo "ERROR: reader hostgroup_id is not an integer"
110
  usage
111
  exit 1
112
fi
113
114
if [ $# -lt 1 -o $# -gt 5 ]; then
115
  echo "ERROR: Invalid number of arguments"
116
  usage
117
  exit 1
118
fi
119
120
if [ $NUMBER_WRITERS -lt 0 ]; then
121
  echo "ERROR: The number of writers should either be 0 to enable all possible nodes ONLINE"
122
  echo "       or be larger than 0 to limit the number of writers"
123
  usage
124
  exit 1
125
fi
126
127
if [ $WRITER_IS_READER -ne 0 -a $WRITER_IS_READER -ne 1 ]; then
128
  echo "ERROR: Writers are readers requires a boolean argument (0|1)"
129
  usage
130
  exit 1
131
fi
132
133
134
# print information prior to a run if ${ERR_FILE} is defined
135
echo "`date` ###### proxysql_galera_checker.sh SUMMARY ######" >> ${ERR_FILE}
136
echo "`date` Hostgroup writers $HOSTGROUP_WRITER_ID" >> ${ERR_FILE}
137
echo "`date` Hostgroup readers $HOSTGROUP_READER_ID" >> ${ERR_FILE}
138
echo "`date` Number of writers $NUMBER_WRITERS" >> ${ERR_FILE}
139
echo "`date` Writers are readers $WRITER_IS_READER" >> ${ERR_FILE}
140
echo "`date` log file $ERR_FILE" >> ${ERR_FILE}
141
142
#Timeout exists for instances where mysqld may be hung
143
TIMEOUT=10
144
145
#proxysql_exec="env MYSQL_PWD=$PROXYSQL_PASSWORD mysql -u$PROXYSQL_USERNAME -h $PROXYSQL_HOSTNAME -P $PROXYSQL_PORT --protocol=tcp -Nse"
146
MYSQL_CREDENTIALS=$(proxysql_exec "SELECT variable_value FROM global_variables WHERE variable_name IN ('mysql-monitor_username','mysql-monitor_password') ORDER BY variable_name DESC")
147
MYSQL_USERNAME=$(echo $MYSQL_CREDENTIALS | awk '{print $1}')
148
MYSQL_PASSWORD=$(echo $MYSQL_CREDENTIALS | awk '{print $2}')
149
#mysql_exec="env MYSQL_PWD=$MYSQL_PASSWORD timeout $TIMEOUT mysql -nNE -u$MYSQL_USERNAME"
150
151
152
function change_server_status() {
153
  echo "`date` Changing server $1:$2:$3 to status $4. Reason: $5" >> ${ERR_FILE}
154
  proxysql_exec "UPDATE mysql_servers set status = '$4' WHERE hostgroup_id = $1 AND hostname = '$2' AND port = $3;" 2>> ${ERR_FILE}
155
}
156
157
158
echo "`date` ###### HANDLE WRITER NODES ######" >> ${ERR_FILE}
159
NUMBER_WRITERS_ONLINE=0
160
proxysql_exec "SELECT hostgroup_id, hostname, port, status FROM mysql_servers WHERE hostgroup_id IN ($HOSTGROUP_WRITER_ID) AND status <> 'OFFLINE_HARD' AND comment <> 'SLAVEREAD' ORDER BY hostgroup_id, weight DESC, hostname, port" | while read hostgroup server port stat
161
do
162
  WSREP_STATUS=$(mysql_exec "SHOW STATUS LIKE 'wsrep_local_state'" 2>>${ERR_FILE}| tail -1 2>>${ERR_FILE})
163
  PXC_MAIN_MODE=$(mysql_exec "SHOW VARIABLES LIKE 'pxc_maint_mode'" 2>>${ERR_FILE} | tail -1 2>>${ERR_FILE})
164
165
  echo "`date` --> Checking WRITE server $hostgroup:$server:$port, current status $stat, wsrep_local_state $WSREP_STATUS" >> ${ERR_FILE}
166
167
  # we have to limit amount of writers, WSREP status OK, AND node is not marked ONLINE
168
  if [ -z "$PXC_MAIN_MODE" ]; then
169
    if [ $NUMBER_WRITERS -gt 0 -a "${WSREP_STATUS}" = "4" -a "$stat" == "ONLINE" ] ; then
170
        if [ $NUMBER_WRITERS_ONLINE -lt $NUMBER_WRITERS ]; then
171
          NUMBER_WRITERS_ONLINE=$(( $NUMBER_WRITERS_ONLINE + 1 ))
172
          echo "`date` server $hostgroup:$server:$port is already ONLINE: ${NUMBER_WRITERS_ONLINE} of ${NUMBER_WRITERS} write nodes" >> ${ERR_FILE}
173
        else
174
          NUMBER_WRITERS_ONLINE=$(( $NUMBER_WRITERS_ONLINE + 1 ))
175
          change_server_status $HOSTGROUP_WRITER_ID "$server" $port "OFFLINE_SOFT" "max write nodes reached (${NUMBER_WRITERS})"
176
          echo "1" > ${RELOAD_CHECK_FILE}
177
        fi
178
    fi
179
  else
180
    if [ $NUMBER_WRITERS -gt 0 -a "${WSREP_STATUS}" = "4" -a "$stat" == "ONLINE" ] ; then
181
        if [ $NUMBER_WRITERS_ONLINE -lt $NUMBER_WRITERS ]; then
182
          NUMBER_WRITERS_ONLINE=$(( $NUMBER_WRITERS_ONLINE + 1 ))
183
          echo "`date` server $hostgroup:$server:$port is already ONLINE: ${NUMBER_WRITERS_ONLINE} of ${NUMBER_WRITERS} write nodes" >> ${ERR_FILE}
184
        else
185
          NUMBER_WRITERS_ONLINE=$(( $NUMBER_WRITERS_ONLINE + 1 ))
186
          change_server_status $HOSTGROUP_WRITER_ID "$server" $port "OFFLINE_SOFT" "max write nodes reached (${NUMBER_WRITERS})"
187
          echo "1" > ${RELOAD_CHECK_FILE}
188
        fi
189
    elif [ $NUMBER_WRITERS -gt 0 -a "${WSREP_STATUS}" = "4" -a "$stat" != "ONLINE"  -a "${PXC_MAIN_MODE}" != "DISABLED" ] ; then
190
      NUMBER_WRITERS_ONLINE=$(( $NUMBER_WRITERS_ONLINE + 1 ))
191
      echo "`date` server $hostgroup:$server:$port is $stat : ${NUMBER_WRITERS_ONLINE} of ${NUMBER_WRITERS} write nodes" >> ${ERR_FILE}
192
    fi
193
  fi
194
195
  # WSREP status OK, but node is not marked ONLINE
196
  if [ -z "$PXC_MAIN_MODE" ]; then
197
    if [ "${WSREP_STATUS}" = "4" -a "$stat" != "ONLINE" ] ; then
198
      # we have to limit amount of writers
199
      if [ $NUMBER_WRITERS -gt 0 ] ; then
200
        if [ $NUMBER_WRITERS_ONLINE -lt $NUMBER_WRITERS ]; then
201
          NUMBER_WRITERS_ONLINE=$(( $NUMBER_WRITERS_ONLINE + 1 ))
202
          change_server_status $HOSTGROUP_WRITER_ID "$server" $port "ONLINE" "{NUMBER_WRITERS_ONLINE} of ${NUMBER_WRITERS} write nodes"
203
          echo "1" > ${RELOAD_CHECK_FILE}
204
        else
205
          NUMBER_WRITERS_ONLINE=$(( $NUMBER_WRITERS_ONLINE + 1 ))
206
          if [ "$stat" != "OFFLINE_SOFT" ]; then
207
            change_server_status $HOSTGROUP_WRITER_ID "$server" $port "OFFLINE_SOFT" "max write nodes reached (${NUMBER_WRITERS})"
208
            echo "1" > ${RELOAD_CHECK_FILE}
209
          else
210
             echo "`date` server $hostgroup:$server:$port is already OFFLINE_SOFT, max write nodes reached (${NUMBER_WRITERS})" >> ${ERR_FILE}
211
          fi
212
        fi
213
      # we do not have to limit
214
      elif [ $NUMBER_WRITERS -eq 0 ] ; then
215
        change_server_status $HOSTGROUP_WRITER_ID "$server" $port "ONLINE" "Changed state, marking write node ONLINE"
216
        echo "1" > ${RELOAD_CHECK_FILE}
217
      fi
218
    fi
219
  else
220
    if [ "${WSREP_STATUS}" = "4" -a "$stat" != "ONLINE" -a "${PXC_MAIN_MODE}" == "DISABLED" ] ; then
221
      # we have to limit amount of writers
222
      if [ $NUMBER_WRITERS -gt 0 ] ; then
223
        if [ $NUMBER_WRITERS_ONLINE -lt $NUMBER_WRITERS ]; then
224
          NUMBER_WRITERS_ONLINE=$(( $NUMBER_WRITERS_ONLINE + 1 ))
225
          change_server_status $HOSTGROUP_WRITER_ID "$server" $port "ONLINE" "{NUMBER_WRITERS_ONLINE} of ${NUMBER_WRITERS} write nodes"
226
          echo "1" > ${RELOAD_CHECK_FILE}
227
        else
228
          NUMBER_WRITERS_ONLINE=$(( $NUMBER_WRITERS_ONLINE + 1 ))
229
          if [ "$stat" != "OFFLINE_SOFT" ]; then
230
            change_server_status $HOSTGROUP_WRITER_ID "$server" $port "OFFLINE_SOFT" "max write nodes reached (${NUMBER_WRITERS})"
231
            echo "1" > ${RELOAD_CHECK_FILE}
232
          else
233
             echo "`date` server $hostgroup:$server:$port is already OFFLINE_SOFT, max write nodes reached (${NUMBER_WRITERS})" >> ${ERR_FILE}
234
          fi
235
        fi
236
      # we do not have to limit
237
      elif [ $NUMBER_WRITERS -eq 0 ] ; then
238
        change_server_status $HOSTGROUP_WRITER_ID "$server" $port "ONLINE" "Changed state, marking write node ONLINE"
239
        echo "1" > ${RELOAD_CHECK_FILE}
240
      fi
241
    fi
242
  fi
243
  # WSREP status is not ok, but the node is marked online, we should put it offline
244
  if [ -z "$PXC_MAIN_MODE" ]; then
245
    if [ "${WSREP_STATUS}" != "4" -a "$stat" = "ONLINE" ]; then
246
      change_server_status $HOSTGROUP_WRITER_ID "$server" $port "OFFLINE_SOFT" "WSREP status is ${WSREP_STATUS} which is not ok"
247
      echo "1" > ${RELOAD_CHECK_FILE}
248
    elif [ "${WSREP_STATUS}" != "4" -a "$stat" = "OFFLINE_SOFT" ]; then
249
      echo "`date` server $hostgroup:$server:$port is already OFFLINE_SOFT, WSREP status is ${WSREP_STATUS} which is not ok" >> ${ERR_FILE}
250
    fi
251
  else
252
    if [ "${WSREP_STATUS}" != "4" -a "$stat" = "ONLINE" ]; then
253
      change_server_status $HOSTGROUP_WRITER_ID "$server" $port "OFFLINE_SOFT" "WSREP status is ${WSREP_STATUS} which is not ok"
254
      echo "1" > ${RELOAD_CHECK_FILE}
255
    elif [ "${PXC_MAIN_MODE}" != "DISABLED" -a "$stat" = "ONLINE" ];then
256
      echo "`date` Changing server $hostgroup:$server:$port to status OFFLINE_SOFT due to $PXC_MAIN_MODE" >> ${ERR_FILE}
257
      change_server_status  $HOSTGROUP_WRITER_ID "$server" $port "OFFLINE_SOFT" "Changed  server $hostgroup:$server:$port to status OFFLINE_SOFT due to $PXC_MAIN_MODE" 2>> ${ERR_FILE}
258
      echo "1" > ${RELOAD_CHECK_FILE}
259
    elif [ "${WSREP_STATUS}" != "4" -a "$stat" = "OFFLINE_SOFT" ]; then
260
      echo "`date` server $hostgroup:$server:$port is already OFFLINE_SOFT, WSREP status is ${WSREP_STATUS} which is not ok" >> ${ERR_FILE}
261
    fi
262
263
  fi
264
done
265
266
# NUMBER_WRITERS_ONLINE is lost after loop
267
NUMBER_WRITERS_ONLINE=$(proxysql_exec "SELECT count(*) FROM mysql_servers WHERE hostgroup_id IN ($HOSTGROUP_WRITER_ID) AND status = 'ONLINE' AND comment <> 'SLAVEREAD'" 2>>${ERR_FILE}| tail -1 2>>${ERR_FILE})
268
269
270
NUMBER_READERS_ONLINE=0
271
if [ ${HOSTGROUP_READER_ID} -ne -1 ]; then
272
273
  echo "`date` ###### HANDLE READER NODES ######" >> ${ERR_FILE}
274
  if [ $WRITER_IS_READER -eq 1 ]; then
275
    READER_PROXYSQL_QUERY="SELECT hostgroup_id, hostname, port, status, 'NULL' FROM mysql_servers WHERE hostgroup_id IN ($HOSTGROUP_READER_ID) AND status <> 'OFFLINE_HARD' AND comment <> 'SLAVEREAD' ORDER BY weight DESC, hostname, port"
276
  elif [ $WRITER_IS_READER -eq 0 ]; then
277
    # We will not try to change reader state of nodes that are writer ONLINE, so what we do is we ORDER BY writer.status ASC because by accident ONLINE is last in the line
278
    READER_PROXYSQL_QUERY="SELECT reader.hostgroup_id,
279
         reader.hostname,
280
         reader.port,
281
         reader.status,
282
         writer.status
283
  FROM mysql_servers as reader
284
  LEFT JOIN mysql_servers as writer
285
    ON writer.hostgroup_id = $HOSTGROUP_WRITER_ID
286
    AND writer.hostname = reader.hostname
287
    AND writer.port = reader.port
288
  WHERE reader.hostgroup_id = $HOSTGROUP_READER_ID
289
    AND reader.status <> 'OFFLINE_HARD'
290
        AND reader.comment <> 'SLAVEREAD'
291
  ORDER BY writer.status ASC,
292
           reader.weight DESC,
293
           reader.hostname,
294
           reader.port"
295
  fi
296
297
  OFFLINE_READERS_FOUND=0
298
  proxysql_exec "$READER_PROXYSQL_QUERY" | while read hostgroup server port stat writer_stat
299
  do
300
    PXC_MAIN_MODE=$(mysql_exec "SHOW VARIABLES LIKE 'pxc_maint_mode'" 2>>${ERR_FILE} | tail -1 2>>${ERR_FILE})
301
    WSREP_STATUS=$(mysql_exec "SHOW STATUS LIKE 'wsrep_local_state'" 2>>${ERR_FILE}| tail -1 2>>${ERR_FILE})
302
303
    echo "`date` --> Checking READ server $hostgroup:$server:$port, current status $stat, wsrep_local_state $WSREP_STATUS" >> ${ERR_FILE}
304
305
    if [ $WRITER_IS_READER -eq 0 -a "$writer_stat" == "ONLINE" ] ; then
306
307
      if [ $OFFLINE_READERS_FOUND -eq 0 ] ; then
308
        if [ -z "$PXC_MAIN_MODE" ]; then
309
          if [ "${WSREP_STATUS}" = "4" -a "$stat" == "ONLINE" ] ; then
310
            echo "`date` server $hostgroup:$server:$port is already ONLINE, is also write node in ONLINE state, not enough non-ONLINE readers found" >> ${ERR_FILE}
311
          fi
312
          if [ "${WSREP_STATUS}" = "4" -a "$stat" != "ONLINE" ] ; then
313
            change_server_status $HOSTGROUP_READER_ID "$server" $port "ONLINE" "marking ONLINE write node as read ONLINE state, not enough non-ONLINE readers found"
314
            echo "1" > ${RELOAD_CHECK_FILE}
315
          fi
316
        else
317
          if [ "${WSREP_STATUS}" = "4" -a "$stat" == "ONLINE" -a "${PXC_MAIN_MODE}" == "DISABLED" ] ; then
318
            echo "`date` server $hostgroup:$server:$port is already ONLINE, is also write node in ONLINE state, not enough non-ONLINE readers found" >> ${ERR_FILE}
319
          fi
320
          if [ "${WSREP_STATUS}" = "4" -a "$stat" != "ONLINE"  -a "${PXC_MAIN_MODE}" == "DISABLED" ] ; then
321
            change_server_status $HOSTGROUP_READER_ID "$server" $port "ONLINE" "marking ONLINE write node as read ONLINE state, not enough non-ONLINE readers found"
322
            echo "1" > ${RELOAD_CHECK_FILE}
323
          elif [ "${PXC_MAIN_MODE}" != "DISABLED" -a "$stat" = "ONLINE" ];then
324
            echo "`date` Changing server $hostgroup:$server:$port to status OFFLINE_SOFT due to $PXC_MAIN_MODE" >> ${ERR_FILE}
325
            change_server_status  $hostgroup "$server" $port "OFFLINE_SOFT" "Changed  server $hostgroup:$server:$port to status OFFLINE_SOFT due to $PXC_MAIN_MODE" 2>> ${ERR_FILE}
326
            echo "1" > ${RELOAD_CHECK_FILE}
327
          fi
328
        fi
329
      else
330
        if [ -z "$PXC_MAIN_MODE" ]; then
331
          if [ "${WSREP_STATUS}" = "4" -a "$stat" == "ONLINE" ] ; then
332
            change_server_status $HOSTGROUP_READER_ID "$server" $port "OFFLINE_SOFT" "making ONLINE writer node as read OFFLINE_SOFT as well because writers should not be readers"
333
            echo "1" > ${RELOAD_CHECK_FILE}
334
          fi
335
          if [ "${WSREP_STATUS}" = "4" -a "$stat" != "ONLINE" ] ; then
336
            echo "`date` server $hostgroup:$server:$port is $stat, keeping node in $stat is a writer ONLINE and it's preferred not to have writers as readers" >> ${ERR_FILE}
337
          fi
338
        else
339
          if [ "${WSREP_STATUS}" = "4" -a "$stat" == "ONLINE" -a "${PXC_MAIN_MODE}" == "DISABLED" ] ; then
340
            change_server_status $HOSTGROUP_READER_ID "$server" $port "OFFLINE_SOFT" "making ONLINE writer node as read OFFLINE_SOFT as well because writers should not be readers"
341
            echo "1" > ${RELOAD_CHECK_FILE}
342
          fi
343
          if [ "${WSREP_STATUS}" = "4" -a "$stat" != "ONLINE" -a "${PXC_MAIN_MODE}" == "DISABLED" ] ; then
344
            echo "`date` server $hostgroup:$server:$port is $stat, keeping node in $stat is a writer ONLINE and it's preferred not to have writers as readers" >> ${ERR_FILE}
345
          elif [ "${PXC_MAIN_MODE}" != "DISABLED" -a "$stat" = "ONLINE" ];then
346
            echo "`date` Changing server $hostgroup:$server:$port to status OFFLINE_SOFT due to $PXC_MAIN_MODE" >> ${ERR_FILE}
347
            change_server_status  $hostgroup "$server" $port "OFFLINE_SOFT" "Changed  server $hostgroup:$server:$port to status OFFLINE_SOFT due to $PXC_MAIN_MODE" 2>> ${ERR_FILE}
348
            echo "1" > ${RELOAD_CHECK_FILE}
349
          fi
350
        fi
351
      fi
352
    else
353
      if [ -z "$PXC_MAIN_MODE" ]; then
354
        if [ "${WSREP_STATUS}" = "4" -a "$stat" == "ONLINE" ] ; then
355
          echo "`date` server $hostgroup:$server:$port is already ONLINE" >> ${ERR_FILE}
356
          OFFLINE_READERS_FOUND=$(( $OFFLINE_READERS_FOUND + 1 ))
357
        fi
358
359
        # WSREP status OK, but node is not marked ONLINE
360
        if [ "${WSREP_STATUS}" = "4" -a "$stat" != "ONLINE" ] ; then
361
          change_server_status $HOSTGROUP_READER_ID "$server" $port "ONLINE" "changed state, making read node ONLINE"
362
          echo "1" > ${RELOAD_CHECK_FILE}
363
          OFFLINE_READERS_FOUND=$(( $OFFLINE_READERS_FOUND + 1 ))
364
        fi
365
      else
366
        if [ "${WSREP_STATUS}" = "4" -a "$stat" == "ONLINE" -a "${PXC_MAIN_MODE}" == "DISABLED" ] ; then
367
          echo "`date` server $hostgroup:$server:$port is already ONLINE" >> ${ERR_FILE}
368
          OFFLINE_READERS_FOUND=$(( $OFFLINE_READERS_FOUND + 1 ))
369
        elif [ "${WSREP_STATUS}" = "4" -a "$stat" != "ONLINE" -a "${PXC_MAIN_MODE}" != "DISABLED" ] ; then
370
          echo "`date` server $hostgroup:$server:$port is $stat" >> ${ERR_FILE}
371
          OFFLINE_READERS_FOUND=$(( $OFFLINE_READERS_FOUND + 1 ))
372
        fi
373
374
        # WSREP status OK, but node is not marked ONLINE
375
        if [ "${WSREP_STATUS}" = "4" -a "$stat" != "ONLINE" -a "${PXC_MAIN_MODE}" == "DISABLED" ] ; then
376
          change_server_status $HOSTGROUP_READER_ID "$server" $port "ONLINE" "changed state, making read node ONLINE"
377
          echo "1" > ${RELOAD_CHECK_FILE}
378
          OFFLINE_READERS_FOUND=$(( $OFFLINE_READERS_FOUND + 1 ))
379
        elif [ "${PXC_MAIN_MODE}" != "DISABLED" -a "$stat" = "ONLINE" ];then
380
          echo "`date` Changing server $hostgroup:$server:$port to status OFFLINE_SOFT due to $PXC_MAIN_MODE" >> ${ERR_FILE}
381
          change_server_status  $hostgroup "$server" $port "OFFLINE_SOFT" "Changed  server $hostgroup:$server:$port to status OFFLINE_SOFT due to $PXC_MAIN_MODE" 2>> ${ERR_FILE}
382
          echo "1" > ${RELOAD_CHECK_FILE}
383
        fi
384
      fi
385
    fi
386
    # WSREP status is not ok, but the node is marked online, we should put it offline
387
    if [ -z "$PXC_MAIN_MODE" ]; then
388
      if [ "${WSREP_STATUS}" != "4" -a "$stat" = "ONLINE" ]; then
389
        change_server_status $HOSTGROUP_READER_ID "$server" $port "OFFLINE_SOFT" "WSREP status is ${WSREP_STATUS} which is not ok"
390
        echo "1" > ${RELOAD_CHECK_FILE}
391
      elif [ "${WSREP_STATUS}" != "4" -a "$stat" = "OFFLINE_SOFT" ]; then
392
        echo "`date` server $hostgroup:$server:$port is already OFFLINE_SOFT, WSREP status is ${WSREP_STATUS} which is not ok" >> ${ERR_FILE}
393
      fi
394
    else
395
      if [ "${WSREP_STATUS}" != "4" -a "$stat" = "ONLINE" ]; then
396
        change_server_status $HOSTGROUP_READER_ID "$server" $port "OFFLINE_SOFT" "WSREP status is ${WSREP_STATUS} which is not ok"
397
        echo "1" > ${RELOAD_CHECK_FILE}
398
      elif [ "${PXC_MAIN_MODE}" != "DISABLED" -a "$stat" = "ONLINE" ];then
399
        echo "`date` Changing server $hostgroup:$server:$port to status OFFLINE_SOFT due to $PXC_MAIN_MODE" >> ${ERR_FILE}
400
        change_server_status  $HOSTGROUP_WRITER_ID "$server" $port "OFFLINE_SOFT" "Changed  server $hostgroup:$server:$port to status OFFLINE_SOFT due to $PXC_MAIN_MODE" 2>> ${ERR_FILE}
401
        echo "1" > ${RELOAD_CHECK_FILE}
402
      elif [ "${WSREP_STATUS}" != "4" -a "$stat" = "OFFLINE_SOFT" ]; then
403
        echo "`date` server $hostgroup:$server:$port is already OFFLINE_SOFT, WSREP status is ${WSREP_STATUS} which is not ok" >> ${ERR_FILE}
404
      fi
405
    fi
406
  done
407
408
  NUMBER_READERS_ONLINE=$(proxysql_exec "SELECT count(*) FROM mysql_servers WHERE hostgroup_id IN ($HOSTGROUP_READER_ID) AND status = 'ONLINE' AND comment <> 'SLAVEREAD'" 2>>${ERR_FILE}| tail -1 2>>${ERR_FILE})
409
fi
410
411
echo "`date` ###### SUMMARY ######" >> ${ERR_FILE}
412
echo "`date` --> Number of writers that are 'ONLINE': ${NUMBER_WRITERS_ONLINE} : hostgroup: ${HOSTGROUP_WRITER_ID}" >> ${ERR_FILE}
413
[ ${HOSTGROUP_READER_ID} -ne -1 ] && echo "`date` --> Number of readers that are 'ONLINE': ${NUMBER_READERS_ONLINE} : hostgroup: ${HOSTGROUP_READER_ID}" >> ${ERR_FILE}
414
415
416
cnt=0
417
# We don't have any writers... alert, try to bring some online!
418
# This includes bringing a DONOR online
419
if [ ${NUMBER_WRITERS_ONLINE} -eq 0 ]; then
420
  echo "`date` ###### TRYING TO FIX MISSING WRITERS ######"
421
  echo "`date` No writers found, Trying to enable last available node of the cluster (in Donor/Desync state)" >> ${ERR_FILE}
422
  proxysql_exec "SELECT hostgroup_id, hostname, port, status FROM mysql_servers WHERE hostgroup_id IN ($HOSTGROUP_WRITER_ID) AND status <> 'OFFLINE_HARD' AND comment <> 'SLAVEREAD'" | while read hostgroup server port stat
423
  do
424
    safety_cnt=0
425
      while [ ${cnt} -le $NUMBER_WRITERS -a ${safety_cnt} -lt 5 ]
426
      do
427
        WSREP_STATUS=$(mysql_exec "SHOW STATUS LIKE 'wsrep_local_state'" 2>>${ERR_FILE} | tail -1 2>>${ERR_FILE})
428
        echo "`date` Check server $hostgroup:$server:$port for only available node in DONOR state, status $stat , wsrep_local_state $WSREP_STATUS" >> ${ERR_FILE}
429
        if [ "${WSREP_STATUS}" = "2" -a "$stat" != "ONLINE" ] # if we are on Donor/Desync an not online in mysql_servers -> proceed
430
        then
431
          PROXY_RUNTIME_STATUS=$(proxysql_exec "SELECT status FROM runtime_mysql_servers WHERE hostname='${server}' AND port='${port}' AND hostgroup_id='${hostgroup}'")
432
          if [ "${PROXY_RUNTIME_STATUS}" != "ONLINE" ] # if we are not online in runtime_mysql_servers, proceed to change the server status and reload mysql_servers
433
          then
434
            change_server_status $HOSTGROUP_WRITER_ID "$server" $port "ONLINE" "WSREP status is DESYNC/DONOR, as this is the only node we will put this one online"
435
            echo "1" > ${RELOAD_CHECK_FILE}
436
            cnt=$(( $cnt + 1 ))
437
          else # otherwise (we are already ONLINE in runtime_mysql_servers) no need to reload so let's just remove RELOAD_CHECK_FILE and update it to ONLINE in mysql_servers (in case something would reload it)
438
            rm ${RELOAD_CHECK_FILE}
439
            cnt=$(( $cnt + 1 ))
440
            change_server_status $HOSTGROUP_WRITER_ID "$server" $port "ONLINE" "WSREP status is DESYNC/DONOR, as this is the only node we will put this one online"
441
          fi
442
        fi
443
        safety_cnt=$(( $safety_cnt + 1 ))
444
    done
445
  done
446
fi
447
448
449
cnt=0
450
# We don't have any readers... alert, try to bring some online!
451
if [  ${HOSTGROUP_READER_ID} -ne -1 -a ${NUMBER_READERS_ONLINE} -eq 0 ]; then
452
  echo "`date` ###### TRYING TO FIX MISSING READERS ######"
453
  echo "`date` --> No readers found, Trying to enable last available node of the cluster (in Donor/Desync state) or pick the master" >> ${ERR_FILE}
454
  proxysql_exec "SELECT hostgroup_id, hostname, port, status FROM mysql_servers WHERE hostgroup_id IN ($HOSTGROUP_READER_ID) AND status <> 'OFFLINE_HARD' AND comment <> 'SLAVEREAD'" | while read hostgroup server port stat
455
  do
456
    safety_cnt=0
457
      while [ ${cnt} -eq 0 -a ${safety_cnt} -lt 5 ]
458
      do
459
        WSREP_STATUS=$(mysql_exec "SHOW STATUS LIKE 'wsrep_local_state'" 2>>${ERR_FILE} | tail -1 2>>${ERR_FILE})
460
        echo "`date` Check server $hostgroup:$server:$port for only available node in DONOR state, status $stat , wsrep_local_state $WSREP_STATUS" >> ${ERR_FILE}
461
        if [ "${WSREP_STATUS}" = "2" -a "$stat" != "ONLINE" ];then # if we are on Donor/Desync an not online in mysql_servers -> proceed
462
          PROXY_RUNTIME_STATUS=$(proxysql_exec "SELECT status FROM runtime_mysql_servers WHERE hostname='${server}' AND port='${port}' AND hostgroup_id='${hostgroup}'")
463
          if [ "${PROXY_RUNTIME_STATUS}" != "ONLINE" ] # if we are not online in runtime_mysql_servers, proceed to change the server status and reload mysql_servers
464
          then
465
            change_server_status $HOSTGROUP_READER_ID "$server" $port "ONLINE" "WSREP status is DESYNC/DONOR, as this is the only node we will put this one online"
466
            echo "1" > ${RELOAD_CHECK_FILE}
467
            cnt=$(( $cnt + 1 ))
468
          else # otherwise (we are already ONLINE in runtime_mysql_servers) no need to reload so let's just remove RELOAD_CHECK_FILE and update it to ONLINE in mysql_servers (in case something would reload it)
469
            rm ${RELOAD_CHECK_FILE}
470
            cnt=$(( $cnt + 1 ))
471
            change_server_status $HOSTGROUP_READER_ID "$server" $port "ONLINE" "WSREP status is DESYNC/DONOR, as this is the only node we will put this one online"
472
          fi
473
        fi
474
        safety_cnt=$(( $safety_cnt + 1 ))
475
    done
476
  done
477
  CHECK_SLAVE=$(proxysql_exec "SELECT hostname FROM mysql_servers WHERE comment='SLAVEREAD' AND status='ONLINE'" 2>>${ERR_FILE}| tail -1 2>>${ERR_FILE})
478
  IS_QUERY_RULE_ACTIVE=$(proxysql_exec "SELECT active FROM mysql_query_rules WHERE destination_hostgroup=$HOSTGROUP_READER_ID limit 1;" 2>> ${ERR_FILE} | tail -1 2>>${ERR_FILE})
479
  if [ "$MODE" == "singlewrite" ]; then
480
    if [[ -z ${CHECK_SLAVE} ]]; then
481
      if [[ ${IS_QUERY_RULE_ACTIVE} -eq 1 ]]; then
482
        proxysql_exec "UPDATE mysql_query_rules SET active=0 WHERE destination_hostgroup=$HOSTGROUP_READER_ID;" 2>> ${ERR_FILE}
483
        proxysql_exec "LOAD MYSQL QUERY RULES TO RUNTIME;" 2>> ${ERR_FILE}
484
        echo "`date` No readers found, marking single writer node as read/write mode" >> ${ERR_FILE}
485
      fi
486
    else
487
      if [[ ${IS_QUERY_RULE_ACTIVE} -eq 0 ]]; then
488
        proxysql_exec "UPDATE mysql_query_rules SET active=1 WHERE destination_hostgroup=$HOSTGROUP_READER_ID;" 2>> ${ERR_FILE}
489
        proxysql_exec "LOAD MYSQL QUERY RULES TO RUNTIME;" 2>> ${ERR_FILE}
490
        echo "`date` Slave host is online, disabling read transaction from writer node" >> ${ERR_FILE}
491
      fi
492
    fi
493
  fi
494
fi
495
496
if [ "$MODE" == "singlewrite" ]; then
497
  if [  ${HOSTGROUP_READER_ID} -ne -1 -a ${NUMBER_READERS_ONLINE} -gt 0 ]; then
498
    IS_QUERY_RULE_ACTIVE=$(proxysql_exec "SELECT active FROM mysql_query_rules WHERE destination_hostgroup=$HOSTGROUP_READER_ID limit 1;" 2>> ${ERR_FILE} | tail -1 2>>${ERR_FILE})
499
    if [[ ${IS_QUERY_RULE_ACTIVE} -eq 0 ]]; then
500
      proxysql_exec "UPDATE mysql_query_rules SET active=1 WHERE destination_hostgroup=$HOSTGROUP_READER_ID;" 2>> ${ERR_FILE}
501
      proxysql_exec "LOAD MYSQL QUERY RULES TO RUNTIME;" 2>> ${ERR_FILE}
502
      echo "`date` Found reader, disabling read transaction from writer node" >> ${ERR_FILE}
503
    fi
504
  fi
505
fi
506
507
if [ $(cat ${RELOAD_CHECK_FILE})  -ne 0 ] ; then
508
    echo "`date` ###### Loading mysql_servers config into runtime ######" >> ${ERR_FILE}
509
    proxysql_exec "LOAD MYSQL SERVERS TO RUNTIME;" 2>> ${ERR_FILE}
510
else
511
    echo "`date` ###### Not loading mysql_servers, no change needed ######" >> ${ERR_FILE}
512
fi
513
514
exit 0
515