When DROP DATABASE gets executed, SIGUSR1 is sent to the Pgpool-II
child process being issuing the command. In its SIGUSR1 handler,
MASTER macro is called while closing all idle connections. The MACRO
checks whether we are in failover process surely we are. As a result,
the process exits and DROP DATABASE command never been issued.
Per bug 486. However the reason of segfault in the report is not
clear. After commit:
https://git.postgresql.org/gitweb/?p=pgpool2.git;a=commit;h=
66b5aacfcc045ec1485921a5884b637fcfb6fd73
Things could be different. Let the user test the latest version in the
git repo and see if the problem is solved...
extern char remote_ps_data[]; /* used for set_ps_display */
extern volatile sig_atomic_t got_sighup;
extern volatile sig_atomic_t exit_request;
+extern volatile sig_atomic_t ignore_sigusr1;
#define QUERY_STRING_BUFFER_LEN 1024
extern char query_string_buffer[]; /* last query string sent to simpleQuery() */
static void child_will_go_down(int code, Datum arg);
static int opt_sort(const void *a, const void *b);
/*
- * non 0 means SIGTERM(smart shutdown) or SIGINT(fast shutdown) has arrived
+ * Non 0 means SIGTERM (smart shutdown) or SIGINT (fast shutdown) has arrived
*/
volatile sig_atomic_t exit_request = 0;
static volatile sig_atomic_t alarm_enabled = false;
+/*
+ * Ignore SIGUSR1 if requested. Used when DROP DATABASE is requested.
+ */
+volatile sig_atomic_t ignore_sigusr1 = 0;
static int idle; /* non 0 means this child is in idle state */
static int accepted = 0;
ConnectionInfo *info;
int save_errno = errno;
+ /*
+ * DROP DATABSE is ongoing.
+ */
+ if (ignore_sigusr1)
+ return;
+
#ifdef NOT_USED
ereport(DEBUG1,
(errmsg("close connection request received")));
*/
if (is_drop_database(node))
{
- int stime = 5; /* XXX give arbitrary time to allow closing idle connections */
+ struct timeval stime;
+ stime.tv_usec = 0;
+ stime.tv_sec = 5; /* XXX give arbitrary time to allow
+ * closing idle connections */
ereport(DEBUG1,
(errmsg("Query: sending SIGUSR1 signal to parent")));
+
+ ignore_sigusr1 = 1; /* disable SIGUSR1 handler */
register_node_operation_request(CLOSE_IDLE_REQUEST, NULL, 0);
- /* we need to loop over here since we will get USR1 signal while sleeping */
- while (stime > 0)
+ /*
+ * We need to loop over here since we might get some signals while
+ * sleeping
+ */
+ for (;;)
{
- stime = sleep(stime);
+ int sts;
+
+ errno = 0;
+ sts = select(0, NULL, NULL, NULL, &stime);
+ if (stime.tv_usec == 0 && stime.tv_sec == 0)
+ break;
+ if (sts != 0 && errno != EINTR)
+ {
+ elog(DEBUG1, "select(2) returns error: %s", strerror(errno));
+ break;
+ }
}
+
+ ignore_sigusr1 = 0;
}
/*