MASTER_CONNECTION refers to the connection to "master"
node. "Master" means the first live backend appearing in
pgpool.conf. The master node is determined at the time of fail over.
Unfortunately with both health check and fail_over_on_backend_error
are disabled, there's no chance of failover, which means the master
node id is remained the default value 0. So the MASTER_CONNECTION
refers to the node 0, and the connection is NULL.
Fix is as follows.
If attempt to connection to backend fails, check the master node id in
the shared memory. If the master node id is the failed node, then
look for new master node using get_next_master_node (this was a static
function, but now it's made to public) and set the node id to the
master node id in the shared memory area.
Problem reported by Muhammad Usama in [pgpool-hackers: 2905].
extern POOL_NODE_STATUS *verify_backend_node_status(POOL_CONNECTION_POOL_SLOT **slots);
extern POOL_NODE_STATUS *pool_get_node_status(void);
extern void pool_set_backend_status_changed_time(int backend_id);
+extern int get_next_master_node(void);
#endif /* POOL_H */
static void reload_config(void);
static int pool_pause(struct timeval *timeout);
static void kill_all_children(int sig);
-static int get_next_master_node(void);
static pid_t fork_follow_child(int old_master, int new_primary, int old_primary);
static int read_status_file(bool discard_status);
static RETSIGTYPE exit_handler(int sig);
* Calculate next valid master node id.
* If no valid node found, returns -1.
*/
-static int get_next_master_node(void)
+int get_next_master_node(void)
{
int i;
/* set down status to local status area */
*(my_backend_status[i]) = CON_DOWN;
+ /* if master_node_id is not updated, the update it */
+ if (Req_info->master_node_id == i)
+ {
+ int old_master = Req_info->master_node_id;
+ Req_info->master_node_id = get_next_master_node();
+
+ ereport(LOG,
+ (errmsg("master node %d is down. Update master node to %d",
+ old_master, Req_info->master_node_id)));
+ }
+
/* make sure that we need to restart the process after
* finishing this session
*/