diff --git a/src/backend/access/transam/parallel.c b/src/backend/access/transam/parallel.c index 17b1038..f42034d 100644 --- a/src/backend/access/transam/parallel.c +++ b/src/backend/access/transam/parallel.c @@ -985,6 +985,8 @@ ParallelWorkerMain(Datum main_arg) error_queue_space = shm_toc_lookup(toc, PARALLEL_KEY_ERROR_QUEUE, false); mq = (shm_mq *) (error_queue_space + ParallelWorkerNumber * PARALLEL_ERROR_QUEUE_SIZE); + write_stderr("PID %d claiming queue %d (%p)\n", + MyProc->pid, ParallelWorkerNumber, mq); shm_mq_set_sender(mq, MyProc); mqh = shm_mq_attach(mq, seg, NULL); pq_redirect_to_shm_mq(seg, mqh); diff --git a/src/backend/postmaster/bgworker.c b/src/backend/postmaster/bgworker.c index 28af6f0..e393d31 100644 --- a/src/backend/postmaster/bgworker.c +++ b/src/backend/postmaster/bgworker.c @@ -219,14 +219,18 @@ FindRegisteredWorkerBySlotNumber(int slotno) { slist_iter siter; + /* elog(DEBUG1, "looking for slot-%d registration", slotno); */ slist_foreach(siter, &BackgroundWorkerList) { RegisteredBgWorker *rw; rw = slist_container(RegisteredBgWorker, rw_lnode, siter.cur); + elog(DEBUG1, "saw slot-%d registration, want %d", + rw->rw_shmem_slot, slotno); if (rw->rw_shmem_slot == slotno) return rw; } + /* elog(DEBUG1, "did not find slot-%d registration", slotno); */ return NULL; } @@ -297,6 +301,7 @@ BackgroundWorkerStateChange(void) } continue; } + elog(DEBUG1, "slot %d not yet registered", slotno); /* * If the worker is marked for termination, we don't need to add it to @@ -390,8 +395,8 @@ BackgroundWorkerStateChange(void) /* Log it! */ ereport(DEBUG1, - (errmsg("registering background worker \"%s\"", - rw->rw_worker.bgw_name))); + (errmsg("registering background worker \"%s\" (slot %d)", + rw->rw_worker.bgw_name, rw->rw_shmem_slot))); slist_push_head(&BackgroundWorkerList, &rw->rw_lnode); } @@ -422,8 +427,8 @@ ForgetBackgroundWorker(slist_mutable_iter *cur) slot->in_use = false; ereport(DEBUG1, - (errmsg("unregistering background worker \"%s\"", - rw->rw_worker.bgw_name))); + (errmsg("unregistering background worker \"%s\" (slot %d)", + rw->rw_worker.bgw_name, rw->rw_shmem_slot))); slist_delete_current(cur); free(rw); diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index 83e99b7..5fb5db1 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -561,6 +561,34 @@ int postmaster_alive_fds[2] = {-1, -1}; HANDLE PostmasterHandle; #endif +static bool siglevel = false; +static void sigforbid(const char *location) +{ + int save_errno; + + PG_SETMASK(&BlockSig); + + save_errno = errno; + elog(LOG, "forbid signals @ %s", location); + if (siglevel) + elog(WARNING, "signals already forbidden @ %s", location); + siglevel = true; + errno = save_errno; +} +static void sigpermit(const char *location) +{ + int save_errno; + + save_errno = errno; + elog(LOG, "permit signals @ %s", location); + if (!siglevel) + elog(WARNING, "signals already permitted @ %s", location); + siglevel = false; + errno = save_errno; + + PG_SETMASK(&UnBlockSig); +} + /* * Postmaster main entry point */ @@ -629,7 +657,7 @@ PostmasterMain(int argc, char *argv[]) * postmaster/checkpointer.c. */ pqinitmask(); - PG_SETMASK(&BlockSig); + sigforbid(__FUNCTION__); pqsignal_no_restart(SIGHUP, SIGHUP_handler); /* reread config file and * have children do same */ @@ -1686,12 +1714,12 @@ ServerLoop(void) if (pmState == PM_WAIT_DEAD_END) { - PG_SETMASK(&UnBlockSig); + sigpermit("PM_WAIT_DEAD_END"); pg_usleep(100000L); /* 100 msec seems reasonable */ selres = 0; - PG_SETMASK(&BlockSig); + sigforbid("PM_WAIT_DEAD_END"); } else { @@ -1701,11 +1729,11 @@ ServerLoop(void) /* Needs to run with blocked signals! */ DetermineSleepTime(&timeout); - PG_SETMASK(&UnBlockSig); + sigpermit("select"); selres = select(nSockets, &rmask, NULL, NULL, &timeout); - PG_SETMASK(&BlockSig); + sigforbid("select"); } /* Now check the select() result */ @@ -2507,7 +2535,7 @@ SIGHUP_handler(SIGNAL_ARGS) { int save_errno = errno; - PG_SETMASK(&BlockSig); + sigforbid(__FUNCTION__); if (Shutdown <= SmartShutdown) { @@ -2566,7 +2594,7 @@ SIGHUP_handler(SIGNAL_ARGS) #endif } - PG_SETMASK(&UnBlockSig); + sigpermit(__FUNCTION__); errno = save_errno; } @@ -2580,7 +2608,7 @@ pmdie(SIGNAL_ARGS) { int save_errno = errno; - PG_SETMASK(&BlockSig); + sigforbid(__FUNCTION__); ereport(DEBUG2, (errmsg_internal("postmaster received signal %d", @@ -2737,7 +2765,7 @@ pmdie(SIGNAL_ARGS) break; } - PG_SETMASK(&UnBlockSig); + sigpermit(__FUNCTION__); errno = save_errno; } @@ -2752,7 +2780,7 @@ reaper(SIGNAL_ARGS) int pid; /* process id of dead child process */ int exitstatus; /* its exit status */ - PG_SETMASK(&BlockSig); + sigforbid(__FUNCTION__); ereport(DEBUG4, (errmsg_internal("reaping dead processes"))); @@ -3051,7 +3079,7 @@ reaper(SIGNAL_ARGS) PostmasterStateMachine(); /* Done with signal handler */ - PG_SETMASK(&UnBlockSig); + sigpermit(__FUNCTION__); errno = save_errno; } @@ -4765,7 +4793,7 @@ SubPostmasterMain(int argc, char *argv[]) /* In EXEC_BACKEND case we will not have inherited these settings */ pqinitmask(); - PG_SETMASK(&BlockSig); + sigforbid(__FUNCTION__); /* Read in remaining GUC variables */ read_nondefault_variables(); @@ -4957,7 +4985,7 @@ sigusr1_handler(SIGNAL_ARGS) { int save_errno = errno; - PG_SETMASK(&BlockSig); + sigforbid(__FUNCTION__); /* Process background worker state change. */ if (CheckPostmasterSignal(PMSIGNAL_BACKGROUND_WORKER_CHANGE)) @@ -5091,7 +5119,7 @@ sigusr1_handler(SIGNAL_ARGS) signal_child(StartupPID, SIGUSR2); } - PG_SETMASK(&UnBlockSig); + sigpermit(__FUNCTION__); errno = save_errno; } @@ -5511,13 +5539,13 @@ BackgroundWorkerInitializeConnectionByOid(Oid dboid, Oid useroid) void BackgroundWorkerBlockSignals(void) { - PG_SETMASK(&BlockSig); + sigforbid(__FUNCTION__); } void BackgroundWorkerUnblockSignals(void) { - PG_SETMASK(&UnBlockSig); + sigpermit(__FUNCTION__); } #ifdef EXEC_BACKEND diff --git a/src/backend/utils/error/assert.c b/src/backend/utils/error/assert.c index 2ef7792..9f4e597 100644 --- a/src/backend/utils/error/assert.c +++ b/src/backend/utils/error/assert.c @@ -42,6 +42,8 @@ ExceptionalCondition(const char *conditionName, /* Usually this shouldn't be needed, but make sure the msg went out */ fflush(stderr); + for(;;); + #ifdef SLEEP_ON_ASSERT /* diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c index 918db0a..e0ef9ec 100644 --- a/src/backend/utils/error/elog.c +++ b/src/backend/utils/error/elog.c @@ -554,6 +554,7 @@ errfinish(int dummy,...) */ fflush(stdout); fflush(stderr); + for(;;); abort(); } diff --git a/src/test/regress/expected/small_parallel.out b/src/test/regress/expected/small_parallel.out new file mode 100644 index 0000000..a17ed33 --- /dev/null +++ b/src/test/regress/expected/small_parallel.out @@ -0,0 +1,44 @@ +-- Serializable isolation would disable parallel query, so explicitly use an +-- arbitrary other level. +begin isolation level repeatable read; +-- encourage use of parallel plans +set parallel_setup_cost=0; +set parallel_tuple_cost=0; +set min_parallel_table_scan_size=0; +set max_parallel_workers_per_gather=4; +-- test parallel bitmap heap scan. +set enable_seqscan to off; +set enable_indexscan to off; +set enable_hashjoin to off; +set enable_mergejoin to off; +set enable_material to off; +-- test prefetching, if the platform allows it +DO $$ +BEGIN + SET effective_io_concurrency = 50; +EXCEPTION WHEN invalid_parameter_value THEN +END $$; +set work_mem='64kB'; --set small work mem to force lossy pages +explain (costs off) + select count(*) from tenk1, tenk2 where tenk1.hundred > 1 and tenk2.thousand=0; + QUERY PLAN +------------------------------------------------------------ + Aggregate + -> Nested Loop + -> Seq Scan on tenk2 + Filter: (thousand = 0) + -> Gather + Workers Planned: 4 + -> Parallel Bitmap Heap Scan on tenk1 + Recheck Cond: (hundred > 1) + -> Bitmap Index Scan on tenk1_hundred + Index Cond: (hundred > 1) +(10 rows) + +select count(*) from tenk1, tenk2 where tenk1.hundred > 1 and tenk2.thousand=0; + count +------- + 98000 +(1 row) + +rollback; diff --git a/src/test/regress/sql/small_parallel.sql b/src/test/regress/sql/small_parallel.sql new file mode 100644 index 0000000..1598d2e --- /dev/null +++ b/src/test/regress/sql/small_parallel.sql @@ -0,0 +1,28 @@ +-- Serializable isolation would disable parallel query, so explicitly use an +-- arbitrary other level. +begin isolation level repeatable read; + +-- encourage use of parallel plans +set parallel_setup_cost=0; +set parallel_tuple_cost=0; +set min_parallel_table_scan_size=0; +set max_parallel_workers_per_gather=4; + +-- test parallel bitmap heap scan. +set enable_seqscan to off; +set enable_indexscan to off; +set enable_hashjoin to off; +set enable_mergejoin to off; +set enable_material to off; +-- test prefetching, if the platform allows it +DO $$ +BEGIN + SET effective_io_concurrency = 50; +EXCEPTION WHEN invalid_parameter_value THEN +END $$; +set work_mem='64kB'; --set small work mem to force lossy pages +explain (costs off) + select count(*) from tenk1, tenk2 where tenk1.hundred > 1 and tenk2.thousand=0; +select count(*) from tenk1, tenk2 where tenk1.hundred > 1 and tenk2.thousand=0; + +rollback;