mirror of
https://github.com/EnterpriseDB/repmgr.git
synced 2026-03-23 07:06:30 +00:00
Refactor show diagnose to handle node IDs correctly.
See previous comments for `show matrix`.
This commit is contained in:
237
repmgr.c
237
repmgr.c
@@ -114,7 +114,7 @@ static void get_barman_property(char *dst, char *name, char *local_repmgr_direct
|
||||
static char *string_skip_prefix(const char *prefix, char *string);
|
||||
static char *string_remove_trailing_newlines(char *string);
|
||||
static int build_cluster_matrix(t_node_status_matrix *matrix, int *name_length);
|
||||
static int build_cluster_diagnose(int **cube, char **node_names, int *name_length);
|
||||
static int build_cluster_diagnose(t_node_status_cube ***cube, int *name_length);
|
||||
|
||||
static char *make_pg_path(char *file);
|
||||
static char *make_barman_ssh_command(void);
|
||||
@@ -164,6 +164,7 @@ static void config_file_list_init(t_configfile_list *list, int max_size);
|
||||
static void config_file_list_add(t_configfile_list *list, const char *file, const char *filename, bool in_data_dir);
|
||||
|
||||
static void matrix_set_node_status(t_node_status_matrix *matrix, int node_id, int connection_node_id, int connection_status);
|
||||
static void cube_set_node_status(t_node_status_cube **cube, int n, int node_id, int matrix_node_id, int connection_node_id, int connection_status);
|
||||
|
||||
/* Global variables */
|
||||
static PQconninfoOption *opts = NULL;
|
||||
@@ -1116,21 +1117,16 @@ static void
|
||||
matrix_set_node_status(t_node_status_matrix *matrix, int node_id, int connection_node_id, int connection_status)
|
||||
{
|
||||
int i, j;
|
||||
// printf("matrix_set_node_status() %i %i %i\n", node_id, connection_node_id, connection_status);
|
||||
|
||||
for (i = 0; i < matrix->length; i++)
|
||||
{
|
||||
// printf("xx %i\n", i);
|
||||
|
||||
if (matrix->matrix_list[i]->node_id == node_id)
|
||||
if (matrix->matrix_rec_list[i]->node_id == node_id)
|
||||
{
|
||||
for (j = 0; j < matrix->length; j++)
|
||||
{
|
||||
//XS printf(" xx %i\n", j);
|
||||
|
||||
if (matrix->matrix_list[i]->node_status_list[j]->node_id == connection_node_id)
|
||||
if (matrix->matrix_rec_list[i]->node_status_list[j]->node_id == connection_node_id)
|
||||
{
|
||||
matrix->matrix_list[i]->node_status_list[j]->node_status = connection_status;
|
||||
matrix->matrix_rec_list[i]->node_status_list[j]->node_status = connection_status;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1199,7 +1195,7 @@ build_cluster_matrix(t_node_status_matrix *matrix, int *name_length)
|
||||
|
||||
matrix->length = n;
|
||||
|
||||
matrix->matrix_list = (t_node_status_matrix_rec **) pg_malloc0(sizeof(t_node_status_matrix_rec) * n);
|
||||
matrix->matrix_rec_list = (t_node_status_matrix_rec **) pg_malloc0(sizeof(t_node_status_matrix_rec) * n);
|
||||
|
||||
|
||||
/* Initialise matrix structure for each node */
|
||||
@@ -1207,25 +1203,25 @@ build_cluster_matrix(t_node_status_matrix *matrix, int *name_length)
|
||||
{
|
||||
int name_length_cur;
|
||||
|
||||
matrix->matrix_list[i] = (t_node_status_matrix_rec *) pg_malloc0(sizeof(t_node_status_matrix_rec));
|
||||
matrix->matrix_rec_list[i] = (t_node_status_matrix_rec *) pg_malloc0(sizeof(t_node_status_matrix_rec));
|
||||
|
||||
matrix->matrix_list[i]->node_id = atoi(PQgetvalue(res, i, 4));
|
||||
strncpy(matrix->matrix_list[i]->node_name, PQgetvalue(res, i, 2), MAXLEN);
|
||||
matrix->matrix_rec_list[i]->node_id = atoi(PQgetvalue(res, i, 4));
|
||||
strncpy(matrix->matrix_rec_list[i]->node_name, PQgetvalue(res, i, 2), MAXLEN);
|
||||
|
||||
/*
|
||||
* Find the maximum length of a node name
|
||||
*/
|
||||
name_length_cur = strlen(matrix->matrix_list[i]->node_name);
|
||||
name_length_cur = strlen(matrix->matrix_rec_list[i]->node_name);
|
||||
if (name_length_cur > *name_length)
|
||||
*name_length = name_length_cur;
|
||||
|
||||
matrix->matrix_list[i]->node_status_list = (t_node_status_rec **) pg_malloc0(sizeof(t_node_status_rec) * n);
|
||||
matrix->matrix_rec_list[i]->node_status_list = (t_node_status_rec **) pg_malloc0(sizeof(t_node_status_rec) * n);
|
||||
|
||||
for (j = 0; j < n; j++)
|
||||
{
|
||||
matrix->matrix_list[i]->node_status_list[j] = (t_node_status_rec *) pg_malloc0(sizeof(t_node_status_rec));
|
||||
matrix->matrix_list[i]->node_status_list[j]->node_id = atoi(PQgetvalue(res, j, 4));
|
||||
matrix->matrix_list[i]->node_status_list[j]->node_status = -2; /* default unknown */
|
||||
matrix->matrix_rec_list[i]->node_status_list[j] = (t_node_status_rec *) pg_malloc0(sizeof(t_node_status_rec));
|
||||
matrix->matrix_rec_list[i]->node_status_list[j]->node_id = atoi(PQgetvalue(res, j, 4));
|
||||
matrix->matrix_rec_list[i]->node_status_list[j]->node_status = -2; /* default unknown */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1341,9 +1337,9 @@ do_cluster_matrix()
|
||||
const char *node_header = "Name";
|
||||
int name_length = strlen(node_header);
|
||||
|
||||
t_node_status_matrix *matrix_new = (t_node_status_matrix *) pg_malloc(sizeof(t_node_status_matrix));
|
||||
t_node_status_matrix *matrix = (t_node_status_matrix *) pg_malloc(sizeof(t_node_status_matrix));
|
||||
|
||||
n = build_cluster_matrix(matrix_new, &name_length);
|
||||
n = build_cluster_matrix(matrix, &name_length);
|
||||
|
||||
if (runtime_options.csv_mode)
|
||||
{
|
||||
@@ -1351,9 +1347,9 @@ do_cluster_matrix()
|
||||
for (i = 0; i < n; i++)
|
||||
for (j = 0; j < n; j++)
|
||||
printf("%d,%d,%d\n",
|
||||
matrix_new->matrix_list[i]->node_id,
|
||||
matrix_new->matrix_list[i]->node_status_list[j]->node_id,
|
||||
matrix_new->matrix_list[i]->node_status_list[j]->node_status);
|
||||
matrix->matrix_rec_list[i]->node_id,
|
||||
matrix->matrix_rec_list[i]->node_status_list[j]->node_id,
|
||||
matrix->matrix_rec_list[i]->node_status_list[j]->node_status);
|
||||
|
||||
}
|
||||
else
|
||||
@@ -1362,7 +1358,7 @@ do_cluster_matrix()
|
||||
|
||||
printf("%*s | Id ", name_length, node_header);
|
||||
for (i = 0; i < n; i++)
|
||||
printf("| %2d ", matrix_new->matrix_list[i]->node_id);
|
||||
printf("| %2d ", matrix->matrix_rec_list[i]->node_id);
|
||||
printf("\n");
|
||||
|
||||
for (i = 0; i < name_length; i++)
|
||||
@@ -1375,12 +1371,11 @@ do_cluster_matrix()
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
printf("%*s | %2d ", name_length,
|
||||
matrix_new->matrix_list[i]->node_name,
|
||||
matrix_new->matrix_list[i]->node_id);
|
||||
matrix->matrix_rec_list[i]->node_name,
|
||||
matrix->matrix_rec_list[i]->node_id);
|
||||
for (j = 0; j < n; j++)
|
||||
{
|
||||
//switch (matrix[i * n + j])
|
||||
switch (matrix_new->matrix_list[i]->node_status_list[j]->node_status)
|
||||
switch (matrix->matrix_rec_list[i]->node_status_list[j]->node_status)
|
||||
{
|
||||
case -2:
|
||||
c = '?';
|
||||
@@ -1402,19 +1397,47 @@ do_cluster_matrix()
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
cube_set_node_status(t_node_status_cube **cube, int n, int execute_node_id, int matrix_node_id, int connection_node_id, int connection_status)
|
||||
{
|
||||
int h, i, j;
|
||||
|
||||
|
||||
for (h = 0; h < n; h++)
|
||||
{
|
||||
if (cube[h]->node_id == execute_node_id)
|
||||
{
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
if (cube[h]->matrix_list_rec[i]->node_id == matrix_node_id)
|
||||
{
|
||||
for (j = 0; j < n; j++)
|
||||
{
|
||||
if (cube[h]->matrix_list_rec[i]->node_status_list[j]->node_id == connection_node_id)
|
||||
{
|
||||
cube[h]->matrix_list_rec[i]->node_status_list[j]->node_status = connection_status;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
build_cluster_diagnose(int **cube, char **node_names, int *name_length)
|
||||
build_cluster_diagnose(t_node_status_cube ***dest_cube, int *name_length)
|
||||
{
|
||||
PGconn *conn;
|
||||
PGresult *res;
|
||||
char sqlquery[QUERY_STR_LEN];
|
||||
int i, j;
|
||||
int h, i, j;
|
||||
|
||||
int x, y, z;
|
||||
int n = 0; /* number of nodes */
|
||||
|
||||
PQExpBufferData command;
|
||||
PQExpBufferData command_output;
|
||||
t_node_status_cube **cube;
|
||||
|
||||
/* We need to connect to get the list of nodes */
|
||||
log_info(_("connecting to database\n"));
|
||||
@@ -1442,41 +1465,52 @@ build_cluster_diagnose(int **cube, char **node_names, int *name_length)
|
||||
PQfinish(conn);
|
||||
|
||||
/*
|
||||
* Allocate an empty cube matrix
|
||||
* Allocate an empty cube matrix structure
|
||||
*
|
||||
* -2 == NULL
|
||||
* -1 == Error
|
||||
* 0 == OK
|
||||
*/
|
||||
n = PQntuples(res);
|
||||
*cube = (int *) pg_malloc(sizeof(int) * n * n * n);
|
||||
for (i = 0; i < n * n * n; i++)
|
||||
(*cube)[i] = -2;
|
||||
|
||||
/*
|
||||
* Find the maximum length of a node name
|
||||
*/
|
||||
for (i = 0; i < n; i++)
|
||||
cube = (t_node_status_cube **) pg_malloc(sizeof(t_node_status_cube *) * n);
|
||||
|
||||
for (h = 0; h < n; h++)
|
||||
{
|
||||
int name_length_cur;
|
||||
|
||||
name_length_cur = strlen(PQgetvalue(res, i, 2));
|
||||
cube[h] = (t_node_status_cube *) pg_malloc(sizeof(t_node_status_cube));
|
||||
cube[h]->node_id = atoi(PQgetvalue(res, h, 4));
|
||||
|
||||
strncpy(cube[h]->node_name, PQgetvalue(res, h, 2), MAXLEN);
|
||||
/*
|
||||
* Find the maximum length of a node name
|
||||
*/
|
||||
name_length_cur = strlen(cube[h]->node_name);
|
||||
if (name_length_cur > *name_length)
|
||||
*name_length = name_length_cur;
|
||||
|
||||
cube[h]->matrix_list_rec = (t_node_status_matrix_rec **) pg_malloc(sizeof(t_node_status_matrix_rec) * n);
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
cube[h]->matrix_list_rec[i] = (t_node_status_matrix_rec *) pg_malloc0(sizeof(t_node_status_matrix_rec));
|
||||
cube[h]->matrix_list_rec[i]->node_id = atoi(PQgetvalue(res, i, 4));
|
||||
|
||||
/* we don't need the name here */
|
||||
cube[h]->matrix_list_rec[i]->node_name[0] = '\0';
|
||||
|
||||
cube[h]->matrix_list_rec[i]->node_status_list = (t_node_status_rec **) pg_malloc0(sizeof(t_node_status_rec) * n);
|
||||
|
||||
for (j = 0; j < n; j++)
|
||||
{
|
||||
cube[h]->matrix_list_rec[i]->node_status_list[j] = (t_node_status_rec *) pg_malloc0(sizeof(t_node_status_rec));
|
||||
cube[h]->matrix_list_rec[i]->node_status_list[j]->node_id = atoi(PQgetvalue(res, j, 4));
|
||||
cube[h]->matrix_list_rec[i]->node_status_list[j]->node_status = -2; /* default unknown */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Save node names into an array
|
||||
*/
|
||||
|
||||
*node_names = (char *) pg_malloc((*name_length + 1) * n);
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
strncpy(*node_names + i * (*name_length + 1),
|
||||
PQgetvalue(res, i, 2),
|
||||
strlen(PQgetvalue(res, i, 2)) + 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Build the connection cube
|
||||
@@ -1484,8 +1518,11 @@ build_cluster_diagnose(int **cube, char **node_names, int *name_length)
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
char *p;
|
||||
int remote_node_id;
|
||||
PQExpBufferData command;
|
||||
PQExpBufferData command_output;
|
||||
|
||||
char *p;
|
||||
|
||||
remote_node_id = atoi(PQgetvalue(res, i, 4));
|
||||
|
||||
@@ -1498,7 +1535,6 @@ build_cluster_diagnose(int **cube, char **node_names, int *name_length)
|
||||
options.cluster_name,
|
||||
remote_node_id);
|
||||
|
||||
|
||||
if (strlen(pg_bindir))
|
||||
// XXX escape path!
|
||||
appendPQExpBuffer(&command,
|
||||
@@ -1506,11 +1542,11 @@ build_cluster_diagnose(int **cube, char **node_names, int *name_length)
|
||||
pg_bindir);
|
||||
|
||||
appendPQExpBuffer(&command,
|
||||
"cluster matrix --csv");
|
||||
"cluster matrix --csv 2>/dev/null");
|
||||
|
||||
initPQExpBuffer(&command_output);
|
||||
|
||||
if (i + 1 == options.node)
|
||||
if (cube[i]->node_id == options.node)
|
||||
{
|
||||
(void)local_command(
|
||||
command.data,
|
||||
@@ -1545,18 +1581,33 @@ build_cluster_diagnose(int **cube, char **node_names, int *name_length)
|
||||
|
||||
termPQExpBuffer("ed_command);
|
||||
}
|
||||
termPQExpBuffer(&command);
|
||||
|
||||
p = command_output.data;
|
||||
|
||||
if(!strlen(command_output.data))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (j = 0; j < n * n; j++)
|
||||
{
|
||||
if (sscanf(p, "%d,%d,%d", &x, &y, &z) != 3)
|
||||
int matrix_rec_node_id;
|
||||
int node_status_node_id;
|
||||
int node_status;
|
||||
|
||||
if (sscanf(p, "%d,%d,%d", &matrix_rec_node_id, &node_status_node_id, &node_status) != 3)
|
||||
{
|
||||
fprintf(stderr, _("cannot parse --csv output: %s\n"), p);
|
||||
exit(ERR_INTERNAL);
|
||||
}
|
||||
(*cube)[i * n * n + (x - 1) * n + (y - 1)] =
|
||||
(z == -1) ? -1 : 0;
|
||||
|
||||
cube_set_node_status(cube,
|
||||
n,
|
||||
remote_node_id,
|
||||
matrix_rec_node_id,
|
||||
node_status_node_id,
|
||||
node_status);
|
||||
|
||||
while (*p && (*p != '\n'))
|
||||
p++;
|
||||
if (*p == '\n')
|
||||
@@ -1564,23 +1615,23 @@ build_cluster_diagnose(int **cube, char **node_names, int *name_length)
|
||||
}
|
||||
}
|
||||
|
||||
PQclear(res);
|
||||
|
||||
*dest_cube = cube;
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
do_cluster_diagnose(void)
|
||||
{
|
||||
int i, j, k, u, v;
|
||||
int n;
|
||||
int i, n;
|
||||
char c;
|
||||
char *node_names;
|
||||
int *cube;
|
||||
const char *node_header = "Name";
|
||||
int name_length = strlen(node_header);
|
||||
|
||||
n = build_cluster_diagnose(&cube, &node_names, &name_length);
|
||||
t_node_status_cube **cube;
|
||||
|
||||
n = build_cluster_diagnose(&cube, &name_length);
|
||||
|
||||
printf("%*s | Id ", name_length, node_header);
|
||||
for (i = 0; i < n; i++)
|
||||
@@ -1596,13 +1647,17 @@ do_cluster_diagnose(void)
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
int column_node_ix;
|
||||
|
||||
printf("%*s | %2d ", name_length,
|
||||
node_names + (name_length + 1) * i, i + 1);
|
||||
for (j = 0; j < n; j++)
|
||||
cube[i]->node_name,
|
||||
cube[i]->node_id);
|
||||
|
||||
for (column_node_ix = 0; column_node_ix < n; column_node_ix++)
|
||||
{
|
||||
u = cube[i * n + j];
|
||||
for (k = 1; k < n; k++)
|
||||
{
|
||||
int max_node_status = -2;
|
||||
int node_ix;
|
||||
|
||||
/*
|
||||
* The value of entry (i,j) is equal to the
|
||||
* maximum value of all the (i,j,k). Indeed:
|
||||
@@ -1617,29 +1672,33 @@ do_cluster_diagnose(void)
|
||||
* (the node is in an unknown state).
|
||||
*/
|
||||
|
||||
v = cube[k * n * n + i * n + j];
|
||||
|
||||
if (v > u) u = v;
|
||||
for(node_ix = 0; node_ix < n; node_ix ++)
|
||||
{
|
||||
int node_status = cube[node_ix]->matrix_list_rec[i]->node_status_list[column_node_ix]->node_status;
|
||||
if (node_status > max_node_status)
|
||||
max_node_status = node_status;
|
||||
}
|
||||
|
||||
switch (u)
|
||||
switch (max_node_status)
|
||||
{
|
||||
case -2:
|
||||
c = '?';
|
||||
break;
|
||||
case -1:
|
||||
c = 'x';
|
||||
break;
|
||||
case 0:
|
||||
c = '*';
|
||||
break;
|
||||
default:
|
||||
exit(ERR_INTERNAL);
|
||||
case -2:
|
||||
c = '?';
|
||||
break;
|
||||
case -1:
|
||||
c = 'x';
|
||||
break;
|
||||
case 0:
|
||||
c = '*';
|
||||
break;
|
||||
default:
|
||||
exit(ERR_INTERNAL);
|
||||
}
|
||||
|
||||
printf("| %c ", c);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
22
repmgr.h
22
repmgr.h
@@ -165,6 +165,8 @@ typedef struct
|
||||
t_configfile_info **files;
|
||||
} t_configfile_list;
|
||||
|
||||
#define T_CONFIGFILE_LIST_INITIALIZER { 0, 0, NULL }
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -172,6 +174,8 @@ typedef struct
|
||||
int node_status;
|
||||
} t_node_status_rec;
|
||||
|
||||
// for each node, list of statuses for other nodes
|
||||
// output of "cluster show"
|
||||
typedef struct
|
||||
{
|
||||
int node_id;
|
||||
@@ -179,18 +183,22 @@ typedef struct
|
||||
t_node_status_rec **node_status_list;
|
||||
} t_node_status_matrix_rec;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int length;
|
||||
t_node_status_matrix_rec **matrix_list;
|
||||
} t_node_status_matrix;
|
||||
|
||||
|
||||
// points to the output of "cluster matrix" on each node
|
||||
typedef struct
|
||||
{
|
||||
int node_id;
|
||||
t_node_status_matrix **node_matrix;
|
||||
char node_name[MAXLEN];
|
||||
t_node_status_matrix_rec **matrix_list_rec;
|
||||
} t_node_status_cube;
|
||||
|
||||
|
||||
#define T_CONFIGFILE_LIST_INITIALIZER { 0, 0, NULL }
|
||||
// not really needed
|
||||
typedef struct
|
||||
{
|
||||
int length;
|
||||
t_node_status_matrix_rec **matrix_rec_list;
|
||||
} t_node_status_matrix;
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user