node status: improve output and documentation

In the default text output mode, list inactive slots.

In CSV output mode, list inactive slots as additional information;
add output line with number of missing slots and a list thereof.

Also document --csv output mode.
This commit is contained in:
Ian Barwick
2018-06-22 11:44:56 +09:00
committed by Ian Barwick
parent f999c810a7
commit d26989bd12
5 changed files with 113 additions and 12 deletions

View File

@@ -2917,8 +2917,7 @@ get_datadir_configuration_files(PGconn *conn, KeyValueList *list)
for (i = 0; i < PQntuples(res); i++)
{
key_value_list_set(
list,
key_value_list_set(list,
PQgetvalue(res, i, 1),
PQgetvalue(res, i, 0));
}
@@ -3655,7 +3654,7 @@ get_slot_record(PGconn *conn, char *slot_name, t_replication_slot *record)
int
get_free_replication_slots(PGconn *conn)
get_free_replication_slot_count(PGconn *conn)
{
PQExpBufferData query;
PGresult *res = NULL;
@@ -3692,6 +3691,47 @@ get_free_replication_slots(PGconn *conn)
}
int
get_inactive_replication_slots(PGconn *conn, KeyValueList *list)
{
PQExpBufferData query;
PGresult *res = NULL;
int i, inactive_slots = 0;
initPQExpBuffer(&query);
appendPQExpBuffer(&query,
" SELECT slot_name, slot_type "
" FROM pg_catalog.pg_replication_slots "
" WHERE active IS FALSE "
" ORDER BY slot_name ");
res = PQexec(conn, query.data);
termPQExpBuffer(&query);
if (PQresultStatus(res) != PGRES_TUPLES_OK)
{
log_error(_("unable to execute replication slot query"));
log_detail("%s", PQerrorMessage(conn));
PQclear(res);
return -1;
}
inactive_slots = PQntuples(res);
for (i = 0; i < inactive_slots; i++)
{
key_value_list_set(list,
PQgetvalue(res, i, 0),
PQgetvalue(res, i, 1));
}
PQclear(res);
return inactive_slots;
}
/* ==================== */
/* tablespace functions */
/* ==================== */

View File

@@ -455,7 +455,8 @@ void create_slot_name(char *slot_name, int node_id);
bool create_replication_slot(PGconn *conn, char *slot_name, int server_version_num, PQExpBufferData *error_msg);
bool drop_replication_slot(PGconn *conn, char *slot_name);
RecordStatus get_slot_record(PGconn *conn, char *slot_name, t_replication_slot *record);
int get_free_replication_slots(PGconn *conn);
int get_free_replication_slot_count(PGconn *conn);
int get_inactive_replication_slots(PGconn *conn, KeyValueList *list);
/* tablespace functions */
bool get_tablespace_name_by_location(PGconn *conn, const char *location, char *name);

View File

@@ -24,7 +24,7 @@
<title>Example</title>
<para>
<programlisting>
$ repmgr -f /etc/repmgr.comf node status
$ repmgr -f /etc/repmgr.conf node status
Node "node1":
PostgreSQL version: 10beta1
Total data size: 30 MB
@@ -38,6 +38,20 @@
</para>
</refsect1>
<refsect1>
<title>Output format</title>
<para>
<itemizedlist spacing="compact" mark="bullet">
<listitem>
<simpara>
<literal>--csv</literal>: generate output in CSV format
</simpara>
</listitem>
</itemizedlist>
</para>
</refsect1>
<refsect1>
<title>See also</title>
<para>

View File

@@ -71,6 +71,7 @@ do_node_status(void)
KeyValueList node_status = {NULL, NULL};
KeyValueListCell *cell = NULL;
NodeInfoList missing_slots = T_NODE_INFO_LIST_INITIALIZER;
ItemList warnings = {NULL, NULL};
RecoveryType recovery_type = RECTYPE_UNKNOWN;
@@ -265,7 +266,6 @@ do_node_status(void)
else
{
PQExpBufferData slotinfo;
NodeInfoList missing_slots = T_NODE_INFO_LIST_INITIALIZER;
/*
* check for missing replication slots - we do this regardless of
@@ -305,6 +305,11 @@ do_node_status(void)
if (node_info.inactive_replication_slots > 0)
{
KeyValueList inactive_replication_slots = {NULL, NULL};
KeyValueListCell *cell = NULL;
(void) get_inactive_replication_slots(conn, &inactive_replication_slots);
appendPQExpBuffer(&slotinfo,
"; %i inactive",
node_info.inactive_replication_slots);
@@ -312,6 +317,14 @@ do_node_status(void)
item_list_append_format(&warnings,
_("- node has %i inactive replication slots"),
node_info.inactive_replication_slots);
for (cell = inactive_replication_slots.head; cell; cell = cell->next)
{
item_list_append_format(&warnings,
" - %s (%s)", cell->key, cell->value);
}
key_value_list_free(&inactive_replication_slots);
}
key_value_list_set(&node_status,
@@ -415,10 +428,44 @@ do_node_status(void)
"\"active_replication_slots\",%i\n",
node_info.active_replication_slots);
/* output inactive slot information */
appendPQExpBuffer(&output,
"\"inactive_replaction_slots\",%i\n",
"\"inactive_replication_slots\",%i",
node_info.inactive_replication_slots);
if (node_info.inactive_replication_slots)
{
KeyValueList inactive_replication_slots = {NULL, NULL};
KeyValueListCell *cell = NULL;
(void) get_inactive_replication_slots(conn, &inactive_replication_slots);
for (cell = inactive_replication_slots.head; cell; cell = cell->next)
{
appendPQExpBuffer(&output,
",\"%s\"", cell->key);
}
key_value_list_free(&inactive_replication_slots);
}
/* output missing slot information */
appendPQExpBuffer(&output, "\n");
appendPQExpBuffer(&output,
"\"missing_replication_slots\",%i",
missing_slots.node_count);
if (missing_slots.node_count > 0)
{
NodeInfoListCell *missing_slot_cell = NULL;
for (missing_slot_cell = missing_slots.head; missing_slot_cell; missing_slot_cell = missing_slot_cell->next)
{
appendPQExpBuffer(&output,
",\"%s\"", missing_slot_cell->node_info->slot_name);
}
}
}
else
{
@@ -439,12 +486,11 @@ do_node_status(void)
termPQExpBuffer(&output);
if (warnings.head != NULL && runtime_options.terse == false)
if (runtime_options.output_mode == OM_TEXT && warnings.head != NULL && runtime_options.terse == false)
{
log_warning(_("following issue(s) were detected:"));
print_item_list(&warnings);
/* add this when functionality implemented */
/* log_hint(_("execute \"repmgr node check\" for more details")); */
log_hint(_("execute \"repmgr node check\" for more details"));
}
key_value_list_free(&node_status);
@@ -1337,7 +1383,7 @@ do_node_check_replication_lag(PGconn *conn, OutputMode mode, t_node_info *node_i
return status;
}
/* TODO: ensure only runs on streaming replication nodes */
static CheckStatus
do_node_check_downstream(PGconn *conn, OutputMode mode, CheckStatusList *list_output)
{

View File

@@ -2257,7 +2257,7 @@ do_standby_follow(void)
if (config_file_options.use_replication_slots)
{
int free_slots = get_free_replication_slots(primary_conn);
int free_slots = get_free_replication_slot_count(primary_conn);
if (free_slots < 0)
{
log_error(_("unable to determine number of free replication slots on the primary"));