mirror of
https://github.com/EnterpriseDB/repmgr.git
synced 2026-03-26 16:46:28 +00:00
Removed any sprintf/strcpy call and use snprintf/strncpy - Fixed bug with tblspc_dir - added debug messages after every query
This commit is contained in:
committed by
Greg Smith
parent
716a0ae9d3
commit
3f1c6a5852
4
log.c
4
log.c
@@ -80,7 +80,9 @@ bool logger_init(const char* ident, const char* level, const char* facility)
|
|||||||
|
|
||||||
if (f == 0) {
|
if (f == 0) {
|
||||||
/* No syslog requested, just stderr */
|
/* No syslog requested, just stderr */
|
||||||
stderr_log_notice(_("Use stderr for logging\n"));
|
#ifdef REPMGR_DEBUG
|
||||||
|
printf(_("Use stderr for logging\n"));
|
||||||
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (f == -1) {
|
else if (f == -1) {
|
||||||
|
|||||||
156
repmgr.c
156
repmgr.c
@@ -62,6 +62,7 @@ static void usage(void);
|
|||||||
static const char *progname;
|
static const char *progname;
|
||||||
static const char *keywords[6];
|
static const char *keywords[6];
|
||||||
static const char *values[6];
|
static const char *values[6];
|
||||||
|
char repmgr_schema[MAXLEN];
|
||||||
|
|
||||||
/* Initialization of runtime options */
|
/* Initialization of runtime options */
|
||||||
t_runtime_options runtime_options = { "", "", "", "", "", "", DEFAULT_WAL_KEEP_SEGMENTS, false, false, "" };
|
t_runtime_options runtime_options = { "", "", "", "", "", "", DEFAULT_WAL_KEEP_SEGMENTS, false, false, "" };
|
||||||
@@ -276,6 +277,9 @@ main(int argc, char **argv)
|
|||||||
|
|
||||||
logger_init(progname, options.loglevel, options.logfacility);
|
logger_init(progname, options.loglevel, options.logfacility);
|
||||||
|
|
||||||
|
/* Prepare the repmgr schema variable */
|
||||||
|
snprintf(repmgr_schema, MAXLEN, "%s%s", DEFAULT_REPMGR_SCHEMA_PREFIX, options.cluster_name);
|
||||||
|
|
||||||
switch (action)
|
switch (action)
|
||||||
{
|
{
|
||||||
case MASTER_REGISTER:
|
case MASTER_REGISTER:
|
||||||
@@ -311,7 +315,7 @@ do_master_register(void)
|
|||||||
char sqlquery[QUERY_STR_LEN];
|
char sqlquery[QUERY_STR_LEN];
|
||||||
|
|
||||||
bool schema_exists = false;
|
bool schema_exists = false;
|
||||||
char master_version[MAXVERSIONSTR];
|
char master_version[MAXVERSIONSTR];
|
||||||
|
|
||||||
conn = establishDBConnection(options.conninfo, true);
|
conn = establishDBConnection(options.conninfo, true);
|
||||||
|
|
||||||
@@ -333,7 +337,8 @@ do_master_register(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Check if there is a schema for this cluster */
|
/* Check if there is a schema for this cluster */
|
||||||
sprintf(sqlquery, "SELECT 1 FROM pg_namespace WHERE nspname = 'repmgr_%s'", options.cluster_name);
|
snprintf(sqlquery, QUERY_STR_LEN, "SELECT 1 FROM pg_namespace WHERE nspname = '%s'", repmgr_schema);
|
||||||
|
log_debug("master register: %s\n", sqlquery);
|
||||||
res = PQexec(conn, sqlquery);
|
res = PQexec(conn, sqlquery);
|
||||||
if (PQresultStatus(res) != PGRES_TUPLES_OK)
|
if (PQresultStatus(res) != PGRES_TUPLES_OK)
|
||||||
{
|
{
|
||||||
@@ -347,7 +352,7 @@ do_master_register(void)
|
|||||||
{
|
{
|
||||||
if (!runtime_options.force) /* and we are not forcing so error */
|
if (!runtime_options.force) /* and we are not forcing so error */
|
||||||
{
|
{
|
||||||
log_notice(_("Schema repmgr_%s already exists.\n"), options.cluster_name);
|
log_notice(_("Schema %s already exists.\n"), repmgr_schema);
|
||||||
PQclear(res);
|
PQclear(res);
|
||||||
PQfinish(conn);
|
PQfinish(conn);
|
||||||
return;
|
return;
|
||||||
@@ -358,59 +363,65 @@ do_master_register(void)
|
|||||||
|
|
||||||
if (!schema_exists)
|
if (!schema_exists)
|
||||||
{
|
{
|
||||||
|
log_info("master register: creating database objects inside the %s schema", repmgr_schema);
|
||||||
|
|
||||||
/* ok, create the schema */
|
/* ok, create the schema */
|
||||||
sprintf(sqlquery, "CREATE SCHEMA repmgr_%s", options.cluster_name);
|
snprintf(sqlquery, QUERY_STR_LEN, "CREATE SCHEMA %s", repmgr_schema);
|
||||||
|
log_debug("master register: %s\n", sqlquery);
|
||||||
if (!PQexec(conn, sqlquery))
|
if (!PQexec(conn, sqlquery))
|
||||||
{
|
{
|
||||||
log_err(_("Cannot create the schema repmgr_%s: %s\n"),
|
log_err(_("Cannot create the schema %s: %s\n"),
|
||||||
options.cluster_name, PQerrorMessage(conn));
|
repmgr_schema, PQerrorMessage(conn));
|
||||||
PQfinish(conn);
|
PQfinish(conn);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ... the tables */
|
/* ... the tables */
|
||||||
sprintf(sqlquery, "CREATE TABLE repmgr_%s.repl_nodes ( "
|
snprintf(sqlquery, QUERY_STR_LEN, "CREATE TABLE %s.repl_nodes ( "
|
||||||
" id integer primary key, "
|
" id integer primary key, "
|
||||||
" cluster text not null, "
|
" cluster text not null, "
|
||||||
" conninfo text not null)", options.cluster_name);
|
" conninfo text not null)", repmgr_schema);
|
||||||
|
log_debug("master register: %s\n", sqlquery);
|
||||||
if (!PQexec(conn, sqlquery))
|
if (!PQexec(conn, sqlquery))
|
||||||
{
|
{
|
||||||
log_err(_("Cannot create the table repmgr_%s.repl_nodes: %s\n"),
|
log_err(_("Cannot create the table %s.repl_nodes: %s\n"),
|
||||||
options.cluster_name, PQerrorMessage(conn));
|
repmgr_schema, PQerrorMessage(conn));
|
||||||
PQfinish(conn);
|
PQfinish(conn);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf(sqlquery, "CREATE TABLE repmgr_%s.repl_monitor ( "
|
snprintf(sqlquery, QUERY_STR_LEN, "CREATE TABLE %s.repl_monitor ( "
|
||||||
" primary_node INTEGER NOT NULL, "
|
" primary_node INTEGER NOT NULL, "
|
||||||
" standby_node INTEGER NOT NULL, "
|
" standby_node INTEGER NOT NULL, "
|
||||||
" last_monitor_time TIMESTAMP WITH TIME ZONE NOT NULL, "
|
" last_monitor_time TIMESTAMP WITH TIME ZONE NOT NULL, "
|
||||||
" last_wal_primary_location TEXT NOT NULL, "
|
" last_wal_primary_location TEXT NOT NULL, "
|
||||||
" last_wal_standby_location TEXT NOT NULL, "
|
" last_wal_standby_location TEXT NOT NULL, "
|
||||||
" replication_lag BIGINT NOT NULL, "
|
" replication_lag BIGINT NOT NULL, "
|
||||||
" apply_lag BIGINT NOT NULL) ", options.cluster_name);
|
" apply_lag BIGINT NOT NULL) ", repmgr_schema);
|
||||||
|
log_debug("master register: %s\n", sqlquery);
|
||||||
if (!PQexec(conn, sqlquery))
|
if (!PQexec(conn, sqlquery))
|
||||||
{
|
{
|
||||||
log_err(_("Cannot create the table repmgr_%s.repl_monitor: %s\n"),
|
log_err(_("Cannot create the table %s.repl_monitor: %s\n"),
|
||||||
options.cluster_name, PQerrorMessage(conn));
|
repmgr_schema, PQerrorMessage(conn));
|
||||||
PQfinish(conn);
|
PQfinish(conn);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* and the view */
|
/* and the view */
|
||||||
sprintf(sqlquery, "CREATE VIEW repmgr_%s.repl_status AS "
|
snprintf(sqlquery, QUERY_STR_LEN, "CREATE VIEW %s.repl_status AS "
|
||||||
" WITH monitor_info AS (SELECT *, ROW_NUMBER() OVER (PARTITION BY primary_node, standby_node "
|
" WITH monitor_info AS (SELECT *, ROW_NUMBER() OVER (PARTITION BY primary_node, standby_node "
|
||||||
" ORDER BY last_monitor_time desc) "
|
" ORDER BY last_monitor_time desc) "
|
||||||
" FROM repmgr_%s.repl_monitor) "
|
" FROM %s.repl_monitor) "
|
||||||
" SELECT primary_node, standby_node, last_monitor_time, last_wal_primary_location, "
|
" SELECT primary_node, standby_node, last_monitor_time, last_wal_primary_location, "
|
||||||
" last_wal_standby_location, pg_size_pretty(replication_lag) replication_lag, "
|
" last_wal_standby_location, pg_size_pretty(replication_lag) replication_lag, "
|
||||||
" pg_size_pretty(apply_lag) apply_lag, age(now(), last_monitor_time) AS time_lag "
|
" pg_size_pretty(apply_lag) apply_lag, age(now(), last_monitor_time) AS time_lag "
|
||||||
" FROM monitor_info a "
|
" FROM monitor_info a "
|
||||||
" WHERE row_number = 1", options.cluster_name, options.cluster_name);
|
" WHERE row_number = 1", repmgr_schema, repmgr_schema);
|
||||||
|
log_debug("master register: %s\n", sqlquery);
|
||||||
if (!PQexec(conn, sqlquery))
|
if (!PQexec(conn, sqlquery))
|
||||||
{
|
{
|
||||||
log_err(_("Cannot create the view repmgr_%s.repl_status: %s\n"),
|
log_err(_("Cannot create the view %s.repl_status: %s\n"),
|
||||||
options.cluster_name, PQerrorMessage(conn));
|
repmgr_schema, PQerrorMessage(conn));
|
||||||
PQfinish(conn);
|
PQfinish(conn);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -433,9 +444,10 @@ do_master_register(void)
|
|||||||
/* Now register the master */
|
/* Now register the master */
|
||||||
if (runtime_options.force)
|
if (runtime_options.force)
|
||||||
{
|
{
|
||||||
sprintf(sqlquery, "DELETE FROM repmgr_%s.repl_nodes "
|
snprintf(sqlquery, QUERY_STR_LEN, "DELETE FROM %s.repl_nodes "
|
||||||
" WHERE id = %d",
|
" WHERE id = %d",
|
||||||
options.cluster_name, options.node);
|
repmgr_schema, options.node);
|
||||||
|
log_debug("master register: %s\n", sqlquery);
|
||||||
|
|
||||||
if (!PQexec(conn, sqlquery))
|
if (!PQexec(conn, sqlquery))
|
||||||
{
|
{
|
||||||
@@ -446,9 +458,10 @@ do_master_register(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf(sqlquery, "INSERT INTO repmgr_%s.repl_nodes "
|
snprintf(sqlquery, QUERY_STR_LEN, "INSERT INTO %s.repl_nodes "
|
||||||
"VALUES (%d, '%s', '%s')",
|
"VALUES (%d, '%s', '%s')",
|
||||||
options.cluster_name, options.node, options.cluster_name, options.conninfo);
|
repmgr_schema, options.node, options.cluster_name, options.conninfo);
|
||||||
|
log_debug("master register: %s\n", sqlquery);
|
||||||
|
|
||||||
if (!PQexec(conn, sqlquery))
|
if (!PQexec(conn, sqlquery))
|
||||||
{
|
{
|
||||||
@@ -498,7 +511,8 @@ do_standby_register(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Check if there is a schema for this cluster */
|
/* Check if there is a schema for this cluster */
|
||||||
sprintf(sqlquery, "SELECT 1 FROM pg_namespace WHERE nspname = 'repmgr_%s'", options.cluster_name);
|
snprintf(sqlquery, QUERY_STR_LEN, "SELECT 1 FROM pg_namespace WHERE nspname = '%s'", repmgr_schema);
|
||||||
|
log_debug("standby register: %s\n", sqlquery);
|
||||||
res = PQexec(conn, sqlquery);
|
res = PQexec(conn, sqlquery);
|
||||||
if (PQresultStatus(res) != PGRES_TUPLES_OK)
|
if (PQresultStatus(res) != PGRES_TUPLES_OK)
|
||||||
{
|
{
|
||||||
@@ -510,7 +524,7 @@ do_standby_register(void)
|
|||||||
|
|
||||||
if (PQntuples(res) == 0) /* schema doesn't exists */
|
if (PQntuples(res) == 0) /* schema doesn't exists */
|
||||||
{
|
{
|
||||||
log_err("Schema repmgr_%s doesn't exists.\n", options.cluster_name);
|
log_err("Schema %s doesn't exists.\n", repmgr_schema);
|
||||||
PQclear(res);
|
PQclear(res);
|
||||||
PQfinish(conn);
|
PQfinish(conn);
|
||||||
return;
|
return;
|
||||||
@@ -548,9 +562,10 @@ do_standby_register(void)
|
|||||||
/* Now register the standby */
|
/* Now register the standby */
|
||||||
if (runtime_options.force)
|
if (runtime_options.force)
|
||||||
{
|
{
|
||||||
sprintf(sqlquery, "DELETE FROM repmgr_%s.repl_nodes "
|
snprintf(sqlquery, QUERY_STR_LEN, "DELETE FROM %s.repl_nodes "
|
||||||
" WHERE id = %d",
|
" WHERE id = %d",
|
||||||
options.cluster_name, options.node);
|
repmgr_schema, options.node);
|
||||||
|
log_debug("standby register: %s\n", sqlquery);
|
||||||
|
|
||||||
if (!PQexec(master_conn, sqlquery))
|
if (!PQexec(master_conn, sqlquery))
|
||||||
{
|
{
|
||||||
@@ -562,10 +577,10 @@ do_standby_register(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf(sqlquery, "INSERT INTO repmgr_%s.repl_nodes "
|
snprintf(sqlquery, QUERY_STR_LEN, "INSERT INTO %s.repl_nodes "
|
||||||
"VALUES (%d, '%s', '%s')",
|
"VALUES (%d, '%s', '%s')",
|
||||||
options.cluster_name, options.node, options.cluster_name, options.conninfo);
|
repmgr_schema, options.node, options.cluster_name, options.conninfo);
|
||||||
log_debug("QUERY: %s\n", sqlquery);
|
log_debug("standby register: %s\n", sqlquery);
|
||||||
|
|
||||||
if (!PQexec(master_conn, sqlquery))
|
if (!PQexec(master_conn, sqlquery))
|
||||||
{
|
{
|
||||||
@@ -592,13 +607,14 @@ do_standby_clone(void)
|
|||||||
int r = 0;
|
int r = 0;
|
||||||
int i;
|
int i;
|
||||||
bool pg_dir = false;
|
bool pg_dir = false;
|
||||||
char master_data_directory[MAXLEN];
|
char master_data_directory[MAXFILENAME];
|
||||||
char master_config_file[MAXLEN];
|
char master_config_file[MAXFILENAME];
|
||||||
char master_hba_file[MAXLEN];
|
char master_hba_file[MAXFILENAME];
|
||||||
char master_ident_file[MAXLEN];
|
char master_ident_file[MAXFILENAME];
|
||||||
|
|
||||||
char master_control_file[MAXLEN];
|
char master_control_file[MAXFILENAME];
|
||||||
char local_control_file[MAXLEN];
|
char local_control_file[MAXFILENAME];
|
||||||
|
char tblspc_dir[MAXFILENAME];
|
||||||
|
|
||||||
const char *first_wal_segment = NULL;
|
const char *first_wal_segment = NULL;
|
||||||
const char *last_wal_segment = NULL;
|
const char *last_wal_segment = NULL;
|
||||||
@@ -721,7 +737,9 @@ do_standby_clone(void)
|
|||||||
log_info(_("Succesfully connected to primary. Current installation size is %s\n"), get_cluster_size(conn));
|
log_info(_("Succesfully connected to primary. Current installation size is %s\n"), get_cluster_size(conn));
|
||||||
|
|
||||||
/* Check if the tablespace locations exists and that we can write to them */
|
/* Check if the tablespace locations exists and that we can write to them */
|
||||||
sprintf(sqlquery, "select spclocation from pg_tablespace where spcname not in ('pg_default', 'pg_global')");
|
snprintf(sqlquery, QUERY_STR_LEN, "select spclocation from pg_tablespace where spcname not in ('pg_default', 'pg_global')");
|
||||||
|
log_debug("standby clone: %s\n", sqlquery);
|
||||||
|
|
||||||
res = PQexec(conn, sqlquery);
|
res = PQexec(conn, sqlquery);
|
||||||
if (PQresultStatus(res) != PGRES_TUPLES_OK)
|
if (PQresultStatus(res) != PGRES_TUPLES_OK)
|
||||||
{
|
{
|
||||||
@@ -732,9 +750,7 @@ do_standby_clone(void)
|
|||||||
}
|
}
|
||||||
for (i = 0; i < PQntuples(res); i++)
|
for (i = 0; i < PQntuples(res); i++)
|
||||||
{
|
{
|
||||||
char *tblspc_dir = NULL;
|
strncpy(tblspc_dir, PQgetvalue(res, i, 0), MAXFILENAME);
|
||||||
|
|
||||||
strcpy(tblspc_dir, PQgetvalue(res, i, 0));
|
|
||||||
/* Check this directory could be used as a PGDATA dir */
|
/* Check this directory could be used as a PGDATA dir */
|
||||||
switch (check_dir(tblspc_dir))
|
switch (check_dir(tblspc_dir))
|
||||||
{
|
{
|
||||||
@@ -793,9 +809,10 @@ do_standby_clone(void)
|
|||||||
log_notice("Starting backup...\n");
|
log_notice("Starting backup...\n");
|
||||||
|
|
||||||
/* Get the data directory full path and the configuration files location */
|
/* Get the data directory full path and the configuration files location */
|
||||||
sprintf(sqlquery, "SELECT name, setting "
|
snprintf(sqlquery, QUERY_STR_LEN, "SELECT name, setting "
|
||||||
" FROM pg_settings "
|
" FROM pg_settings "
|
||||||
" WHERE name IN ('data_directory', 'config_file', 'hba_file', 'ident_file')");
|
" WHERE name IN ('data_directory', 'config_file', 'hba_file', 'ident_file')");
|
||||||
|
log_debug("standby clone: %s\n", sqlquery);
|
||||||
res = PQexec(conn, sqlquery);
|
res = PQexec(conn, sqlquery);
|
||||||
if (PQresultStatus(res) != PGRES_TUPLES_OK)
|
if (PQresultStatus(res) != PGRES_TUPLES_OK)
|
||||||
{
|
{
|
||||||
@@ -807,13 +824,13 @@ do_standby_clone(void)
|
|||||||
for (i = 0; i < PQntuples(res); i++)
|
for (i = 0; i < PQntuples(res); i++)
|
||||||
{
|
{
|
||||||
if (strcmp(PQgetvalue(res, i, 0), "data_directory") == 0)
|
if (strcmp(PQgetvalue(res, i, 0), "data_directory") == 0)
|
||||||
strcpy(master_data_directory, PQgetvalue(res, i, 1));
|
strncpy(master_data_directory, PQgetvalue(res, i, 1), MAXFILENAME);
|
||||||
else if (strcmp(PQgetvalue(res, i, 0), "config_file") == 0)
|
else if (strcmp(PQgetvalue(res, i, 0), "config_file") == 0)
|
||||||
strcpy(master_config_file, PQgetvalue(res, i, 1));
|
strncpy(master_config_file, PQgetvalue(res, i, 1), MAXFILENAME);
|
||||||
else if (strcmp(PQgetvalue(res, i, 0), "hba_file") == 0)
|
else if (strcmp(PQgetvalue(res, i, 0), "hba_file") == 0)
|
||||||
strcpy(master_hba_file, PQgetvalue(res, i, 1));
|
strncpy(master_hba_file, PQgetvalue(res, i, 1), MAXFILENAME);
|
||||||
else if (strcmp(PQgetvalue(res, i, 0), "ident_file") == 0)
|
else if (strcmp(PQgetvalue(res, i, 0), "ident_file") == 0)
|
||||||
strcpy(master_ident_file, PQgetvalue(res, i, 1));
|
strncpy(master_ident_file, PQgetvalue(res, i, 1), MAXFILENAME);
|
||||||
else
|
else
|
||||||
log_warning(_("unknown parameter: %s\n"), PQgetvalue(res, i, 0));
|
log_warning(_("unknown parameter: %s\n"), PQgetvalue(res, i, 0));
|
||||||
}
|
}
|
||||||
@@ -823,7 +840,7 @@ do_standby_clone(void)
|
|||||||
* inform the master we will start a backup and get the first XLog filename
|
* inform the master we will start a backup and get the first XLog filename
|
||||||
* so we can say to the user we need those files
|
* so we can say to the user we need those files
|
||||||
*/
|
*/
|
||||||
sprintf(sqlquery, "SELECT pg_xlogfile_name(pg_start_backup('repmgr_standby_clone_%ld'))", time(NULL));
|
snprintf(sqlquery, QUERY_STR_LEN, "SELECT pg_xlogfile_name(pg_start_backup('repmgr_standby_clone_%ld'))", time(NULL));
|
||||||
log_debug("standby clone: %s\n", sqlquery);
|
log_debug("standby clone: %s\n", sqlquery);
|
||||||
|
|
||||||
res = PQexec(conn, sqlquery);
|
res = PQexec(conn, sqlquery);
|
||||||
@@ -851,8 +868,8 @@ do_standby_clone(void)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* need to create the global sub directory */
|
/* need to create the global sub directory */
|
||||||
sprintf(master_control_file, "%s/global/pg_control", master_data_directory);
|
snprintf(master_control_file, MAXFILENAME, "%s/global/pg_control", master_data_directory);
|
||||||
sprintf(local_control_file, "%s/global", runtime_options.dest_dir);
|
snprintf(local_control_file, MAXFILENAME, "%s/global", runtime_options.dest_dir);
|
||||||
if (!create_directory(local_control_file))
|
if (!create_directory(local_control_file))
|
||||||
{
|
{
|
||||||
log_err(_("%s: couldn't create directory %s ...\n"),
|
log_err(_("%s: couldn't create directory %s ...\n"),
|
||||||
@@ -872,7 +889,8 @@ do_standby_clone(void)
|
|||||||
* Copy tablespace locations, i'm doing this separately because i couldn't find and appropiate
|
* Copy tablespace locations, i'm doing this separately because i couldn't find and appropiate
|
||||||
* rsync option but besides we could someday make all these rsync happen concurrently
|
* rsync option but besides we could someday make all these rsync happen concurrently
|
||||||
*/
|
*/
|
||||||
sprintf(sqlquery, "select spclocation from pg_tablespace where spcname not in ('pg_default', 'pg_global')");
|
snprintf(sqlquery, QUERY_STR_LEN, "select spclocation from pg_tablespace where spcname not in ('pg_default', 'pg_global')");
|
||||||
|
log_debug("standby clone: %s\n", sqlquery);
|
||||||
res = PQexec(conn, sqlquery);
|
res = PQexec(conn, sqlquery);
|
||||||
if (PQresultStatus(res) != PGRES_TUPLES_OK)
|
if (PQresultStatus(res) != PGRES_TUPLES_OK)
|
||||||
{
|
{
|
||||||
@@ -911,7 +929,7 @@ stop_backup:
|
|||||||
|
|
||||||
log_notice("Finishing backup...\n");
|
log_notice("Finishing backup...\n");
|
||||||
|
|
||||||
sprintf(sqlquery, "SELECT pg_xlogfile_name(pg_stop_backup())");
|
snprintf(sqlquery, QUERY_STR_LEN, "SELECT pg_xlogfile_name(pg_stop_backup())");
|
||||||
log_debug("standby clone: %s\n", sqlquery);
|
log_debug("standby clone: %s\n", sqlquery);
|
||||||
|
|
||||||
res = PQexec(conn, sqlquery);
|
res = PQexec(conn, sqlquery);
|
||||||
@@ -935,7 +953,7 @@ stop_backup:
|
|||||||
progname, first_wal_segment, last_wal_segment);
|
progname, first_wal_segment, last_wal_segment);
|
||||||
|
|
||||||
/* we need to create the pg_xlog sub directory too, i'm reusing a variable here */
|
/* we need to create the pg_xlog sub directory too, i'm reusing a variable here */
|
||||||
sprintf(local_control_file, "%s/pg_xlog", runtime_options.dest_dir);
|
snprintf(local_control_file, MAXFILENAME, "%s/pg_xlog", runtime_options.dest_dir);
|
||||||
if (!create_directory(local_control_file))
|
if (!create_directory(local_control_file))
|
||||||
{
|
{
|
||||||
log_err(_("%s: couldn't create directory %s, you will need to do it manually...\n"),
|
log_err(_("%s: couldn't create directory %s, you will need to do it manually...\n"),
|
||||||
@@ -963,8 +981,8 @@ do_standby_promote(void)
|
|||||||
|
|
||||||
int r;
|
int r;
|
||||||
char data_dir[MAXLEN];
|
char data_dir[MAXLEN];
|
||||||
char recovery_file_path[MAXLEN];
|
char recovery_file_path[MAXFILENAME];
|
||||||
char recovery_done_path[MAXLEN];
|
char recovery_done_path[MAXFILENAME];
|
||||||
|
|
||||||
char standby_version[MAXVERSIONSTR];
|
char standby_version[MAXVERSIONSTR];
|
||||||
|
|
||||||
@@ -1000,8 +1018,9 @@ do_standby_promote(void)
|
|||||||
printf(_("\n%s: Promoting standby...\n"), progname);
|
printf(_("\n%s: Promoting standby...\n"), progname);
|
||||||
|
|
||||||
/* Get the data directory full path and the last subdirectory */
|
/* Get the data directory full path and the last subdirectory */
|
||||||
sprintf(sqlquery, "SELECT setting "
|
snprintf(sqlquery, QUERY_STR_LEN, "SELECT setting "
|
||||||
" FROM pg_settings WHERE name = 'data_directory'");
|
" FROM pg_settings WHERE name = 'data_directory'");
|
||||||
|
log_debug("standby promote: %s\n", sqlquery);
|
||||||
res = PQexec(conn, sqlquery);
|
res = PQexec(conn, sqlquery);
|
||||||
if (PQresultStatus(res) != PGRES_TUPLES_OK)
|
if (PQresultStatus(res) != PGRES_TUPLES_OK)
|
||||||
{
|
{
|
||||||
@@ -1014,12 +1033,12 @@ do_standby_promote(void)
|
|||||||
PQclear(res);
|
PQclear(res);
|
||||||
PQfinish(conn);
|
PQfinish(conn);
|
||||||
|
|
||||||
sprintf(recovery_file_path, "%s/%s", data_dir, RECOVERY_FILE);
|
snprintf(recovery_file_path, MAXFILENAME, "%s/%s", data_dir, RECOVERY_FILE);
|
||||||
sprintf(recovery_done_path, "%s/%s", data_dir, RECOVERY_DONE_FILE);
|
snprintf(recovery_done_path, MAXFILENAME, "%s/%s", data_dir, RECOVERY_DONE_FILE);
|
||||||
rename(recovery_file_path, recovery_done_path);
|
rename(recovery_file_path, recovery_done_path);
|
||||||
|
|
||||||
/* We assume the pg_ctl script is in the PATH */
|
/* We assume the pg_ctl script is in the PATH */
|
||||||
sprintf(script, "pg_ctl -D %s -m fast restart", data_dir);
|
snprintf(script, QUERY_STR_LEN, "pg_ctl -D %s -m fast restart", data_dir);
|
||||||
r = system(script);
|
r = system(script);
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
{
|
{
|
||||||
@@ -1129,8 +1148,9 @@ do_standby_follow(void)
|
|||||||
printf(_("\n%s: Changing standby's master...\n"), progname);
|
printf(_("\n%s: Changing standby's master...\n"), progname);
|
||||||
|
|
||||||
/* Get the data directory full path */
|
/* Get the data directory full path */
|
||||||
sprintf(sqlquery, "SELECT setting "
|
snprintf(sqlquery, QUERY_STR_LEN, "SELECT setting "
|
||||||
" FROM pg_settings WHERE name = 'data_directory'");
|
" FROM pg_settings WHERE name = 'data_directory'");
|
||||||
|
log_debug("standby follow: %s\n", sqlquery);
|
||||||
res = PQexec(conn, sqlquery);
|
res = PQexec(conn, sqlquery);
|
||||||
if (PQresultStatus(res) != PGRES_TUPLES_OK)
|
if (PQresultStatus(res) != PGRES_TUPLES_OK)
|
||||||
{
|
{
|
||||||
@@ -1149,7 +1169,7 @@ do_standby_follow(void)
|
|||||||
|
|
||||||
/* Finally, restart the service */
|
/* Finally, restart the service */
|
||||||
/* We assume the pg_ctl script is in the PATH */
|
/* We assume the pg_ctl script is in the PATH */
|
||||||
sprintf(script, "pg_ctl -D %s -m fast restart", data_dir);
|
snprintf(script, QUERY_STR_LEN, "pg_ctl -D %s -m fast restart", data_dir);
|
||||||
r = system(script);
|
r = system(script);
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
{
|
{
|
||||||
@@ -1205,10 +1225,10 @@ static bool
|
|||||||
create_recovery_file(const char *data_dir)
|
create_recovery_file(const char *data_dir)
|
||||||
{
|
{
|
||||||
FILE *recovery_file;
|
FILE *recovery_file;
|
||||||
char recovery_file_path[MAXLEN];
|
char recovery_file_path[MAXFILENAME];
|
||||||
char line[MAXLEN];
|
char line[MAXLEN];
|
||||||
|
|
||||||
sprintf(recovery_file_path, "%s/%s", data_dir, RECOVERY_FILE);
|
snprintf(recovery_file_path, MAXFILENAME, "%s/%s", data_dir, RECOVERY_FILE);
|
||||||
|
|
||||||
recovery_file = fopen(recovery_file_path, "w");
|
recovery_file = fopen(recovery_file_path, "w");
|
||||||
if (recovery_file == NULL)
|
if (recovery_file == NULL)
|
||||||
@@ -1217,7 +1237,7 @@ create_recovery_file(const char *data_dir)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf(line, "standby_mode = 'on'\n");
|
snprintf(line, MAXLEN, "standby_mode = 'on'\n");
|
||||||
if (fputs(line, recovery_file) == EOF)
|
if (fputs(line, recovery_file) == EOF)
|
||||||
{
|
{
|
||||||
log_err("recovery file could not be written, it could be necessary to create it manually\n");
|
log_err("recovery file could not be written, it could be necessary to create it manually\n");
|
||||||
@@ -1225,7 +1245,7 @@ create_recovery_file(const char *data_dir)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf(line, "primary_conninfo = 'host=%s port=%s'\n", runtime_options.host, runtime_options.masterport);
|
snprintf(line, MAXLEN, "primary_conninfo = 'host=%s port=%s'\n", runtime_options.host, runtime_options.masterport);
|
||||||
if (fputs(line, recovery_file) == EOF)
|
if (fputs(line, recovery_file) == EOF)
|
||||||
{
|
{
|
||||||
log_err("recovery file could not be written, it could be necessary to create it manually\n");
|
log_err("recovery file could not be written, it could be necessary to create it manually\n");
|
||||||
@@ -1249,7 +1269,7 @@ copy_remote_files(char *host, char *remote_user, char *remote_path, char *local_
|
|||||||
int r;
|
int r;
|
||||||
|
|
||||||
if (strnlen(runtime_options.rsync_options, QUERY_STR_LEN) == 0)
|
if (strnlen(runtime_options.rsync_options, QUERY_STR_LEN) == 0)
|
||||||
sprintf(options, "--archive --checksum --compress --progress --rsh=ssh");
|
snprintf(options, QUERY_STR_LEN, "--archive --checksum --compress --progress --rsh=ssh");
|
||||||
else
|
else
|
||||||
strncpy(options, runtime_options.rsync_options, QUERY_STR_LEN);
|
strncpy(options, runtime_options.rsync_options, QUERY_STR_LEN);
|
||||||
|
|
||||||
@@ -1258,22 +1278,22 @@ copy_remote_files(char *host, char *remote_user, char *remote_path, char *local_
|
|||||||
|
|
||||||
if (remote_user == NULL)
|
if (remote_user == NULL)
|
||||||
{
|
{
|
||||||
sprintf(host_string,"%s",host);
|
snprintf(host_string, QUERY_STR_LEN, "%s",host);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sprintf(host_string,"%s@%s",remote_user,host);
|
snprintf(host_string, QUERY_STR_LEN, "%s@%s",remote_user,host);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_directory)
|
if (is_directory)
|
||||||
{
|
{
|
||||||
strcat(options, " --exclude=pg_xlog* --exclude=pg_control --exclude=*.pid");
|
strcat(options, " --exclude=pg_xlog* --exclude=pg_control --exclude=*.pid");
|
||||||
sprintf(script, "rsync %s %s:%s/* %s",
|
snprintf(script, QUERY_STR_LEN, "rsync %s %s:%s/* %s",
|
||||||
options, host_string, remote_path, local_path);
|
options, host_string, remote_path, local_path);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sprintf(script, "rsync %s %s:%s %s/.",
|
snprintf(script, QUERY_STR_LEN, "rsync %s %s:%s %s/.",
|
||||||
options, host_string, remote_path, local_path);
|
options, host_string, remote_path, local_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
1
repmgr.h
1
repmgr.h
@@ -43,6 +43,7 @@
|
|||||||
#define DEFAULT_DEST_DIR "."
|
#define DEFAULT_DEST_DIR "."
|
||||||
#define DEFAULT_MASTER_PORT "5432"
|
#define DEFAULT_MASTER_PORT "5432"
|
||||||
#define DEFAULT_DBNAME "postgres"
|
#define DEFAULT_DBNAME "postgres"
|
||||||
|
#define DEFAULT_REPMGR_SCHEMA_PREFIX "repmgr_"
|
||||||
|
|
||||||
/* Run time options type */
|
/* Run time options type */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|||||||
18
repmgrd.c
18
repmgrd.c
@@ -48,6 +48,7 @@ const char *progname;
|
|||||||
|
|
||||||
char *config_file = DEFAULT_CONFIG_FILE;
|
char *config_file = DEFAULT_CONFIG_FILE;
|
||||||
bool verbose = false;
|
bool verbose = false;
|
||||||
|
char repmgr_schema[MAXLEN];
|
||||||
|
|
||||||
// should initialize with {0} to be ANSI complaint ? but this raises error with gcc -Wall
|
// should initialize with {0} to be ANSI complaint ? but this raises error with gcc -Wall
|
||||||
repmgr_config config = {};
|
repmgr_config config = {};
|
||||||
@@ -145,6 +146,7 @@ main(int argc, char **argv)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
logger_init(progname, local_options.loglevel, local_options.logfacility);
|
logger_init(progname, local_options.loglevel, local_options.logfacility);
|
||||||
|
snprintf(repmgr_schema, MAXLEN, "%s%s", DEFAULT_REPMGR_SCHEMA_PREFIX, local_options.cluster_name);
|
||||||
|
|
||||||
myLocalConn = establishDBConnection(local_options.conninfo, true);
|
myLocalConn = establishDBConnection(local_options.conninfo, true);
|
||||||
|
|
||||||
@@ -317,10 +319,10 @@ MonitorExecute(void)
|
|||||||
* Build the SQL to execute on primary
|
* Build the SQL to execute on primary
|
||||||
*/
|
*/
|
||||||
snprintf(sqlquery,
|
snprintf(sqlquery,
|
||||||
QUERY_STR_LEN, "INSERT INTO repmgr_%s.repl_monitor "
|
QUERY_STR_LEN, "INSERT INTO %s.repl_monitor "
|
||||||
"VALUES(%d, %d, '%s'::timestamp with time zone, "
|
"VALUES(%d, %d, '%s'::timestamp with time zone, "
|
||||||
" '%s', '%s', "
|
" '%s', '%s', "
|
||||||
" %lld, %lld)", local_options.cluster_name,
|
" %lld, %lld)", repmgr_schema,
|
||||||
primary_options.node, local_options.node, monitor_standby_timestamp,
|
primary_options.node, local_options.node, monitor_standby_timestamp,
|
||||||
last_wal_primary_location,
|
last_wal_primary_location,
|
||||||
last_wal_standby_received,
|
last_wal_standby_received,
|
||||||
@@ -343,8 +345,8 @@ checkClusterConfiguration(void)
|
|||||||
PGresult *res;
|
PGresult *res;
|
||||||
|
|
||||||
snprintf(sqlquery, QUERY_STR_LEN, "SELECT oid FROM pg_class "
|
snprintf(sqlquery, QUERY_STR_LEN, "SELECT oid FROM pg_class "
|
||||||
" WHERE oid = 'repmgr_%s.repl_nodes'::regclass",
|
" WHERE oid = '%s.repl_nodes'::regclass",
|
||||||
local_options.cluster_name);
|
repmgr_schema);
|
||||||
res = PQexec(myLocalConn, sqlquery);
|
res = PQexec(myLocalConn, sqlquery);
|
||||||
if (PQresultStatus(res) != PGRES_TUPLES_OK)
|
if (PQresultStatus(res) != PGRES_TUPLES_OK)
|
||||||
{
|
{
|
||||||
@@ -380,9 +382,9 @@ checkNodeConfiguration(char *conninfo)
|
|||||||
/*
|
/*
|
||||||
* Check if we have my node information in repl_nodes
|
* Check if we have my node information in repl_nodes
|
||||||
*/
|
*/
|
||||||
snprintf(sqlquery, QUERY_STR_LEN, "SELECT * FROM repmgr_%s.repl_nodes "
|
snprintf(sqlquery, QUERY_STR_LEN, "SELECT * FROM %s.repl_nodes "
|
||||||
" WHERE id = %d AND cluster = '%s' ",
|
" WHERE id = %d AND cluster = '%s' ",
|
||||||
local_options.cluster_name, local_options.node, local_options.cluster_name);
|
repmgr_schema, local_options.node, local_options.cluster_name);
|
||||||
|
|
||||||
res = PQexec(myLocalConn, sqlquery);
|
res = PQexec(myLocalConn, sqlquery);
|
||||||
if (PQresultStatus(res) != PGRES_TUPLES_OK)
|
if (PQresultStatus(res) != PGRES_TUPLES_OK)
|
||||||
@@ -402,9 +404,9 @@ checkNodeConfiguration(char *conninfo)
|
|||||||
{
|
{
|
||||||
PQclear(res);
|
PQclear(res);
|
||||||
/* Adding the node */
|
/* Adding the node */
|
||||||
snprintf(sqlquery, QUERY_STR_LEN, "INSERT INTO repmgr_%s.repl_nodes "
|
snprintf(sqlquery, QUERY_STR_LEN, "INSERT INTO %s.repl_nodes "
|
||||||
"VALUES (%d, '%s', '%s')",
|
"VALUES (%d, '%s', '%s')",
|
||||||
local_options.cluster_name, local_options.node, local_options.cluster_name, local_options.conninfo);
|
repmgr_schema, local_options.node, local_options.cluster_name, local_options.conninfo);
|
||||||
|
|
||||||
if (!PQexec(primaryConn, sqlquery))
|
if (!PQexec(primaryConn, sqlquery))
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user