[MINOR] add option "mysql-check" to use MySQL health checks

This patch adds support for MySQL health checks. Those are
enabled using the new option "mysql-check".
This commit is contained in:
Hervé COMMOWICK 2010-01-12 09:25:13 +01:00 committed by Willy Tarreau
parent 9f2b9d5bf7
commit 698ae00fc2
5 changed files with 98 additions and 5 deletions

View File

@ -771,6 +771,7 @@ option httplog X X X X
[no] option log-separate-
errors X X X -
[no] option logasap X X X -
option mysql-check X - X X
[no] option nolinger X X X X
option originalto X X X X
[no] option persist X - X X
@ -2526,8 +2527,8 @@ option httpchk <method> <uri> <version>
option httpchk OPTIONS * HTTP/1.1\r\nHost:\ www
server apache1 192.168.1.1:443 check port 80
See also : "option ssl-hello-chk", "option smtpchk", "http-check" and the
"check", "port" and "interval" server options.
See also : "option ssl-hello-chk", "option smtpchk", "option mysql-check",
"http-check" and the "check", "port" and "interval" server options.
option http-server-close
@ -2770,6 +2771,28 @@ no option logasap
logging.
option mysql-check
Use Mysql health checks for server testing
May be used in sections : defaults | frontend | listen | backend
yes | no | yes | yes
Arguments : none
The check consists in parsing Mysql Handshake Initialisation packet or Error
packet, which is sent by MySQL server on connect. It is a basic but useful
test which does not produce any logging on the server. However, it does not
check database presence nor database consistency, nor user permission to
access. To do this, you can use an external check with xinetd for example.
Most often, an incoming MySQL server needs to see the client's IP address for
various purposes, including IP privilege matching and connection logging.
When possible, it is often wise to masquerade the client's IP address when
connecting to the server using the "usesrc" argument of the "source" keyword,
which requires the cttproxy feature to be compiled in, and the MySQL server
to route the client via the machine hosting haproxy.
See also: "option httpchk"
option nolinger
no option nolinger
Enable or disable immediate session resource cleaning after close
@ -4809,8 +4832,8 @@ check
"port" parameter, the source address using the "source" address, and the
interval and timers using the "inter", "rise" and "fall" parameters. The
request method is define in the backend using the "httpchk", "smtpchk",
and "ssl-hello-chk" options. Please refer to those options and parameters for
more information.
"mysql-check" and "ssl-hello-chk" options. Please refer to those options and
parameters for more information.
Supported in default-server: No

View File

@ -132,6 +132,8 @@
#define PR_O2_AS_M_QS 0x00010000 /* query-string mode */
#define PR_O2_AS_M_ANY 0x00010000 /* mask covering all PR_O2_AS_M_* values */
#define PR_O2_MYSQL_CHK 0x00020000 /* use MYSQL check for server health */
struct error_snapshot {
struct timeval when; /* date of this event, (tv_sec == 0) means "never" */
unsigned int len; /* original length of the last invalid request/response */

View File

@ -2227,6 +2227,7 @@ stats_error_parsing:
free(curproxy->check_req);
curproxy->options &= ~PR_O_SSL3_CHK;
curproxy->options &= ~PR_O_SMTP_CHK;
curproxy->options2 &= ~PR_O2_MYSQL_CHK;
curproxy->options |= PR_O_HTTP_CHK;
if (!*args[2]) { /* no argument */
curproxy->check_req = strdup(DEF_CHECK_REQ); /* default request */
@ -2256,6 +2257,7 @@ stats_error_parsing:
free(curproxy->check_req);
curproxy->options &= ~PR_O_HTTP_CHK;
curproxy->options &= ~PR_O_SMTP_CHK;
curproxy->options2 &= ~PR_O2_MYSQL_CHK;
curproxy->options |= PR_O_SSL3_CHK;
}
else if (!strcmp(args[1], "smtpchk")) {
@ -2263,6 +2265,7 @@ stats_error_parsing:
free(curproxy->check_req);
curproxy->options &= ~PR_O_HTTP_CHK;
curproxy->options &= ~PR_O_SSL3_CHK;
curproxy->options2 &= ~PR_O2_MYSQL_CHK;
curproxy->options |= PR_O_SMTP_CHK;
if (!*args[2] || !*args[3]) { /* no argument or incomplete EHLO host */
@ -2282,6 +2285,14 @@ stats_error_parsing:
}
}
}
else if (!strcmp(args[1], "mysql-check")) {
/* use MYSQL request to check servers' health */
free(curproxy->check_req);
curproxy->options &= ~PR_O_HTTP_CHK;
curproxy->options &= ~PR_O_SSL3_CHK;
curproxy->options &= ~PR_O_SMTP_CHK;
curproxy->options2 |= PR_O2_MYSQL_CHK;
}
else if (!strcmp(args[1], "forwardfor")) {
int cur_arg;

View File

@ -660,7 +660,8 @@ static int event_srv_chk_w(int fd)
/* we don't want to mark 'UP' a server on which we detected an error earlier */
if ((s->proxy->options & PR_O_HTTP_CHK) ||
(s->proxy->options & PR_O_SSL3_CHK) ||
(s->proxy->options & PR_O_SMTP_CHK)) {
(s->proxy->options & PR_O_SMTP_CHK) ||
(s->proxy->options2 & PR_O2_MYSQL_CHK)) {
int ret;
/* we want to check if this host replies to HTTP or SSLv3 requests
* so we'll send the request, and won't wake the checker up now.
@ -862,6 +863,33 @@ static int event_srv_chk_r(int fd)
else
set_server_check_status(s, HCHK_STATUS_L7STS, desc);
}
else if (s->proxy->options2 & PR_O2_MYSQL_CHK) {
/* MySQL Error packet always begin with field_count = 0xff
* contrary to OK Packet who always begin whith 0x00 */
if (trash[4] != -1) {
/* We set the MySQL Version in description for information purpose
* FIXME : it can be cool to use MySQL Version for other purpose,
* like mark as down old MySQL server.
*/
if (len > 51) {
desc = ltrim(&trash[5], ' ');
set_server_check_status(s, HCHK_STATUS_L7OKD, desc);
}
else {
/* it seems we have a OK packet but without a valid length,
* it must be a protocol error
*/
set_server_check_status(s, HCHK_STATUS_L7RSP, trash);
}
}
else {
/* An error message is attached in the Error packet,
* so we can display it ! :)
*/
desc = ltrim(&trash[7], ' ');
set_server_check_status(s, HCHK_STATUS_L7STS, desc);
}
}
else {
/* other checks are valid if the connection succeeded anyway */
set_server_check_status(s, HCHK_STATUS_L4OK, NULL);

29
tests/test-sql.cfg Normal file
View File

@ -0,0 +1,29 @@
# This is a test configuration.
# It requires a mysql server running on local port 3306.
global
maxconn 500
defaults
contimeout 1000
clitimeout 5000
srvtimeout 5000
retries 1
option redispatch
listen stats
bind :8080
mode http
stats enable
stats uri /stats
listen mysql_1
bind :3307
mode tcp
balance roundrobin
option mysql-check
server srv1 127.0.0.1:3306 check port 3306 inter 1000 fall 1
# server srv2 127.0.0.2:3306 check port 3306 inter 1000 fall 1
# server srv3 127.0.0.3:3306 check port 3306 inter 1000 fall 1
# server srv4 127.0.0.4:3306 check port 3306 inter 1000 fall 1