mirror of
https://github.com/EnterpriseDB/repmgr.git
synced 2026-03-24 15:46:29 +00:00
Improve "repmgr cluster show" display
Rather than simply emit "FAILED" for an unreachable node, indicate whether its state matches that expected by repmgr. E.g. following output: ID | Name | Role | Status | Upstream | Connection string ----+-------+---------+----------------------+----------+---------------------------------------------------- 1 | node1 | primary | * running | | host=localhost dbname=repmgr user=repmgr port=5501 2 | node2 | standby | ? unreachable | node1 | host=localhost dbname=repmgr user=repmgr port=5502 3 | node3 | standby | ! running as primary | node1 | host=localhost dbname=repmgr user=repmgr port=5503 is for a cluster where "node2" has been manually stopped, and "node3" manually promoted.
This commit is contained in:
@@ -11,12 +11,17 @@
|
|||||||
#include "repmgr-client-global.h"
|
#include "repmgr-client-global.h"
|
||||||
#include "repmgr-action-cluster.h"
|
#include "repmgr-action-cluster.h"
|
||||||
|
|
||||||
#define SHOW_HEADER_COUNT 4
|
#define SHOW_HEADER_COUNT 6
|
||||||
|
|
||||||
#define ROLE_HEADER 0
|
// id,name,role,status,upstream_name,conninfo
|
||||||
#define NAME_HEADER 1
|
typedef enum {
|
||||||
#define UPSTREAM_NAME_HEADER 2
|
SHOW_ID = 0,
|
||||||
#define CONNINFO_HEADER 3
|
SHOW_NAME,
|
||||||
|
SHOW_ROLE,
|
||||||
|
SHOW_STATUS,
|
||||||
|
SHOW_UPSTREAM_NAME,
|
||||||
|
SHOW_CONNINFO
|
||||||
|
} ShowHeader;
|
||||||
|
|
||||||
#define EVENT_HEADER_COUNT 5
|
#define EVENT_HEADER_COUNT 5
|
||||||
|
|
||||||
@@ -64,10 +69,12 @@ do_cluster_show(void)
|
|||||||
exit(ERR_BAD_CONFIG);
|
exit(ERR_BAD_CONFIG);
|
||||||
}
|
}
|
||||||
|
|
||||||
strncpy(headers_show[ROLE_HEADER].title, _("Role"), MAXLEN);
|
strncpy(headers_show[SHOW_ID].title, _("ID"), MAXLEN);
|
||||||
strncpy(headers_show[NAME_HEADER].title, _("Name"), MAXLEN);
|
strncpy(headers_show[SHOW_NAME].title, _("Name"), MAXLEN);
|
||||||
strncpy(headers_show[UPSTREAM_NAME_HEADER].title, _("Upstream"), MAXLEN);
|
strncpy(headers_show[SHOW_ROLE].title, _("Role"), MAXLEN);
|
||||||
strncpy(headers_show[CONNINFO_HEADER].title, _("Connection string"), MAXLEN);
|
strncpy(headers_show[SHOW_STATUS].title, _("Status"), MAXLEN);
|
||||||
|
strncpy(headers_show[SHOW_UPSTREAM_NAME].title, _("Upstream"), MAXLEN);
|
||||||
|
strncpy(headers_show[SHOW_CONNINFO].title, _("Connection string"), MAXLEN);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XXX if repmgr is ever localized into non-ASCII locales,
|
* XXX if repmgr is ever localized into non-ASCII locales,
|
||||||
@@ -81,39 +88,129 @@ do_cluster_show(void)
|
|||||||
|
|
||||||
for (cell = nodes.head; cell; cell = cell->next)
|
for (cell = nodes.head; cell; cell = cell->next)
|
||||||
{
|
{
|
||||||
|
RecoveryType rec_type = RECTYPE_UNKNOWN;
|
||||||
|
PQExpBufferData details;
|
||||||
|
|
||||||
cell->node_info->conn = establish_db_connection_quiet(cell->node_info->conninfo);
|
cell->node_info->conn = establish_db_connection_quiet(cell->node_info->conninfo);
|
||||||
|
|
||||||
if (PQstatus(conn) != CONNECTION_OK)
|
if (PQstatus(cell->node_info->conn) == CONNECTION_OK)
|
||||||
{
|
{
|
||||||
strcpy(cell->node_info->details, " FAILED");
|
cell->node_info->node_status = NODE_STATUS_UP;
|
||||||
}
|
|
||||||
else if (cell->node_info->type == BDR)
|
if (cell->node_info->type != BDR)
|
||||||
{
|
{
|
||||||
strcpy(cell->node_info->details, " BDR");
|
rec_type = get_recovery_type(cell->node_info->conn);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
RecoveryType rec_type = get_recovery_type(cell->node_info->conn);
|
cell->node_info->node_status = NODE_STATUS_DOWN;
|
||||||
switch (rec_type)
|
|
||||||
{
|
|
||||||
case RECTYPE_PRIMARY:
|
|
||||||
strcpy(cell->node_info->details, "* primary");
|
|
||||||
break;
|
|
||||||
case RECTYPE_STANDBY:
|
|
||||||
strcpy(cell->node_info->details, " standby");
|
|
||||||
break;
|
|
||||||
case RECTYPE_UNKNOWN:
|
|
||||||
strcpy(cell->node_info->details, " unknown");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
initPQExpBuffer(&details);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO: count nodes marked as "? unreachable" and add a hint about
|
||||||
|
* the other cluster commands for better determining whether unreachable.
|
||||||
|
*/
|
||||||
|
switch (cell->node_info->type)
|
||||||
|
{
|
||||||
|
case PRIMARY:
|
||||||
|
{
|
||||||
|
/* node is reachable */
|
||||||
|
if (cell->node_info->node_status == NODE_STATUS_UP)
|
||||||
|
{
|
||||||
|
if (cell->node_info->active == true)
|
||||||
|
{
|
||||||
|
switch (rec_type)
|
||||||
|
{
|
||||||
|
case RECTYPE_PRIMARY:
|
||||||
|
appendPQExpBuffer(&details, "* running");
|
||||||
|
break;
|
||||||
|
case RECTYPE_STANDBY:
|
||||||
|
appendPQExpBuffer(&details, "! running as standby");
|
||||||
|
break;
|
||||||
|
case RECTYPE_UNKNOWN:
|
||||||
|
appendPQExpBuffer(&details, "! unknown");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (rec_type == RECTYPE_PRIMARY)
|
||||||
|
appendPQExpBuffer(&details, "! running");
|
||||||
|
else
|
||||||
|
appendPQExpBuffer(&details, "! running as standby");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* node is unreachable but marked active*/
|
||||||
|
if (cell->node_info->active == true)
|
||||||
|
appendPQExpBuffer(&details, "? unreachable");
|
||||||
|
else
|
||||||
|
appendPQExpBuffer(&details, "- failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case STANDBY:
|
||||||
|
{
|
||||||
|
/* node is reachable */
|
||||||
|
if (cell->node_info->node_status == NODE_STATUS_UP)
|
||||||
|
{
|
||||||
|
if (cell->node_info->active == true)
|
||||||
|
{
|
||||||
|
switch (rec_type)
|
||||||
|
{
|
||||||
|
case RECTYPE_STANDBY:
|
||||||
|
appendPQExpBuffer(&details, " running");
|
||||||
|
break;
|
||||||
|
case RECTYPE_PRIMARY:
|
||||||
|
appendPQExpBuffer(&details, "! running as primary");
|
||||||
|
break;
|
||||||
|
case RECTYPE_UNKNOWN:
|
||||||
|
appendPQExpBuffer(&details, "! unknown");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (rec_type == RECTYPE_STANDBY)
|
||||||
|
appendPQExpBuffer(&details, "! running");
|
||||||
|
else
|
||||||
|
appendPQExpBuffer(&details, "! running as primary");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* node is unreachable but marked active*/
|
||||||
|
if (cell->node_info->active == true)
|
||||||
|
appendPQExpBuffer(&details, "? unreachable");
|
||||||
|
else
|
||||||
|
appendPQExpBuffer(&details, "- failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BDR:
|
||||||
|
{
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case UNKNOWN:
|
||||||
|
{
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
strncpy(cell->node_info->details, details.data, MAXLEN);
|
||||||
|
termPQExpBuffer(&details);
|
||||||
|
|
||||||
PQfinish(cell->node_info->conn);
|
PQfinish(cell->node_info->conn);
|
||||||
|
|
||||||
headers_show[ROLE_HEADER].cur_length = strlen(cell->node_info->details);
|
headers_show[SHOW_ROLE].cur_length = strlen(get_node_type_string(cell->node_info->type));
|
||||||
headers_show[NAME_HEADER].cur_length = strlen(cell->node_info->node_name);
|
headers_show[SHOW_NAME].cur_length = strlen(cell->node_info->node_name);
|
||||||
headers_show[UPSTREAM_NAME_HEADER].cur_length = strlen(cell->node_info->upstream_node_name);
|
headers_show[SHOW_STATUS].cur_length = strlen(cell->node_info->details);
|
||||||
headers_show[CONNINFO_HEADER].cur_length = strlen(cell->node_info->conninfo);
|
headers_show[SHOW_UPSTREAM_NAME].cur_length = strlen(cell->node_info->upstream_node_name);
|
||||||
|
headers_show[SHOW_CONNINFO].cur_length = strlen(cell->node_info->conninfo);
|
||||||
|
|
||||||
for (i = 0; i < SHOW_HEADER_COUNT; i++)
|
for (i = 0; i < SHOW_HEADER_COUNT; i++)
|
||||||
{
|
{
|
||||||
@@ -166,10 +263,12 @@ do_cluster_show(void)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf( " %-*s ", headers_show[ROLE_HEADER].max_length, cell->node_info->details);
|
printf( " %-*i ", headers_show[SHOW_ID].max_length, cell->node_info->node_id);
|
||||||
printf("| %-*s ", headers_show[NAME_HEADER].max_length, cell->node_info->node_name);
|
printf("| %-*s ", headers_show[SHOW_NAME].max_length, cell->node_info->node_name);
|
||||||
printf("| %-*s ", headers_show[UPSTREAM_NAME_HEADER].max_length , cell->node_info->upstream_node_name);
|
printf("| %-*s ", headers_show[SHOW_ROLE].max_length, get_node_type_string(cell->node_info->type));
|
||||||
printf("| %-*s\n", headers_show[CONNINFO_HEADER].max_length, cell->node_info->conninfo);
|
printf("| %-*s ", headers_show[SHOW_STATUS].max_length, cell->node_info->details);
|
||||||
|
printf("| %-*s ", headers_show[SHOW_UPSTREAM_NAME].max_length , cell->node_info->upstream_node_name);
|
||||||
|
printf("| %-*s\n", headers_show[SHOW_CONNINFO].max_length, cell->node_info->conninfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user