mirror of
https://github.com/EnterpriseDB/repmgr.git
synced 2026-03-22 22:56:29 +00:00
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:
46
dbutils.c
46
dbutils.c
@@ -2933,8 +2933,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));
|
||||
}
|
||||
@@ -3671,7 +3670,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;
|
||||
@@ -3708,6 +3707,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 */
|
||||
/* ==================== */
|
||||
|
||||
@@ -453,7 +453,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);
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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"));
|
||||
|
||||
Reference in New Issue
Block a user