"node check": add server role check

This commit is contained in:
Ian Barwick
2017-08-14 22:57:09 +09:00
parent fa7d60cd51
commit 10ef30096c
9 changed files with 156 additions and 22 deletions

View File

@@ -1038,9 +1038,16 @@ get_recovery_type(PGconn *conn)
PQerrorMessage(conn)); PQerrorMessage(conn));
recovery_type = RECTYPE_UNKNOWN; recovery_type = RECTYPE_UNKNOWN;
} }
else if (PQntuples(res) == 1 && strcmp(PQgetvalue(res, 0, 0), "t") == 0) else if (PQntuples(res) == 1)
{ {
recovery_type = RECTYPE_STANDBY; if (strcmp(PQgetvalue(res, 0, 0), "f") == 0)
{
recovery_type = RECTYPE_PRIMARY;
}
else
{
recovery_type = RECTYPE_STANDBY;
}
} }
PQclear(res); PQclear(res);
@@ -1462,19 +1469,23 @@ get_replication_lag_seconds(PGconn *conn)
" AS lag_seconds"); " AS lag_seconds");
res = PQexec(conn, query.data); res = PQexec(conn, query.data);
log_verbose(LOG_DEBUG, "get_replication_lag_seconds():\n%s", query.data);
termPQExpBuffer(&query); termPQExpBuffer(&query);
log_verbose(LOG_DEBUG, "get_node_record():\n%s", query.data); if (PQresultStatus(res) != PGRES_TUPLES_OK)
if (PQresultStatus(res) != PGRES_TUPLES_OK || !PQntuples(res))
{ {
log_warning("%s", PQerrorMessage(conn)); log_warning("%s", PQerrorMessage(conn));
PQclear(res); PQclear(res);
/* XXX magic number */ /* XXX magic number */
return -1; return -1;
} }
if (!PQntuples(res))
{
return -1;
}
lag_seconds = atoi(PQgetvalue(res, 0, 0)); lag_seconds = atoi(PQgetvalue(res, 0, 0));
PQclear(res); PQclear(res);
@@ -3576,7 +3587,7 @@ get_last_wal_receive_location(PGconn *conn)
/* ============= */ /* ============= */
bool bool
is_bdr_db(PGconn *conn) is_bdr_db(PGconn *conn, PQExpBufferData *output)
{ {
PQExpBufferData query; PQExpBufferData query;
PGresult *res = NULL; PGresult *res = NULL;
@@ -3604,7 +3615,13 @@ is_bdr_db(PGconn *conn)
if (is_bdr_db == false) if (is_bdr_db == false)
{ {
log_warning(_("BDR extension is not available for this database")); const char *warning = _("BDR extension is not available for this database");
if (output != NULL)
appendPQExpBuffer(output, "%s", warning);
else
log_warning("%s", warning);
return is_bdr_db; return is_bdr_db;
} }
@@ -3620,11 +3637,15 @@ is_bdr_db(PGconn *conn)
if (is_bdr_db == false) if (is_bdr_db == false)
{ {
log_warning(_("BDR extension available for this database, but the database is not configured for BDR")); const char *warning = _("BDR extension available for this database, but the database is not configured for BDR");
if (output != NULL)
appendPQExpBuffer(output, "%s", warning);
else
log_warning("%s", warning);
} }
PQclear(res);
PQclear(res);
return is_bdr_db; return is_bdr_db;
} }

View File

@@ -441,7 +441,7 @@ void get_node_replication_stats(PGconn *conn, t_node_info *node_info);
/* BDR functions */ /* BDR functions */
void get_all_bdr_node_records(PGconn *conn, BdrNodeInfoList *node_list); void get_all_bdr_node_records(PGconn *conn, BdrNodeInfoList *node_list);
RecordStatus get_bdr_node_record_by_name(PGconn *conn, const char *node_name, t_bdr_node_info *node_info); RecordStatus get_bdr_node_record_by_name(PGconn *conn, const char *node_name, t_bdr_node_info *node_info);
bool is_bdr_db(PGconn *conn); bool is_bdr_db(PGconn *conn, PQExpBufferData *output);
bool is_active_bdr_node(PGconn *conn, const char *node_name); bool is_active_bdr_node(PGconn *conn, const char *node_name);
bool is_bdr_repmgr(PGconn *conn); bool is_bdr_repmgr(PGconn *conn);
bool is_table_in_bdr_replication_set(PGconn *conn, const char *tablename, const char *set); bool is_table_in_bdr_replication_set(PGconn *conn, const char *tablename, const char *set);

View File

