[MINOR] checks: add PostgreSQL health check

I have written a small patch to enable a correct PostgreSQL health check
It works similar to mysql-check with the very same parameters.

E.g.:
listen pgsql 127.0.0.1:5432
   mode tcp
   option pgsql-check user pgsql
   server masterdb pgsql.server.com:5432 check inter 10000
This commit is contained in:
Rauf Kuliyev 2011-01-04 15:14:13 +01:00 committed by Willy Tarreau
parent 0013433b09
commit 38b4156a69
4 changed files with 106 additions and 3 deletions

View File

@ -993,6 +993,7 @@ option log-health-checks (*) X - X X
option log-separate-errors (*) X X X -
option logasap (*) X X X -
option mysql-check X - X X
option pgsql-check X - X X
option nolinger (*) X X X X
option originalto X X X X
option persist (*) X - X X
@ -3266,7 +3267,8 @@ option httpchk <method> <uri> <version>
server apache1 192.168.1.1:443 check port 80
See also : "option ssl-hello-chk", "option smtpchk", "option mysql-check",
"http-check" and the "check", "port" and "inter" server options.
"option pgsql-check", "http-check" and the "check", "port" and
"inter" server options.
option httpclose
@ -3540,6 +3542,20 @@ option mysql-check [ user <username> ]
See also: "option httpchk"
option pgsql-check [ user <username> ]
Use PostgreSQL health checks for server testing
May be used in sections : defaults | frontend | listen | backend
yes | no | yes | yes
Arguments :
user <username> This is the username which will be used when connecting
to PostgreSQL server.
The check sends a PostgreSQL StartupMessage and waits for either
Authentication request or ErrorResponse message. It is a basic but useful
test which does not produce error nor aborted connect on the server.
This check is identical with the "mysql-check".
See also: "option httpchk"
option nolinger
no option nolinger
@ -6457,8 +6473,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",
"mysql-check" and "ssl-hello-chk" options. Please refer to those options and
parameters for more information.
"mysql-check", "pgsql-check" and "ssl-hello-chk" options. Please refer to
those options and parameters for more information.
Supported in default-server: No

View File

@ -149,6 +149,8 @@
#define PR_O2_EXP_TYPE 0x03800000 /* mask for http-check expect type */
#define PR_O2_EXP_INV 0x04000000 /* http-check expect !<rule> */
#define PR_O2_COOK_PSV 0x08000000 /* cookie ... preserve */
#define PR_O2_PGSQL_CHK 0x10000000 /* use PGSQL check for server health */
/* end of proxy->options2 */
/* bits for sticking rules */

View File

