From 45444b3362e8d00e998fae195023b8a55d96a005 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Tue, 30 May 2017 22:59:19 -0400 Subject: [PATCH] Split background worker name into type and name Remove background worker structure field bgw_name and add two new fields bgw_type and bgw_name_extra. The bgw_type field is intended to be set to the same value for all workers of the same type, so they can be grouped in pg_stat_activity, for example. The bgw_name_extra field can be any suffix that is specific to the individual worker. So bgw_type + bgw_name_extra is the old bgw_name. The backend_type column in pg_stat_activity now shows bgw_type for a background worker. The ps listing and some log messages no longer call out that a process is a "background worker" but just show the bgw_type. That way, being a background worker is effectively an implementation detail now that is not shown to the user. Don't set application_name in logical replication launcher or worker anymore. Those processes can now be identified using the mechanisms described above instead. --- doc/src/sgml/bgworker.sgml | 17 +++++++++--- src/backend/access/transam/parallel.c | 3 ++- src/backend/postmaster/bgworker.c | 42 ++++++++++++++++-------------- src/backend/postmaster/postmaster.c | 16 +++++------- src/backend/replication/logical/launcher.c | 15 +++++------ src/backend/replication/logical/worker.c | 4 --- src/backend/utils/adt/pgstatfuncs.c | 29 +++++++++++++++++++-- src/include/postmaster/bgworker.h | 3 ++- src/test/modules/test_shm_mq/setup.c | 2 +- src/test/modules/worker_spi/worker_spi.c | 17 +++++++----- 10 files changed, 92 insertions(+), 56 deletions(-) diff --git a/doc/src/sgml/bgworker.sgml b/doc/src/sgml/bgworker.sgml index b422323081..0a89a5044b 100644 --- a/doc/src/sgml/bgworker.sgml +++ b/doc/src/sgml/bgworker.sgml @@ -50,7 +50,8 @@ Background Worker Processes typedef void (*bgworker_main_type)(Datum main_arg); typedef struct BackgroundWorker { - char bgw_name[BGW_MAXLEN]; + char bgw_type[BGW_MAXLEN]; + char bgw_name_extra[BGW_MAXLEN]; int bgw_flags; BgWorkerStartTime bgw_start_time; int bgw_restart_time; /* in seconds, or BGW_NEVER_RESTART */ @@ -64,8 +65,18 @@ Background Worker Processes - bgw_name is a string to be used in log messages, process - listings and similar contexts. + bgw_type is a string to be used in log messages, process + listings and similar contexts. It should be the same for all background + workers of the same type, so that it is possible to group such workers in a + process listing, for example. + + + + bgw_name_extra is a string that is appended + to bgw_type in some contexts such as process + listings. Unlike bgw_type, it can contain + information that is particular to this process. The string, if not empty, + should normally start with a space or other separator. diff --git a/src/backend/access/transam/parallel.c b/src/backend/access/transam/parallel.c index 2dad3e8a65..fbdcf2da31 100644 --- a/src/backend/access/transam/parallel.c +++ b/src/backend/access/transam/parallel.c @@ -436,7 +436,8 @@ LaunchParallelWorkers(ParallelContext *pcxt) /* Configure a worker. */ memset(&worker, 0, sizeof(worker)); - snprintf(worker.bgw_name, BGW_MAXLEN, "parallel worker for PID %d", + snprintf(worker.bgw_type, BGW_MAXLEN, "parallel worker"); + snprintf(worker.bgw_name_extra, BGW_MAXLEN, " for PID %d", MyProcPid); worker.bgw_flags = BGWORKER_SHMEM_ACCESS | BGWORKER_BACKEND_DATABASE_CONNECTION diff --git a/src/backend/postmaster/bgworker.c b/src/backend/postmaster/bgworker.c index c3454276bf..65318a5fb8 100644 --- a/src/backend/postmaster/bgworker.c +++ b/src/backend/postmaster/bgworker.c @@ -342,8 +342,10 @@ BackgroundWorkerStateChange(void) * Copy strings in a paranoid way. If shared memory is corrupted, the * source data might not even be NUL-terminated. */ - ascii_safe_strlcpy(rw->rw_worker.bgw_name, - slot->worker.bgw_name, BGW_MAXLEN); + ascii_safe_strlcpy(rw->rw_worker.bgw_type, + slot->worker.bgw_type, BGW_MAXLEN); + ascii_safe_strlcpy(rw->rw_worker.bgw_name_extra, + slot->worker.bgw_name_extra, BGW_MAXLEN); ascii_safe_strlcpy(rw->rw_worker.bgw_library_name, slot->worker.bgw_library_name, BGW_MAXLEN); ascii_safe_strlcpy(rw->rw_worker.bgw_function_name, @@ -389,9 +391,10 @@ BackgroundWorkerStateChange(void) rw->rw_terminate = false; /* Log it! */ - ereport(DEBUG1, - (errmsg("registering background worker \"%s\"", - rw->rw_worker.bgw_name))); + elog(DEBUG1, + "registering background worker \"%s%s\"", + rw->rw_worker.bgw_type, + rw->rw_worker.bgw_name_extra); slist_push_head(&BackgroundWorkerList, &rw->rw_lnode); } @@ -421,9 +424,10 @@ ForgetBackgroundWorker(slist_mutable_iter *cur) slot->in_use = false; - ereport(DEBUG1, - (errmsg("unregistering background worker \"%s\"", - rw->rw_worker.bgw_name))); + elog(DEBUG1, + "unregistering background worker \"%s%s\"", + rw->rw_worker.bgw_type, + rw->rw_worker.bgw_name_extra); slist_delete_current(cur); free(rw); @@ -588,7 +592,7 @@ SanityCheckBackgroundWorker(BackgroundWorker *worker, int elevel) ereport(elevel, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("background worker \"%s\": must attach to shared memory in order to request a database connection", - worker->bgw_name))); + worker->bgw_type))); return false; } @@ -597,7 +601,7 @@ SanityCheckBackgroundWorker(BackgroundWorker *worker, int elevel) ereport(elevel, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("background worker \"%s\": cannot request database access if starting at postmaster start", - worker->bgw_name))); + worker->bgw_type))); return false; } @@ -611,7 +615,7 @@ SanityCheckBackgroundWorker(BackgroundWorker *worker, int elevel) ereport(elevel, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("background worker \"%s\": invalid restart interval", - worker->bgw_name))); + worker->bgw_type))); return false; } @@ -626,7 +630,7 @@ SanityCheckBackgroundWorker(BackgroundWorker *worker, int elevel) ereport(elevel, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("background worker \"%s\": parallel workers may not be configured for restart", - worker->bgw_name))); + worker->bgw_type))); return false; } @@ -670,8 +674,8 @@ bgworker_die(SIGNAL_ARGS) ereport(FATAL, (errcode(ERRCODE_ADMIN_SHUTDOWN), - errmsg("terminating background worker \"%s\" due to administrator command", - MyBgworkerEntry->bgw_name))); + errmsg("terminating %s due to administrator command", + MyBgworkerEntry->bgw_type))); } /* @@ -710,7 +714,7 @@ StartBackgroundWorker(void) IsBackgroundWorker = true; /* Identify myself via ps */ - snprintf(buf, MAXPGPATH, "bgworker: %s", worker->bgw_name); + snprintf(buf, MAXPGPATH, "%s%s", worker->bgw_type, worker->bgw_name_extra); init_ps_display(buf, "", "", ""); /* @@ -852,8 +856,8 @@ RegisterBackgroundWorker(BackgroundWorker *worker) static int numworkers = 0; if (!IsUnderPostmaster) - ereport(DEBUG1, - (errmsg("registering background worker \"%s\"", worker->bgw_name))); + elog(DEBUG1, + "registering background worker \"%s%s\"", worker->bgw_type, worker->bgw_name_extra); if (!process_shared_preload_libraries_in_progress && strcmp(worker->bgw_library_name, "postgres") != 0) @@ -862,7 +866,7 @@ RegisterBackgroundWorker(BackgroundWorker *worker) ereport(LOG, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("background worker \"%s\": must be registered in shared_preload_libraries", - worker->bgw_name))); + worker->bgw_type))); return; } @@ -874,7 +878,7 @@ RegisterBackgroundWorker(BackgroundWorker *worker) ereport(LOG, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("background worker \"%s\": only dynamic background workers can request notification", - worker->bgw_name))); + worker->bgw_type))); return; } diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index 35b4ec88d3..991caeace7 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -3070,7 +3070,6 @@ static bool CleanupBackgroundWorker(int pid, int exitstatus) /* child's exit status */ { - char namebuf[MAXPGPATH]; slist_mutable_iter iter; slist_foreach_modify(iter, &BackgroundWorkerList) @@ -3088,9 +3087,6 @@ CleanupBackgroundWorker(int pid, exitstatus = 0; #endif - snprintf(namebuf, MAXPGPATH, "%s: %s", _("worker process"), - rw->rw_worker.bgw_name); - if (!EXIT_STATUS_0(exitstatus)) { /* Record timestamp, so we know when to restart the worker. */ @@ -3112,7 +3108,7 @@ CleanupBackgroundWorker(int pid, { if (!EXIT_STATUS_0(exitstatus) && !EXIT_STATUS_1(exitstatus)) { - HandleChildCrash(pid, exitstatus, namebuf); + HandleChildCrash(pid, exitstatus, rw->rw_worker.bgw_type); return true; } } @@ -3125,7 +3121,7 @@ CleanupBackgroundWorker(int pid, if (!ReleasePostmasterChildSlot(rw->rw_child_slot) && (rw->rw_worker.bgw_flags & BGWORKER_SHMEM_ACCESS) != 0) { - HandleChildCrash(pid, exitstatus, namebuf); + HandleChildCrash(pid, exitstatus, rw->rw_worker.bgw_type); return true; } @@ -3150,7 +3146,7 @@ CleanupBackgroundWorker(int pid, ReportBackgroundWorkerExit(&iter); /* report child death */ LogChildExit(EXIT_STATUS_0(exitstatus) ? DEBUG1 : LOG, - namebuf, pid, exitstatus); + rw->rw_worker.bgw_type, pid, exitstatus); return true; } @@ -5576,9 +5572,9 @@ do_start_bgworker(RegisteredBgWorker *rw) return false; } - ereport(DEBUG1, - (errmsg("starting background worker process \"%s\"", - rw->rw_worker.bgw_name))); + elog(DEBUG1, + "starting background worker process \"%s%s\"", + rw->rw_worker.bgw_type, rw->rw_worker.bgw_name_extra); #ifdef EXEC_BACKEND switch ((worker_pid = bgworker_forkexec(rw->rw_shmem_slot))) diff --git a/src/backend/replication/logical/launcher.c b/src/backend/replication/logical/launcher.c index b956052014..624d8e9ca7 100644 --- a/src/backend/replication/logical/launcher.c +++ b/src/backend/replication/logical/launcher.c @@ -379,12 +379,13 @@ logicalrep_worker_launch(Oid dbid, Oid subid, const char *subname, Oid userid, bgw.bgw_start_time = BgWorkerStart_RecoveryFinished; snprintf(bgw.bgw_library_name, BGW_MAXLEN, "postgres"); snprintf(bgw.bgw_function_name, BGW_MAXLEN, "ApplyWorkerMain"); + snprintf(bgw.bgw_type, BGW_MAXLEN, "logical replication worker"); if (OidIsValid(relid)) - snprintf(bgw.bgw_name, BGW_MAXLEN, - "logical replication worker for subscription %u sync %u", subid, relid); + snprintf(bgw.bgw_name_extra, BGW_MAXLEN, + " for subscription %u sync %u", subid, relid); else - snprintf(bgw.bgw_name, BGW_MAXLEN, - "logical replication worker for subscription %u", subid); + snprintf(bgw.bgw_name_extra, BGW_MAXLEN, + " for subscription %u", subid); bgw.bgw_restart_time = BGW_NEVER_RESTART; bgw.bgw_notify_pid = MyProcPid; @@ -706,7 +707,7 @@ ApplyLauncherRegister(void) bgw.bgw_start_time = BgWorkerStart_RecoveryFinished; snprintf(bgw.bgw_library_name, BGW_MAXLEN, "postgres"); snprintf(bgw.bgw_function_name, BGW_MAXLEN, "ApplyLauncherMain"); - snprintf(bgw.bgw_name, BGW_MAXLEN, + snprintf(bgw.bgw_type, BGW_MAXLEN, "logical replication launcher"); bgw.bgw_restart_time = 5; bgw.bgw_notify_pid = 0; @@ -797,10 +798,6 @@ ApplyLauncherMain(Datum main_arg) pqsignal(SIGTERM, logicalrep_worker_sigterm); BackgroundWorkerUnblockSignals(); - /* Make it easy to identify our processes. */ - SetConfigOption("application_name", MyBgworkerEntry->bgw_name, - PGC_USERSET, PGC_S_SESSION); - LogicalRepCtx->launcher_pid = MyProcPid; /* diff --git a/src/backend/replication/logical/worker.c b/src/backend/replication/logical/worker.c index c67720bd2f..e59b9db407 100644 --- a/src/backend/replication/logical/worker.c +++ b/src/backend/replication/logical/worker.c @@ -1467,10 +1467,6 @@ ApplyWorkerMain(Datum main_arg) MyLogicalRepWorker->last_send_time = MyLogicalRepWorker->last_recv_time = MyLogicalRepWorker->reply_time = GetCurrentTimestamp(); - /* Make it easy to identify our processes. */ - SetConfigOption("application_name", MyBgworkerEntry->bgw_name, - PGC_USERSET, PGC_S_SESSION); - /* Load the libpq-specific functions */ load_file("libpqwalreceiver", false); diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c index e0cae1ba1e..9d779491b5 100644 --- a/src/backend/utils/adt/pgstatfuncs.c +++ b/src/backend/utils/adt/pgstatfuncs.c @@ -21,6 +21,7 @@ #include "funcapi.h" #include "miscadmin.h" #include "pgstat.h" +#include "postmaster/bgworker_internals.h" #include "postmaster/postmaster.h" #include "storage/proc.h" #include "storage/procarray.h" @@ -820,8 +821,32 @@ pg_stat_get_activity(PG_FUNCTION_ARGS) } } /* Add backend type */ - values[17] = - CStringGetTextDatum(pgstat_get_backend_desc(beentry->st_backendType)); + if (beentry->st_backendType == B_BG_WORKER) + { + slist_iter siter; + bool found = false; + + slist_foreach(siter, &BackgroundWorkerList) + { + RegisteredBgWorker *rw; + + rw = slist_container(RegisteredBgWorker, rw_lnode, siter.cur); + + if (rw->rw_pid == beentry->st_procpid) + { + values[17] = + CStringGetTextDatum(rw->rw_worker.bgw_type); + found = true; + break; + } + } + + if (!found) + nulls[17] = true; + } + else + values[17] = + CStringGetTextDatum(pgstat_get_backend_desc(beentry->st_backendType)); } else { diff --git a/src/include/postmaster/bgworker.h b/src/include/postmaster/bgworker.h index 51a5978ea8..daf7a3f7fe 100644 --- a/src/include/postmaster/bgworker.h +++ b/src/include/postmaster/bgworker.h @@ -87,7 +87,8 @@ typedef enum typedef struct BackgroundWorker { - char bgw_name[BGW_MAXLEN]; + char bgw_type[BGW_MAXLEN]; + char bgw_name_extra[BGW_MAXLEN]; int bgw_flags; BgWorkerStartTime bgw_start_time; int bgw_restart_time; /* in seconds, or BGW_NEVER_RESTART */ diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 06c49bdb40..54c8dea4ed 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -219,7 +219,7 @@ setup_background_workers(int nworkers, dsm_segment *seg) worker.bgw_restart_time = BGW_NEVER_RESTART; sprintf(worker.bgw_library_name, "test_shm_mq"); sprintf(worker.bgw_function_name, "test_shm_mq_main"); - snprintf(worker.bgw_name, BGW_MAXLEN, "test_shm_mq"); + snprintf(worker.bgw_type, BGW_MAXLEN, "test_shm_mq"); worker.bgw_main_arg = UInt32GetDatum(dsm_segment_handle(seg)); /* set bgw_notify_pid, so we can detect if the worker stops */ worker.bgw_notify_pid = MyProcPid; diff --git a/src/test/modules/worker_spi/worker_spi.c b/src/test/modules/worker_spi/worker_spi.c index 9abfc714a9..9c217b69c8 100644 --- a/src/test/modules/worker_spi/worker_spi.c +++ b/src/test/modules/worker_spi/worker_spi.c @@ -181,8 +181,10 @@ worker_spi_main(Datum main_arg) /* Connect to our database */ BackgroundWorkerInitializeConnection("postgres", NULL); - elog(LOG, "%s initialized with %s.%s", - MyBgworkerEntry->bgw_name, table->schema, table->name); + elog(LOG, "%s%s initialized with %s.%s", + MyBgworkerEntry->bgw_type, + MyBgworkerEntry->bgw_name_extra, + table->schema, table->name); initialize_worker_spi(table); /* @@ -282,8 +284,9 @@ worker_spi_main(Datum main_arg) SPI_tuptable->tupdesc, 1, &isnull)); if (!isnull) - elog(LOG, "%s: count in %s.%s is now %d", - MyBgworkerEntry->bgw_name, + elog(LOG, "%s%s: count in %s.%s is now %d", + MyBgworkerEntry->bgw_type, + MyBgworkerEntry->bgw_name_extra, table->schema, table->name, val); } @@ -357,7 +360,8 @@ _PG_init(void) */ for (i = 1; i <= worker_spi_total_workers; i++) { - snprintf(worker.bgw_name, BGW_MAXLEN, "worker %d", i); + snprintf(worker.bgw_type, BGW_MAXLEN, "worker_spi worker"); + snprintf(worker.bgw_name_extra, BGW_MAXLEN, " %d", i); worker.bgw_main_arg = Int32GetDatum(i); RegisterBackgroundWorker(&worker); @@ -383,7 +387,8 @@ worker_spi_launch(PG_FUNCTION_ARGS) worker.bgw_restart_time = BGW_NEVER_RESTART; sprintf(worker.bgw_library_name, "worker_spi"); sprintf(worker.bgw_function_name, "worker_spi_main"); - snprintf(worker.bgw_name, BGW_MAXLEN, "worker %d", i); + snprintf(worker.bgw_type, BGW_MAXLEN, "worker_spi worker"); + snprintf(worker.bgw_name_extra, BGW_MAXLEN, " %d", i); worker.bgw_main_arg = Int32GetDatum(i); /* set bgw_notify_pid so that we can use WaitForBackgroundWorkerStartup */ worker.bgw_notify_pid = MyProcPid; -- 2.13.0