Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 488 lines (410 sloc) 12.608 kb
a12e719 Initial commit
postgres authored
1 /*
9b7a078 @gbartolini Added license information in every source file
gbartolini authored
2 * repmgrd.c - Replication manager daemon
3 * Copyright (C) 2ndQuadrant, 2010
a12e719 Initial commit
postgres authored
4 *
5 * This module connects to the nodes of a replication cluster and monitors
9843205 Reformat all source code using astyle
Greg Smith authored
6 * how far are they from master
7 *
9b7a078 @gbartolini Added license information in every source file
gbartolini authored
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20
a12e719 Initial commit
postgres authored
21 */
22
d1d1232 @Jaime2ndQuadrant Add signals to repmgrd and teach it to clean things up when
Jaime2ndQuadrant authored
23 #include <signal.h>
24
a12e719 Initial commit
postgres authored
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <unistd.h>
28
29 #include "repmgr.h"
2c1eafd @gbartolini first alpha version for syslog support
gbartolini authored
30 #include "config.h"
31 #include "log.h"
a12e719 Initial commit
postgres authored
32
d1d1232 @Jaime2ndQuadrant Add signals to repmgrd and teach it to clean things up when
Jaime2ndQuadrant authored
33 #include "libpq/pqsignal.h"
34
716a0ae @gbartolini removed any malloc operation, added t_runtime_options struct
gbartolini authored
35
a12e719 Initial commit
postgres authored
36 /* Local info */
716a0ae @gbartolini removed any malloc operation, added t_runtime_options struct
gbartolini authored
37 t_configuration_options local_options;
a12e719 Initial commit
postgres authored
38 int myLocalMode = STANDBY_MODE;
39 PGconn *myLocalConn;
40
41 /* Primary info */
716a0ae @gbartolini removed any malloc operation, added t_runtime_options struct
gbartolini authored
42 t_configuration_options primary_options;
a12e719 Initial commit
postgres authored
43 PGconn *primaryConn;
44
716a0ae @gbartolini removed any malloc operation, added t_runtime_options struct
gbartolini authored
45 char sqlquery[QUERY_STR_LEN];
a12e719 Initial commit
postgres authored
46
ae628d0 @Jaime2ndQuadrant Changes in repmgr are:
Jaime2ndQuadrant authored
47 const char *progname;
48
716a0ae @gbartolini removed any malloc operation, added t_runtime_options struct
gbartolini authored
49 char *config_file = DEFAULT_CONFIG_FILE;
3b8e818 @Jaime2ndQuadrant Changes when trying to compile:
Jaime2ndQuadrant authored
50 bool verbose = false;
3f1c6a5 @gbartolini Removed any sprintf/strcpy call and use snprintf/strncpy - Fixed bug …
gbartolini authored
51 char repmgr_schema[MAXLEN];
ae628d0 @Jaime2ndQuadrant Changes in repmgr are:
Jaime2ndQuadrant authored
52
814863e @trbs use struct for config file information
trbs authored
53 // should initialize with {0} to be ANSI complaint ? but this raises error with gcc -Wall
54 repmgr_config config = {};
ae628d0 @Jaime2ndQuadrant Changes in repmgr are:
Jaime2ndQuadrant authored
55
f6a6632 @gbartolini Added new log system to both repmgr and repmgrd. Needs cleaning, but …
gbartolini authored
56 static void help(const char* progname);
57 static void usage(void);
5cd9e39 @Jaime2ndQuadrant A few changes from repmgrd and improve the SQL of the repl_status
Jaime2ndQuadrant authored
58 static void checkClusterConfiguration(void);
59 static void checkNodeConfiguration(char *conninfo);
6168785 @Jaime2ndQuadrant improve documentation, also add CREATE DATABASE and CREATE USER
Jaime2ndQuadrant authored
60 static void CancelQuery(void);
a12e719 Initial commit
postgres authored
61
5cd9e39 @Jaime2ndQuadrant A few changes from repmgrd and improve the SQL of the repl_status
Jaime2ndQuadrant authored
62 static void MonitorExecute(void);
a12e719 Initial commit
postgres authored
63
5cd9e39 @Jaime2ndQuadrant A few changes from repmgrd and improve the SQL of the repl_status
Jaime2ndQuadrant authored
64 static unsigned long long int walLocationToBytes(char *wal_location);
7ec3485 Lag is now monitored in bytes, we show replication lag
postgres authored
65
d1d1232 @Jaime2ndQuadrant Add signals to repmgrd and teach it to clean things up when
Jaime2ndQuadrant authored
66 static void handle_sigint(SIGNAL_ARGS);
67 static void setup_cancel_handler(void);
68
69 #define CloseConnections() \
70 if (PQisBusy(primaryConn) == 1) \
71 CancelQuery(); \
72 if (myLocalConn != NULL) \
73 PQfinish(myLocalConn); \
74 if (primaryConn != NULL) \
75 PQfinish(primaryConn);
76
77 /*
78 * Every 3 seconds, insert monitor info
79 */
80 #define MonitorCheck() \
81 for (;;) \
82 { \
83 MonitorExecute(); \
84 sleep(3); \
9843205 Reformat all source code using astyle
Greg Smith authored
85 }
d1d1232 @Jaime2ndQuadrant Add signals to repmgrd and teach it to clean things up when
Jaime2ndQuadrant authored
86
a12e719 Initial commit
postgres authored
87
88 int
89 main(int argc, char **argv)
90 {
9843205 Reformat all source code using astyle
Greg Smith authored
91 static struct option long_options[] =
92 {
ae628d0 @Jaime2ndQuadrant Changes in repmgr are:
Jaime2ndQuadrant authored
93 {"config", required_argument, NULL, 'f'},
94 {"verbose", no_argument, NULL, 'v'},
95 {NULL, 0, NULL, 0}
96 };
97
98 int optindex;
99 int c;
100
d88783a @gbartolini Changed pg_version() prototype in order to remove the small memory leak
gbartolini authored
101 char standby_version[MAXVERSIONSTR];
a12e719 Initial commit
postgres authored
102
ae628d0 @Jaime2ndQuadrant Changes in repmgr are:
Jaime2ndQuadrant authored
103 progname = get_progname(argv[0]);
104
105 if (argc > 1)
106 {
107 if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
108 {
109 help(progname);
110 exit(0);
111 }
112 if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
113 {
114 printf("%s (PostgreSQL) " PG_VERSION "\n", progname);
115 exit(0);
116 }
117 }
118
119
120 while ((c = getopt_long(argc, argv, "f:v", long_options, &optindex)) != -1)
121 {
122 switch (c)
123 {
9843205 Reformat all source code using astyle
Greg Smith authored
124 case 'f':
125 config_file = optarg;
126 break;
127 case 'v':
128 verbose = true;
129 break;
130 default:
f6a6632 @gbartolini Added new log system to both repmgr and repmgrd. Needs cleaning, but …
gbartolini authored
131 usage();
9843205 Reformat all source code using astyle
Greg Smith authored
132 exit(1);
ae628d0 @Jaime2ndQuadrant Changes in repmgr are:
Jaime2ndQuadrant authored
133 }
134 }
d1d1232 @Jaime2ndQuadrant Add signals to repmgrd and teach it to clean things up when
Jaime2ndQuadrant authored
135
136 setup_cancel_handler();
9843205 Reformat all source code using astyle
Greg Smith authored
137
a12e719 Initial commit
postgres authored
138 /*
139 * Read the configuration file: repmgr.conf
9843205 Reformat all source code using astyle
Greg Smith authored
140 */
2c1eafd @gbartolini first alpha version for syslog support
gbartolini authored
141 parse_config(config_file, &local_options);
142 if (local_options.node == -1)
a12e719 Initial commit
postgres authored
143 {
f6a6632 @gbartolini Added new log system to both repmgr and repmgrd. Needs cleaning, but …
gbartolini authored
144 log_err("Node information is missing. "
9843205 Reformat all source code using astyle
Greg Smith authored
145 "Check the configuration file.\n");
a12e719 Initial commit
postgres authored
146 exit(1);
147 }
2c1eafd @gbartolini first alpha version for syslog support
gbartolini authored
148 logger_init(progname, local_options.loglevel, local_options.logfacility);
3f1c6a5 @gbartolini Removed any sprintf/strcpy call and use snprintf/strncpy - Fixed bug …
gbartolini authored
149 snprintf(repmgr_schema, MAXLEN, "%s%s", DEFAULT_REPMGR_SCHEMA_PREFIX, local_options.cluster_name);
a12e719 Initial commit
postgres authored
150
2c1eafd @gbartolini first alpha version for syslog support
gbartolini authored
151 myLocalConn = establishDBConnection(local_options.conninfo, true);
a12e719 Initial commit
postgres authored
152
219b443 @Jaime2ndQuadrant Replace the function is_supported_version() with the function pg_vers…
Jaime2ndQuadrant authored
153 /* should be v9 or better */
d88783a @gbartolini Changed pg_version() prototype in order to remove the small memory leak
gbartolini authored
154 pg_version(myLocalConn, standby_version);
219b443 @Jaime2ndQuadrant Replace the function is_supported_version() with the function pg_vers…
Jaime2ndQuadrant authored
155 if (strcmp(standby_version, "") == 0)
156 {
157 PQfinish(myLocalConn);
f6a6632 @gbartolini Added new log system to both repmgr and repmgrd. Needs cleaning, but …
gbartolini authored
158 log_err(_("%s needs standby to be PostgreSQL 9.0 or better\n"), progname);
219b443 @Jaime2ndQuadrant Replace the function is_supported_version() with the function pg_vers…
Jaime2ndQuadrant authored
159 exit(1);
160 }
161
9843205 Reformat all source code using astyle
Greg Smith authored
162 /*
163 * Set my server mode, establish a connection to primary
a12e719 Initial commit
postgres authored
164 * and start monitor
9843205 Reformat all source code using astyle
Greg Smith authored
165 */
9341771 Add docs, fix Makefile and fix some bugs and typos
postgres authored
166 myLocalMode = is_standby(myLocalConn) ? STANDBY_MODE : PRIMARY_MODE;
5cd9e39 @Jaime2ndQuadrant A few changes from repmgrd and improve the SQL of the repl_status
Jaime2ndQuadrant authored
167 if (myLocalMode == PRIMARY_MODE)
168 {
2c1eafd @gbartolini first alpha version for syslog support
gbartolini authored
169 primary_options.node = local_options.node;
716a0ae @gbartolini removed any malloc operation, added t_runtime_options struct
gbartolini authored
170 strncpy(primary_options.conninfo, local_options.conninfo, MAXLEN);
5cd9e39 @Jaime2ndQuadrant A few changes from repmgrd and improve the SQL of the repl_status
Jaime2ndQuadrant authored
171 primaryConn = myLocalConn;
172 }
6168785 @Jaime2ndQuadrant improve documentation, also add CREATE DATABASE and CREATE USER
Jaime2ndQuadrant authored
173 else
174 {
175 /* I need the id of the primary as well as a connection to it */
2c1eafd @gbartolini first alpha version for syslog support
gbartolini authored
176 primaryConn = getMasterConnection(myLocalConn, local_options.node, local_options.cluster_name, &primary_options.node);
378bdd7 @Jaime2ndQuadrant Add MASTER REGISTER and STANDBY REGISTER commands.
Jaime2ndQuadrant authored
177 if (primaryConn == NULL)
178 exit(1);
6168785 @Jaime2ndQuadrant improve documentation, also add CREATE DATABASE and CREATE USER
Jaime2ndQuadrant authored
179 }
5cd9e39 @Jaime2ndQuadrant A few changes from repmgrd and improve the SQL of the repl_status
Jaime2ndQuadrant authored
180
a12e719 Initial commit
postgres authored
181 checkClusterConfiguration();
2c1eafd @gbartolini first alpha version for syslog support
gbartolini authored
182 checkNodeConfiguration(local_options.conninfo);
a12e719 Initial commit
postgres authored
183 if (myLocalMode == STANDBY_MODE)
184 {
9843205 Reformat all source code using astyle
Greg Smith authored
185 MonitorCheck();
a12e719 Initial commit
postgres authored
186 }
187
9843205 Reformat all source code using astyle
Greg Smith authored
188 /* close the connection to the database and cleanup */
189 CloseConnections();
f6a6632 @gbartolini Added new log system to both repmgr and repmgrd. Needs cleaning, but …
gbartolini authored
190
191 /* Shuts down logging system */
192 logger_shutdown();
a12e719 Initial commit
postgres authored
193
9843205 Reformat all source code using astyle
Greg Smith authored
194 return 0;
a12e719 Initial commit
postgres authored
195 }
196
197
198 /*
d1d1232 @Jaime2ndQuadrant Add signals to repmgrd and teach it to clean things up when
Jaime2ndQuadrant authored
199 * Insert monitor info, this is basically the time and xlog replayed,
200 * applied on standby and current xlog location in primary.
201 * Also do the math to see how far are we in bytes for being uptodate
a12e719 Initial commit
postgres authored
202 */
5cd9e39 @Jaime2ndQuadrant A few changes from repmgrd and improve the SQL of the repl_status
Jaime2ndQuadrant authored
203 static void
a12e719 Initial commit
postgres authored
204 MonitorExecute(void)
205 {
9843205 Reformat all source code using astyle
Greg Smith authored
206 PGresult *res;
7ec3485 Lag is now monitored in bytes, we show replication lag
postgres authored
207 char monitor_standby_timestamp[MAXLEN];
208 char last_wal_primary_location[MAXLEN];
209 char last_wal_standby_received[MAXLEN];
210 char last_wal_standby_applied[MAXLEN];
211
212 unsigned long long int lsn_primary;
213 unsigned long long int lsn_standby_received;
214 unsigned long long int lsn_standby_applied;
215
508acf5 @Jaime2ndQuadrant Fix segmentation fault caused when trying to close a lost connection.
Jaime2ndQuadrant authored
216 int connection_retries;
217
9843205 Reformat all source code using astyle
Greg Smith authored
218 /*
219 * Check if the master is still available, if after 5 minutes of retries
220 * we cannot reconnect, try to get a new master.
508acf5 @Jaime2ndQuadrant Fix segmentation fault caused when trying to close a lost connection.
Jaime2ndQuadrant authored
221 */
3565fe1 @Jaime2ndQuadrant Implement Martin's suggestion about how much we should try to
Jaime2ndQuadrant authored
222 for (connection_retries = 0; connection_retries < 15; connection_retries++)
508acf5 @Jaime2ndQuadrant Fix segmentation fault caused when trying to close a lost connection.
Jaime2ndQuadrant authored
223 {
224 if (PQstatus(primaryConn) != CONNECTION_OK)
225 {
f6a6632 @gbartolini Added new log system to both repmgr and repmgrd. Needs cleaning, but …
gbartolini authored
226 log_warning(_("Connection to master has been lost, trying to recover..."));
3565fe1 @Jaime2ndQuadrant Implement Martin's suggestion about how much we should try to
Jaime2ndQuadrant authored
227 /* wait 20 seconds between retries */
228 sleep(20);
d9eee72 @Jaime2ndQuadrant Make repmgrd retry connection to current master 3 times (every 5 min),
Jaime2ndQuadrant authored
229
508acf5 @Jaime2ndQuadrant Fix segmentation fault caused when trying to close a lost connection.
Jaime2ndQuadrant authored
230 PQreset(primaryConn);
9843205 Reformat all source code using astyle
Greg Smith authored
231 }
508acf5 @Jaime2ndQuadrant Fix segmentation fault caused when trying to close a lost connection.
Jaime2ndQuadrant authored
232 else
d9eee72 @Jaime2ndQuadrant Make repmgrd retry connection to current master 3 times (every 5 min),
Jaime2ndQuadrant authored
233 {
f6a6632 @gbartolini Added new log system to both repmgr and repmgrd. Needs cleaning, but …
gbartolini authored
234 log_notice(_("Connection to master has been restored, continue monitoring."));
508acf5 @Jaime2ndQuadrant Fix segmentation fault caused when trying to close a lost connection.
Jaime2ndQuadrant authored
235 break;
d9eee72 @Jaime2ndQuadrant Make repmgrd retry connection to current master 3 times (every 5 min),
Jaime2ndQuadrant authored
236 }
508acf5 @Jaime2ndQuadrant Fix segmentation fault caused when trying to close a lost connection.
Jaime2ndQuadrant authored
237 }
3565fe1 @Jaime2ndQuadrant Implement Martin's suggestion about how much we should try to
Jaime2ndQuadrant authored
238 if (PQstatus(primaryConn) != CONNECTION_OK)
508acf5 @Jaime2ndQuadrant Fix segmentation fault caused when trying to close a lost connection.
Jaime2ndQuadrant authored
239 {
f6a6632 @gbartolini Added new log system to both repmgr and repmgrd. Needs cleaning, but …
gbartolini authored
240 log_err(_("We couldn't reconnect to master. Now checking if another node has been promoted."));
3565fe1 @Jaime2ndQuadrant Implement Martin's suggestion about how much we should try to
Jaime2ndQuadrant authored
241 for (connection_retries = 0; connection_retries < 6; connection_retries++)
d9eee72 @Jaime2ndQuadrant Make repmgrd retry connection to current master 3 times (every 5 min),
Jaime2ndQuadrant authored
242 {
2c1eafd @gbartolini first alpha version for syslog support
gbartolini authored
243 primaryConn = getMasterConnection(myLocalConn, local_options.node, local_options.cluster_name, &primary_options.node);
d9eee72 @Jaime2ndQuadrant Make repmgrd retry connection to current master 3 times (every 5 min),
Jaime2ndQuadrant authored
244 if (PQstatus(primaryConn) == CONNECTION_OK)
245 {
246 /* Connected, we can continue the process so break the loop */
f6a6632 @gbartolini Added new log system to both repmgr and repmgrd. Needs cleaning, but …
gbartolini authored
247 log_err(_("Connected to node %d, continue monitoring."), primary_options.node);
d9eee72 @Jaime2ndQuadrant Make repmgrd retry connection to current master 3 times (every 5 min),
Jaime2ndQuadrant authored
248 break;
249 }
250 else
251 {
f6a6632 @gbartolini Added new log system to both repmgr and repmgrd. Needs cleaning, but …
gbartolini authored
252 log_err(_("We haven't found a new master, waiting before retry..."));
3565fe1 @Jaime2ndQuadrant Implement Martin's suggestion about how much we should try to
Jaime2ndQuadrant authored
253 /* wait 5 minutes before retries, after 6 failures (30 minutes) we stop trying */
254 sleep(300);
d9eee72 @Jaime2ndQuadrant Make repmgrd retry connection to current master 3 times (every 5 min),
Jaime2ndQuadrant authored
255 }
256 }
508acf5 @Jaime2ndQuadrant Fix segmentation fault caused when trying to close a lost connection.
Jaime2ndQuadrant authored
257 }
b4d6966 @Jaime2ndQuadrant After 30 minutes of retry we are supposed to exit, so do that...
Jaime2ndQuadrant authored
258 if (PQstatus(primaryConn) != CONNECTION_OK)
259 {
f6a6632 @gbartolini Added new log system to both repmgr and repmgrd. Needs cleaning, but …
gbartolini authored
260 log_err(_("We couldn't reconnect for long enough, exiting..."));
b4d6966 @Jaime2ndQuadrant After 30 minutes of retry we are supposed to exit, so do that...
Jaime2ndQuadrant authored
261 exit(1);
262 }
508acf5 @Jaime2ndQuadrant Fix segmentation fault caused when trying to close a lost connection.
Jaime2ndQuadrant authored
263
264 /* Check if we still are a standby, we could have been promoted */
4641ddc @Jaime2ndQuadrant Teach repmgrd that if the node is promoted it should exit
Jaime2ndQuadrant authored
265 if (!is_standby(myLocalConn))
9843205 Reformat all source code using astyle
Greg Smith authored
266 {
f6a6632 @gbartolini Added new log system to both repmgr and repmgrd. Needs cleaning, but …
gbartolini authored
267 log_err(_("It seems like we have been promoted, so exit from monitoring..."));
4641ddc @Jaime2ndQuadrant Teach repmgrd that if the node is promoted it should exit
Jaime2ndQuadrant authored
268 CloseConnections();
269 exit(1);
270 }
271
9843205 Reformat all source code using astyle
Greg Smith authored
272 /*
d1d1232 @Jaime2ndQuadrant Add signals to repmgrd and teach it to clean things up when
Jaime2ndQuadrant authored
273 * first check if there is a command being executed,
274 * and if that is the case, cancel the query so i can
9843205 Reformat all source code using astyle
Greg Smith authored
275 * insert the current record
276 */
d1d1232 @Jaime2ndQuadrant Add signals to repmgrd and teach it to clean things up when
Jaime2ndQuadrant authored
277 if (PQisBusy(primaryConn) == 1)
278 CancelQuery();
279
7ec3485 Lag is now monitored in bytes, we show replication lag
postgres authored
280 /* Get local xlog info */
716a0ae @gbartolini removed any malloc operation, added t_runtime_options struct
gbartolini authored
281 snprintf(sqlquery, QUERY_STR_LEN,
9843205 Reformat all source code using astyle
Greg Smith authored
282 "SELECT CURRENT_TIMESTAMP, pg_last_xlog_receive_location(), "
283 "pg_last_xlog_replay_location()");
284
285 res = PQexec(myLocalConn, sqlquery);
286 if (PQresultStatus(res) != PGRES_TUPLES_OK)
287 {
f6a6632 @gbartolini Added new log system to both repmgr and repmgrd. Needs cleaning, but …
gbartolini authored
288 log_err("PQexec failed: %s\n", PQerrorMessage(myLocalConn));
9843205 Reformat all source code using astyle
Greg Smith authored
289 PQclear(res);
d1d1232 @Jaime2ndQuadrant Add signals to repmgrd and teach it to clean things up when
Jaime2ndQuadrant authored
290 /* if there is any error just let it be and retry in next loop */
9843205 Reformat all source code using astyle
Greg Smith authored
291 return;
292 }
a12e719 Initial commit
postgres authored
293
716a0ae @gbartolini removed any malloc operation, added t_runtime_options struct
gbartolini authored
294 strncpy(monitor_standby_timestamp, PQgetvalue(res, 0, 0), MAXLEN);
295 strncpy(last_wal_standby_received , PQgetvalue(res, 0, 1), MAXLEN);
296 strncpy(last_wal_standby_applied , PQgetvalue(res, 0, 2), MAXLEN);
9843205 Reformat all source code using astyle
Greg Smith authored
297 PQclear(res);
7ec3485 Lag is now monitored in bytes, we show replication lag
postgres authored
298
299 /* Get primary xlog info */
716a0ae @gbartolini removed any malloc operation, added t_runtime_options struct
gbartolini authored
300 snprintf(sqlquery, QUERY_STR_LEN, "SELECT pg_current_xlog_location() ");
7ec3485 Lag is now monitored in bytes, we show replication lag
postgres authored
301
9843205 Reformat all source code using astyle
Greg Smith authored
302 res = PQexec(primaryConn, sqlquery);
303 if (PQresultStatus(res) != PGRES_TUPLES_OK)
304 {
f6a6632 @gbartolini Added new log system to both repmgr and repmgrd. Needs cleaning, but …
gbartolini authored
305 log_err("PQexec failed: %s\n", PQerrorMessage(primaryConn));
9843205 Reformat all source code using astyle
Greg Smith authored
306 PQclear(res);
307 return;
308 }
7ec3485 Lag is now monitored in bytes, we show replication lag
postgres authored
309
716a0ae @gbartolini removed any malloc operation, added t_runtime_options struct
gbartolini authored
310 strncpy(last_wal_primary_location, PQgetvalue(res, 0, 0), MAXLEN);
9843205 Reformat all source code using astyle
Greg Smith authored
311 PQclear(res);
7ec3485 Lag is now monitored in bytes, we show replication lag
postgres authored
312
313 /* Calculate the lag */
314 lsn_primary = walLocationToBytes(last_wal_primary_location);
315 lsn_standby_received = walLocationToBytes(last_wal_standby_received);
316 lsn_standby_applied = walLocationToBytes(last_wal_standby_applied);
a12e719 Initial commit
postgres authored
317
318 /*
319 * Build the SQL to execute on primary
320 */
716a0ae @gbartolini removed any malloc operation, added t_runtime_options struct
gbartolini authored
321 snprintf(sqlquery,
3f1c6a5 @gbartolini Removed any sprintf/strcpy call and use snprintf/strncpy - Fixed bug …
gbartolini authored
322 QUERY_STR_LEN, "INSERT INTO %s.repl_monitor "
9843205 Reformat all source code using astyle
Greg Smith authored
323 "VALUES(%d, %d, '%s'::timestamp with time zone, "
324 " '%s', '%s', "
3f1c6a5 @gbartolini Removed any sprintf/strcpy call and use snprintf/strncpy - Fixed bug …
gbartolini authored
325 " %lld, %lld)", repmgr_schema,
2c1eafd @gbartolini first alpha version for syslog support
gbartolini authored
326 primary_options.node, local_options.node, monitor_standby_timestamp,
9843205 Reformat all source code using astyle
Greg Smith authored
327 last_wal_primary_location,
328 last_wal_standby_received,
329 (lsn_primary - lsn_standby_received),
330 (lsn_standby_received - lsn_standby_applied));
a12e719 Initial commit
postgres authored
331
332 /*
333 * Execute the query asynchronously, but don't check for a result. We
334 * will check the result next time we pause for a monitor step.
335 */
d1d1232 @Jaime2ndQuadrant Add signals to repmgrd and teach it to clean things up when
Jaime2ndQuadrant authored
336 if (PQsendQuery(primaryConn, sqlquery) == 0)
f6a6632 @gbartolini Added new log system to both repmgr and repmgrd. Needs cleaning, but …
gbartolini authored
337 log_warning("Query could not be sent to primary. %s\n",
9843205 Reformat all source code using astyle
Greg Smith authored
338 PQerrorMessage(primaryConn));
a12e719 Initial commit
postgres authored
339 }
340
341
5cd9e39 @Jaime2ndQuadrant A few changes from repmgrd and improve the SQL of the repl_status
Jaime2ndQuadrant authored
342 static void
a12e719 Initial commit
postgres authored
343 checkClusterConfiguration(void)
344 {
9843205 Reformat all source code using astyle
Greg Smith authored
345 PGresult *res;
a12e719 Initial commit
postgres authored
346
716a0ae @gbartolini removed any malloc operation, added t_runtime_options struct
gbartolini authored
347 snprintf(sqlquery, QUERY_STR_LEN, "SELECT oid FROM pg_class "
3f1c6a5 @gbartolini Removed any sprintf/strcpy call and use snprintf/strncpy - Fixed bug …
gbartolini authored
348 " WHERE oid = '%s.repl_nodes'::regclass",
349 repmgr_schema);
9843205 Reformat all source code using astyle
Greg Smith authored
350 res = PQexec(myLocalConn, sqlquery);
351 if (PQresultStatus(res) != PGRES_TUPLES_OK)
352 {
f6a6632 @gbartolini Added new log system to both repmgr and repmgrd. Needs cleaning, but …
gbartolini authored
353 log_err("PQexec failed: %s\n", PQerrorMessage(myLocalConn));
9843205 Reformat all source code using astyle
Greg Smith authored
354 PQclear(res);
355 PQfinish(myLocalConn);
356 PQfinish(primaryConn);
a12e719 Initial commit
postgres authored
357 exit(1);
9843205 Reformat all source code using astyle
Greg Smith authored
358 }
a12e719 Initial commit
postgres authored
359
360 /*
361 * If there isn't any results then we have not configured a primary node yet
362 * in repmgr or the connection string is pointing to the wrong database.
363 * XXX if we are the primary, should we try to create the tables needed?
364 */
365 if (PQntuples(res) == 0)
366 {
f6a6632 @gbartolini Added new log system to both repmgr and repmgrd. Needs cleaning, but …
gbartolini authored
367 log_err("The replication cluster is not configured\n");
9843205 Reformat all source code using astyle
Greg Smith authored
368 PQclear(res);
369 PQfinish(myLocalConn);
370 PQfinish(primaryConn);
a12e719 Initial commit
postgres authored
371 exit(1);
372 }
373 PQclear(res);
374 }
375
376
5cd9e39 @Jaime2ndQuadrant A few changes from repmgrd and improve the SQL of the repl_status
Jaime2ndQuadrant authored
377 static void
a12e719 Initial commit
postgres authored
378 checkNodeConfiguration(char *conninfo)
379 {
9843205 Reformat all source code using astyle
Greg Smith authored
380 PGresult *res;
a12e719 Initial commit
postgres authored
381
382 /*
383 * Check if we have my node information in repl_nodes
384 */
3f1c6a5 @gbartolini Removed any sprintf/strcpy call and use snprintf/strncpy - Fixed bug …
gbartolini authored
385 snprintf(sqlquery, QUERY_STR_LEN, "SELECT * FROM %s.repl_nodes "
9843205 Reformat all source code using astyle
Greg Smith authored
386 " WHERE id = %d AND cluster = '%s' ",
3f1c6a5 @gbartolini Removed any sprintf/strcpy call and use snprintf/strncpy - Fixed bug …
gbartolini authored
387 repmgr_schema, local_options.node, local_options.cluster_name);
9843205 Reformat all source code using astyle
Greg Smith authored
388
389 res = PQexec(myLocalConn, sqlquery);
390 if (PQresultStatus(res) != PGRES_TUPLES_OK)
391 {
f6a6632 @gbartolini Added new log system to both repmgr and repmgrd. Needs cleaning, but …
gbartolini authored
392 log_err("PQexec failed: %s\n", PQerrorMessage(myLocalConn));
9843205 Reformat all source code using astyle
Greg Smith authored
393 PQclear(res);
394 PQfinish(myLocalConn);
395 PQfinish(primaryConn);
a12e719 Initial commit
postgres authored
396 exit(1);
9843205 Reformat all source code using astyle
Greg Smith authored
397 }
a12e719 Initial commit
postgres authored
398
399 /*
400 * If there isn't any results then we have not configured this node yet
9843205 Reformat all source code using astyle
Greg Smith authored
401 * in repmgr, if that is the case we will insert the node to the cluster
a12e719 Initial commit
postgres authored
402 */
403 if (PQntuples(res) == 0)
404 {
9843205 Reformat all source code using astyle
Greg Smith authored
405 PQclear(res);
a12e719 Initial commit
postgres authored
406 /* Adding the node */
3f1c6a5 @gbartolini Removed any sprintf/strcpy call and use snprintf/strncpy - Fixed bug …
gbartolini authored
407 snprintf(sqlquery, QUERY_STR_LEN, "INSERT INTO %s.repl_nodes "
9843205 Reformat all source code using astyle
Greg Smith authored
408 "VALUES (%d, '%s', '%s')",
3f1c6a5 @gbartolini Removed any sprintf/strcpy call and use snprintf/strncpy - Fixed bug …
gbartolini authored
409 repmgr_schema, local_options.node, local_options.cluster_name, local_options.conninfo);
a12e719 Initial commit
postgres authored
410
9843205 Reformat all source code using astyle
Greg Smith authored
411 if (!PQexec(primaryConn, sqlquery))
a12e719 Initial commit
postgres authored
412 {
f6a6632 @gbartolini Added new log system to both repmgr and repmgrd. Needs cleaning, but …
gbartolini authored
413 log_err("Cannot insert node details, %s\n",
9843205 Reformat all source code using astyle
Greg Smith authored
414 PQerrorMessage(primaryConn));
a12e719 Initial commit
postgres authored
415 PQfinish(myLocalConn);
416 PQfinish(primaryConn);
417 exit(1);
418 }
419 }
420 PQclear(res);
421 }
7ec3485 Lag is now monitored in bytes, we show replication lag
postgres authored
422
423
9843205 Reformat all source code using astyle
Greg Smith authored
424 static unsigned long long int
7ec3485 Lag is now monitored in bytes, we show replication lag
postgres authored
425 walLocationToBytes(char *wal_location)
426 {
9843205 Reformat all source code using astyle
Greg Smith authored
427 unsigned int xlogid;
428 unsigned int xrecoff;
429
430 if (sscanf(wal_location, "%X/%X", &xlogid, &xrecoff) != 2)
431 {
f6a6632 @gbartolini Added new log system to both repmgr and repmgrd. Needs cleaning, but …
gbartolini authored
432 log_err("wrong log location format: %s\n", wal_location);
9843205 Reformat all source code using astyle
Greg Smith authored
433 return 0;
434 }
435 return ((xlogid * 16 * 1024 * 1024 * 255) + xrecoff);
7ec3485 Lag is now monitored in bytes, we show replication lag
postgres authored
436 }
3b8e818 @Jaime2ndQuadrant Changes when trying to compile:
Jaime2ndQuadrant authored
437
438
f6a6632 @gbartolini Added new log system to both repmgr and repmgrd. Needs cleaning, but …
gbartolini authored
439 void usage(void)
440 {
441 log_err(_("\n\n%s: Replicator manager daemon \n"), progname);
442 log_err(_("Try \"%s --help\" for more information.\n"), progname);
443 }
444
445 void help(const char *progname)
3b8e818 @Jaime2ndQuadrant Changes when trying to compile:
Jaime2ndQuadrant authored
446 {
9843205 Reformat all source code using astyle
Greg Smith authored
447 printf(_("\n%s: Replicator manager daemon \n"), progname);
448 printf(_("Usage:\n"));
449 printf(_(" %s [OPTIONS]\n"), progname);
450 printf(_("\nOptions:\n"));
3b8e818 @Jaime2ndQuadrant Changes when trying to compile:
Jaime2ndQuadrant authored
451 printf(_(" --help show this help, then exit\n"));
452 printf(_(" --version output version information, then exit\n"));
453 printf(_(" --verbose output verbose activity information\n"));
2c1eafd @gbartolini first alpha version for syslog support
gbartolini authored
454 printf(_(" -f, --config_file=PATH configuration file\n"));
9843205 Reformat all source code using astyle
Greg Smith authored
455 printf(_("\n%s monitors a cluster of servers.\n"), progname);
3b8e818 @Jaime2ndQuadrant Changes when trying to compile:
Jaime2ndQuadrant authored
456 }
d1d1232 @Jaime2ndQuadrant Add signals to repmgrd and teach it to clean things up when
Jaime2ndQuadrant authored
457
458
459
460 #ifndef WIN32
461 static void
462 handle_sigint(SIGNAL_ARGS)
463 {
9843205 Reformat all source code using astyle
Greg Smith authored
464 CloseConnections();
d1d1232 @Jaime2ndQuadrant Add signals to repmgrd and teach it to clean things up when
Jaime2ndQuadrant authored
465 }
466
467 static void
468 setup_cancel_handler(void)
469 {
9843205 Reformat all source code using astyle
Greg Smith authored
470 pqsignal(SIGINT, handle_sigint);
d1d1232 @Jaime2ndQuadrant Add signals to repmgrd and teach it to clean things up when
Jaime2ndQuadrant authored
471 }
472 #endif
473
474
475 static void
476 CancelQuery(void)
477 {
716a0ae @gbartolini removed any malloc operation, added t_runtime_options struct
gbartolini authored
478 char errbuf[ERRBUFF_SIZE];
9843205 Reformat all source code using astyle
Greg Smith authored
479 PGcancel *pgcancel;
d1d1232 @Jaime2ndQuadrant Add signals to repmgrd and teach it to clean things up when
Jaime2ndQuadrant authored
480
9843205 Reformat all source code using astyle
Greg Smith authored
481 pgcancel = PQgetCancel(primaryConn);
d1d1232 @Jaime2ndQuadrant Add signals to repmgrd and teach it to clean things up when
Jaime2ndQuadrant authored
482
716a0ae @gbartolini removed any malloc operation, added t_runtime_options struct
gbartolini authored
483 if (!pgcancel || PQcancel(pgcancel, errbuf, ERRBUFF_SIZE) == 0)
f6a6632 @gbartolini Added new log system to both repmgr and repmgrd. Needs cleaning, but …
gbartolini authored
484 log_warning("Can't stop current query: %s", errbuf);
d1d1232 @Jaime2ndQuadrant Add signals to repmgrd and teach it to clean things up when
Jaime2ndQuadrant authored
485
9843205 Reformat all source code using astyle
Greg Smith authored
486 PQfreeCancel(pgcancel);
d1d1232 @Jaime2ndQuadrant Add signals to repmgrd and teach it to clean things up when
Jaime2ndQuadrant authored
487 }
Something went wrong with that request. Please try again.