@@ -42,7 +42,7 @@ do_bdr_register(void)
conn = establish_db_connection(config_file_options.conninfo, true); conn = establish_db_connection(config_file_options.conninfo, true);
if (!is_bdr_db(conn)) if (!is_bdr_db(conn, NULL))
{ {
log_error(_("database \"%s\" is not BDR-enabled"), dbname); log_error(_("database \"%s\" is not BDR-enabled"), dbname);
log_hint(_("when using repmgr with BDR, the repmgr schema must be stored in the BDR database")); log_hint(_("when using repmgr with BDR, the repmgr schema must be stored in the BDR database"));
@@ -336,7 +336,7 @@ do_bdr_unregister(void)
conn = establish_db_connection(config_file_options.conninfo, true); conn = establish_db_connection(config_file_options.conninfo, true);
if (!is_bdr_db(conn)) if (!is_bdr_db(conn, NULL))
{ {
log_error(_("database \"%s\" is not BDR-enabled"), dbname); log_error(_("database \"%s\" is not BDR-enabled"), dbname);
exit(ERR_BAD_CONFIG); exit(ERR_BAD_CONFIG);

View File

@@ -29,6 +29,10 @@ static void _do_node_status_is_shutdown(void);
static void _do_node_archive_config(void); static void _do_node_archive_config(void);
static void _do_node_restore_config(void); static void _do_node_restore_config(void);
static CheckStatus do_node_check_role(PGconn *conn, OutputMode mode, t_node_info *node_info, CheckStatusList *list_output);
static CheckStatus do_node_check_archiver(PGconn *conn, OutputMode mode, CheckStatusList *list_output);
static CheckStatus do_node_check_replication_lag(PGconn *conn, OutputMode mode, CheckStatusList *list_output);
void void
do_node_status(void) do_node_status(void)
@@ -547,11 +551,18 @@ do_node_check(void)
return; return;
} }
if (runtime_options.role == true)
{
(void) do_node_check_role(conn, runtime_options.output_mode, &node_info, NULL);
PQfinish(conn);
return;
}
/* output general overview */ /* output general overview */
initPQExpBuffer(&output); initPQExpBuffer(&output);
//(void) do_node_check_role(conn, runtime_options.output_mode, &output); (void) do_node_check_role(conn, runtime_options.output_mode, &node_info, &status_list);
(void) do_node_check_replication_lag(conn, runtime_options.output_mode, &status_list); (void) do_node_check_replication_lag(conn, runtime_options.output_mode, &status_list);
(void) do_node_check_archiver(conn, runtime_options.output_mode, &status_list); (void) do_node_check_archiver(conn, runtime_options.output_mode, &status_list);
@@ -594,7 +605,104 @@ do_node_check(void)
PQfinish(conn); PQfinish(conn);
} }
CheckStatus
static CheckStatus
do_node_check_role(PGconn *conn, OutputMode mode, t_node_info *node_info, CheckStatusList *list_output)
{
CheckStatus status = CHECK_STATUS_OK;
PQExpBufferData details;
RecoveryType recovery_type = get_recovery_type(conn);
if (mode == OM_CSV)
{
log_error(_("--csv output not provided with --role option"));
PQfinish(conn);
exit(ERR_BAD_CONFIG);
}
initPQExpBuffer(&details);
switch (node_info->type)
{
case PRIMARY:
if (recovery_type == RECTYPE_STANDBY)
{
status = CHECK_STATUS_CRITICAL;
appendPQExpBuffer(
&details,
_("node is registered as primary but running as standby"));
}
break;
case STANDBY:
if (recovery_type == RECTYPE_PRIMARY)
{
status = CHECK_STATUS_CRITICAL;
appendPQExpBuffer(
&details,
_("node is registered as standby but running as primary"));
}
break;
case BDR:
{
PQExpBufferData output;
initPQExpBuffer(&output);
if (is_bdr_db(conn, &output) == false)
{
status = CHECK_STATUS_CRITICAL;
appendPQExpBuffer(
&details,
"%s", output.data);
}
termPQExpBuffer(&output);
if (status == CHECK_STATUS_OK)
{
if (is_active_bdr_node(conn, node_info->node_name) == false)
{
status = CHECK_STATUS_CRITICAL;
appendPQExpBuffer(
&details,
_("node is not an active BDR node"));
}
}
}
default:
break;
}
switch (mode)
{
case OM_NAGIOS:
printf("PG_SERVER_ROLE %s: %s\n",
output_check_status(status),
details.data);
break;
case OM_TEXT:
if (list_output != NULL)
{
check_status_list_set(list_output,
"Server role",
status,
details.data);
}
else
{
printf("%s (%s)\n",
output_check_status(status),
details.data);
}
default:
break;
}
termPQExpBuffer(&details);
return status;
}
static CheckStatus
do_node_check_archiver(PGconn *conn, OutputMode mode, CheckStatusList *list_output) do_node_check_archiver(PGconn *conn, OutputMode mode, CheckStatusList *list_output)
{ {
int ready_archive_files = 0; int ready_archive_files = 0;
@@ -604,6 +712,7 @@ do_node_check_archiver(PGconn *conn, OutputMode mode, CheckStatusList *list_outp
if (mode == OM_CSV) if (mode == OM_CSV)
{ {
log_error(_("--csv output not provided with --archiver option")); log_error(_("--csv output not provided with --archiver option"));
PQfinish(conn);
exit(ERR_BAD_CONFIG); exit(ERR_BAD_CONFIG);
} }
@@ -748,7 +857,7 @@ do_node_check_archiver(PGconn *conn, OutputMode mode, CheckStatusList *list_outp
} }
CheckStatus static CheckStatus
do_node_check_replication_lag(PGconn *conn, OutputMode mode, CheckStatusList *list_output) do_node_check_replication_lag(PGconn *conn, OutputMode mode, CheckStatusList *list_output)
{ {
CheckStatus status = CHECK_STATUS_UNKNOWN; CheckStatus status = CHECK_STATUS_UNKNOWN;
@@ -758,6 +867,7 @@ do_node_check_replication_lag(PGconn *conn, OutputMode mode, CheckStatusList *li
if (mode == OM_CSV) if (mode == OM_CSV)
{ {
log_error(_("--csv output not provided with --replication-lag option")); log_error(_("--csv output not provided with --replication-lag option"));
PQfinish(conn);
exit(ERR_BAD_CONFIG); exit(ERR_BAD_CONFIG);
} }

View File

@@ -8,10 +8,6 @@
extern void do_node_status(void); extern void do_node_status(void);
extern void do_node_check(void); extern void do_node_check(void);
//extern CheckStatus do_node_check_archiver(PGconn *conn, OutputMode mode, PQExpBufferData *output);
extern CheckStatus do_node_check_archiver(PGconn *conn, OutputMode mode, CheckStatusList *list_output);
extern CheckStatus do_node_check_replication_lag(PGconn *conn, OutputMode mode, CheckStatusList *list_output);
extern void do_node_rejoin(void); extern void do_node_rejoin(void);

View File

@@ -86,6 +86,7 @@ typedef struct
/* "node check" options */ /* "node check" options */
bool archiver; bool archiver;
bool replication_lag; bool replication_lag;
bool role;
/* "node join" options */ /* "node join" options */
char config_files[MAXLEN]; char config_files[MAXLEN];
@@ -131,7 +132,7 @@ typedef struct
/* "node status" options */ \ /* "node status" options */ \
false, \ false, \
/* "node check" options */ \ /* "node check" options */ \
false, false, \ false, false, false, \
/* "node join" options */ \ /* "node join" options */ \
"", \ "", \
/* "node service" options */ \ /* "node service" options */ \

View File

@@ -430,6 +430,10 @@ main(int argc, char **argv)
runtime_options.replication_lag = true; runtime_options.replication_lag = true;
break; break;
case OPT_ROLE:
runtime_options.role = true;
break;
/* "node join" options * /* "node join" options *
* ------------------- */ * ------------------- */
case OPT_CONFIG_FILES: case OPT_CONFIG_FILES:

View File

@@ -70,6 +70,7 @@
#define OPT_REPLICATION_LAG 1034 #define OPT_REPLICATION_LAG 1034
#define OPT_CONFIG_FILES 1035 #define OPT_CONFIG_FILES 1035
#define OPT_SIBLINGS_FOLLOW 1036 #define OPT_SIBLINGS_FOLLOW 1036
#define OPT_ROLE 1037
/* deprecated since 3.3 */ /* deprecated since 3.3 */
#define OPT_DATA_DIR 999 #define OPT_DATA_DIR 999
#define OPT_NO_CONNINFO_PASSWORD 998 #define OPT_NO_CONNINFO_PASSWORD 998
@@ -139,6 +140,7 @@ static struct option long_options[] =
/* "node check" options */ /* "node check" options */
{"archiver", no_argument, NULL, OPT_ARCHIVER }, {"archiver", no_argument, NULL, OPT_ARCHIVER },
{"replication-lag", no_argument, NULL, OPT_REPLICATION_LAG }, {"replication-lag", no_argument, NULL, OPT_REPLICATION_LAG },
{"role", no_argument, NULL, OPT_ROLE },
/* "node join" options */ /* "node join" options */
{"config-files", required_argument, NULL, OPT_CONFIG_FILES }, {"config-files", required_argument, NULL, OPT_CONFIG_FILES },

View File

@@ -59,7 +59,7 @@ monitor_bdr(void)
*/ */
log_info(_("connected to database, checking for BDR")); log_info(_("connected to database, checking for BDR"));
if (!is_bdr_db(local_conn)) if (!is_bdr_db(local_conn, NULL))
{ {
log_error(_("database is not BDR-enabled")); log_error(_("database is not BDR-enabled"));
exit(ERR_BAD_CONFIG); exit(ERR_BAD_CONFIG);