@ -3312,6 +3312,7 @@ stats_error_parsing:
curproxy->options &= ~PR_O_SMTP_CHK;
curproxy->options2 &= ~PR_O2_SSL3_CHK;
curproxy->options2 &= ~PR_O2_MYSQL_CHK;
curproxy->options2 &= ~PR_O2_PGSQL_CHK;
curproxy->options2 &= ~PR_O2_LDAP_CHK;
curproxy->options |= PR_O_HTTP_CHK;
if (!*args[2]) { /* no argument */
@ -3344,6 +3345,7 @@ stats_error_parsing:
curproxy->options &= ~PR_O_HTTP_CHK;
curproxy->options &= ~PR_O_SMTP_CHK;
curproxy->options2 &= ~PR_O2_MYSQL_CHK;
curproxy->options2 &= ~PR_O2_PGSQL_CHK;
curproxy->options2 &= ~PR_O2_LDAP_CHK;
curproxy->options2 |= PR_O2_SSL3_CHK;
}
@ -3354,6 +3356,7 @@ stats_error_parsing:
curproxy->options &= ~PR_O_HTTP_CHK;
curproxy->options2 &= ~PR_O2_SSL3_CHK;
curproxy->options2 &= ~PR_O2_MYSQL_CHK;
curproxy->options2 &= ~PR_O2_PGSQL_CHK;
curproxy->options2 &= ~PR_O2_LDAP_CHK;
curproxy->options |= PR_O_SMTP_CHK;
@ -3374,6 +3377,69 @@ stats_error_parsing:
}
}
}
else if (!strcmp(args[1], "pgsql-check")) {
/* use PostgreSQL request to check servers' health */
if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
err_code |= ERR_WARN;
free(curproxy->check_req);
curproxy->check_req = NULL;
curproxy->options &= ~PR_O_HTTP_CHK;
curproxy->options &= ~PR_O_SMTP_CHK;
curproxy->options2 &= ~PR_O2_SSL3_CHK;
curproxy->options2 &= ~PR_O2_LDAP_CHK;
curproxy->options2 &= ~PR_O2_MYSQL_CHK;
curproxy->options2 |= PR_O2_PGSQL_CHK;
if (*(args[2])) {
int cur_arg = 2;
while (*(args[cur_arg])) {
if (strcmp(args[cur_arg], "user") == 0) {
char * packet;
uint32_t packet_len;
uint32_t pv;
/* suboption header - needs additional argument for it */
if (*(args[cur_arg+1]) == 0) {
Alert("parsing [%s:%d] : '%s %s %s' expects <username> as argument.\n",
file, linenum, args[0], args[1], args[cur_arg]);
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
}
/* uint32_t + uint32_t + strlen("user")+1 + strlen(username)+1 + 1 */
packet_len = 4 + 4 + 5 + strlen(args[cur_arg + 1])+1 +1;
pv = htonl(0x30000); /* protocol version 3.0 */
packet = (char*) calloc(1, packet_len);
memcpy(packet + 4, &pv, 4);
/* copy "user" */
memcpy(packet + 8, "user", 4);
/* copy username */
memcpy(packet + 13, args[cur_arg+1], strlen(args[cur_arg+1]));
free(curproxy->check_req);
curproxy->check_req = packet;
curproxy->check_len = packet_len;
packet_len = htonl(packet_len);
memcpy(packet, &packet_len, 4);
cur_arg += 2;
} else {
/* unknown suboption - catchall */
Alert("parsing [%s:%d] : '%s %s' only supports optional values: 'user'.\n",
file, linenum, args[0], args[1]);
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
}
} /* end while loop */
}
}
else if (!strcmp(args[1], "mysql-check")) {
/* use MYSQL request to check servers' health */
if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[1], NULL))
@ -3385,6 +3451,7 @@ stats_error_parsing:
curproxy->options &= ~PR_O_SMTP_CHK;
curproxy->options2 &= ~PR_O2_SSL3_CHK;
curproxy->options2 &= ~PR_O2_LDAP_CHK;
curproxy->options2 &= ~PR_O2_PGSQL_CHK;
curproxy->options2 |= PR_O2_MYSQL_CHK;
/* This is an exemple of an MySQL >=4.0 client Authentication packet kindly provided by Cyril Bonte.
@ -3454,6 +3521,7 @@ stats_error_parsing:
curproxy->options &= ~PR_O_SMTP_CHK;
curproxy->options2 &= ~PR_O2_SSL3_CHK;
curproxy->options2 &= ~PR_O2_MYSQL_CHK;
curproxy->options2 &= ~PR_O2_PGSQL_CHK;
curproxy->options2 |= PR_O2_LDAP_CHK;
curproxy->check_req = (char *) malloc(sizeof(DEF_LDAP_CHECK_REQ) - 1);

View File

@ -747,6 +747,7 @@ static int event_srv_chk_w(int fd)
(s->proxy->options & PR_O_SMTP_CHK) ||
(s->proxy->options2 & PR_O2_SSL3_CHK) ||
(s->proxy->options2 & PR_O2_MYSQL_CHK) ||
(s->proxy->options2 & PR_O2_PGSQL_CHK) ||
(s->proxy->options2 & PR_O2_LDAP_CHK)) {
int ret;
const char *check_req = s->proxy->check_req;
@ -1001,6 +1002,22 @@ 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_PGSQL_CHK) {
if (!done && s->check_data_len < 9)
goto wait_more_data;
if (s->check_data[0] == 'R') {
set_server_check_status(s, HCHK_STATUS_L7OKD, "PostgreSQL server is ok");
}
else {
if ((s->check_data[0] == 'E') && (s->check_data[5]!=0) && (s->check_data[6]!=0))
desc = &s->check_data[6];
else
desc = "PostgreSQL unknown error";
set_server_check_status(s, HCHK_STATUS_L7STS, desc);
}
}
else if (s->proxy->options2 & PR_O2_MYSQL_CHK) {
if (!done && s->check_data_len < 5)
goto wait_more_data;