diff options
author | Heikki Linnakangas | 2024-03-03 17:37:28 +0000 |
---|---|---|
committer | Heikki Linnakangas | 2024-03-03 17:37:28 +0000 |
commit | ab355e3a88de745607f6dd4c21f0119b5c68f2ad (patch) | |
tree | 7808e71e8fbee29095708f47f80bb2bea099e52e /src/backend/utils | |
parent | 30b8d6e4ce1112168ddfe8cdbba76fbefd304b34 (diff) |
Redefine backend ID to be an index into the proc array
Previously, backend ID was an index into the ProcState array, in the
shared cache invalidation manager (sinvaladt.c). The entry in the
ProcState array was reserved at backend startup by scanning the array
for a free entry, and that was also when the backend got its backend
ID. Things become slightly simpler if we redefine backend ID to be the
index into the PGPROC array, and directly use it also as an index to
the ProcState array. This uses a little more memory, as we reserve a
few extra slots in the ProcState array for aux processes that don't
need them, but the simplicity is worth it.
Aux processes now also have a backend ID. This simplifies the
reservation of BackendStatusArray and ProcSignal slots.
You can now convert a backend ID into an index into the PGPROC array
simply by subtracting 1. We still use 0-based "pgprocnos" in various
places, for indexes into the PGPROC array, but the only difference now
is that backend IDs start at 1 while pgprocnos start at 0. (The next
commmit will get rid of the term "backend ID" altogether and make
everything 0-based.)
There is still a 'backendId' field in PGPROC, now part of 'vxid' which
encapsulates the backend ID and local transaction ID together. It's
needed for prepared xacts. For regular backends, the backendId is
always equal to pgprocno + 1, but for prepared xact PGPROC entries,
it's the ID of the original backend that processed the transaction.
Reviewed-by: Andres Freund, Reid Thompson
Discussion: https://www.postgresql.org/message-id/[email protected]
Diffstat (limited to 'src/backend/utils')
-rw-r--r-- | src/backend/utils/activity/backend_status.c | 52 | ||||
-rw-r--r-- | src/backend/utils/adt/lockfuncs.c | 2 | ||||
-rw-r--r-- | src/backend/utils/adt/mcxtfuncs.c | 14 | ||||
-rw-r--r-- | src/backend/utils/error/csvlog.c | 4 | ||||
-rw-r--r-- | src/backend/utils/error/elog.c | 6 | ||||
-rw-r--r-- | src/backend/utils/error/jsonlog.c | 6 | ||||
-rw-r--r-- | src/backend/utils/init/postinit.c | 10 | ||||
-rw-r--r-- | src/backend/utils/time/snapmgr.c | 5 |
8 files changed, 34 insertions, 65 deletions
diff --git a/src/backend/utils/activity/backend_status.c b/src/backend/utils/activity/backend_status.c index 1a1050c8da1..3d3f7b06723 100644 --- a/src/backend/utils/activity/backend_status.c +++ b/src/backend/utils/activity/backend_status.c @@ -19,6 +19,7 @@ #include "port/atomics.h" /* for memory barriers */ #include "storage/ipc.h" #include "storage/proc.h" /* for MyProc */ +#include "storage/procarray.h" #include "storage/sinvaladt.h" #include "utils/ascii.h" #include "utils/backend_status.h" @@ -29,13 +30,12 @@ /* ---------- * Total number of backends including auxiliary * - * We reserve a slot for each possible BackendId, plus one for each - * possible auxiliary process type. (This scheme assumes there is not - * more than one of any auxiliary process type at a time.) MaxBackends - * includes autovacuum workers and background workers as well. + * We reserve a slot for each possible PGPROC entry, including aux processes. + * (But not including PGPROC entries reserved for prepared xacts; they are not + * real processes.) * ---------- */ -#define NumBackendStatSlots (MaxBackends + NUM_AUXPROCTYPES) +#define NumBackendStatSlots (MaxBackends + NUM_AUXILIARY_PROCS) /* ---------- @@ -238,10 +238,9 @@ CreateSharedBackendStatus(void) /* * Initialize pgstats backend activity state, and set up our on-proc-exit - * hook. Called from InitPostgres and AuxiliaryProcessMain. For auxiliary - * process, MyBackendId is invalid. Otherwise, MyBackendId must be set, but we - * must not have started any transaction yet (since the exit hook must run - * after the last transaction exit). + * hook. Called from InitPostgres and AuxiliaryProcessMain. MyBackendId must + * be set, but we must not have started any transaction yet (since the exit + * hook must run after the last transaction exit). * * NOTE: MyDatabaseId isn't set yet; so the shutdown hook has to be careful. */ @@ -249,26 +248,9 @@ void pgstat_beinit(void) { /* Initialize MyBEEntry */ - if (MyBackendId != InvalidBackendId) - { - Assert(MyBackendId >= 1 && MyBackendId <= MaxBackends); - MyBEEntry = &BackendStatusArray[MyBackendId - 1]; - } - else - { - /* Must be an auxiliary process */ - Assert(MyAuxProcType != NotAnAuxProcess); - - /* - * Assign the MyBEEntry for an auxiliary process. Since it doesn't - * have a BackendId, the slot is statically allocated based on the - * auxiliary process type (MyAuxProcType). Backends use slots indexed - * in the range from 0 to MaxBackends (exclusive), so we use - * MaxBackends + AuxProcType as the index of the slot for an auxiliary - * process. - */ - MyBEEntry = &BackendStatusArray[MaxBackends + MyAuxProcType]; - } + Assert(MyBackendId != InvalidBackendId); + Assert(MyBackendId >= 1 && MyBackendId <= NumBackendStatSlots); + MyBEEntry = &BackendStatusArray[MyBackendId - 1]; /* Set up a process-exit hook to clean up */ on_shmem_exit(pgstat_beshutdown_hook, 0); @@ -281,12 +263,12 @@ pgstat_beinit(void) * Initialize this backend's entry in the PgBackendStatus array. * Called from InitPostgres. * - * Apart from auxiliary processes, MyBackendId, MyDatabaseId, - * session userid, and application_name must be set for a - * backend (hence, this cannot be combined with pgstat_beinit). - * Note also that we must be inside a transaction if this isn't an aux - * process, as we may need to do encoding conversion on some strings. - * ---------- + * Apart from auxiliary processes, MyDatabaseId, session userid, and + * application_name must already be set (hence, this cannot be combined + * with pgstat_beinit). Note also that we must be inside a transaction + * if this isn't an aux process, as we may need to do encoding conversion + * on some strings. + *---------- */ void pgstat_bestart(void) diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c index 4b49f7fe3d8..bbe5cc0806e 100644 --- a/src/backend/utils/adt/lockfuncs.c +++ b/src/backend/utils/adt/lockfuncs.c @@ -353,7 +353,7 @@ pg_lock_status(PG_FUNCTION_ARGS) break; } - values[10] = VXIDGetDatum(instance->backend, instance->lxid); + values[10] = VXIDGetDatum(instance->vxid.backendId, instance->vxid.localTransactionId); if (instance->pid != 0) values[11] = Int32GetDatum(instance->pid); else diff --git a/src/backend/utils/adt/mcxtfuncs.c b/src/backend/utils/adt/mcxtfuncs.c index 4708d73f5fa..a7267dc15d1 100644 --- a/src/backend/utils/adt/mcxtfuncs.c +++ b/src/backend/utils/adt/mcxtfuncs.c @@ -148,19 +148,11 @@ pg_log_backend_memory_contexts(PG_FUNCTION_ARGS) PGPROC *proc; BackendId backendId = InvalidBackendId; - proc = BackendPidGetProc(pid); - /* * See if the process with given pid is a backend or an auxiliary process. - * - * If the given process is a backend, use its backend id in - * SendProcSignal() later to speed up the operation. Otherwise, don't do - * that because auxiliary processes (except the startup process) don't - * have a valid backend id. */ - if (proc != NULL) - backendId = proc->backendId; - else + proc = BackendPidGetProc(pid); + if (proc == NULL) proc = AuxiliaryPidGetProc(pid); /* @@ -183,6 +175,8 @@ pg_log_backend_memory_contexts(PG_FUNCTION_ARGS) PG_RETURN_BOOL(false); } + if (proc != NULL) + backendId = GetBackendIdFromPGProc(proc); if (SendProcSignal(pid, PROCSIG_LOG_MEMORY_CONTEXT, backendId) < 0) { /* Again, just a warning to allow loops */ diff --git a/src/backend/utils/error/csvlog.c b/src/backend/utils/error/csvlog.c index 1b62b07f231..1d44d8a6a31 100644 --- a/src/backend/utils/error/csvlog.c +++ b/src/backend/utils/error/csvlog.c @@ -152,8 +152,8 @@ write_csvlog(ErrorData *edata) /* Virtual transaction id */ /* keep VXID format in sync with lockfuncs.c */ - if (MyProc != NULL && MyProc->backendId != InvalidBackendId) - appendStringInfo(&buf, "%d/%u", MyProc->backendId, MyProc->lxid); + if (MyProc != NULL && MyProc->vxid.backendId != InvalidBackendId) + appendStringInfo(&buf, "%d/%u", MyProc->vxid.backendId, MyProc->vxid.lxid); appendStringInfoChar(&buf, ','); /* Transaction id */ diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c index c9719f358b6..149b4b8df13 100644 --- a/src/backend/utils/error/elog.c +++ b/src/backend/utils/error/elog.c @@ -3076,18 +3076,18 @@ log_status_format(StringInfo buf, const char *format, ErrorData *edata) break; case 'v': /* keep VXID format in sync with lockfuncs.c */ - if (MyProc != NULL && MyProc->backendId != InvalidBackendId) + if (MyProc != NULL && MyProc->vxid.backendId != InvalidBackendId) { if (padding != 0) { char strfbuf[128]; snprintf(strfbuf, sizeof(strfbuf) - 1, "%d/%u", - MyProc->backendId, MyProc->lxid); + MyProc->vxid.backendId, MyProc->vxid.lxid); appendStringInfo(buf, "%*s", padding, strfbuf); } else - appendStringInfo(buf, "%d/%u", MyProc->backendId, MyProc->lxid); + appendStringInfo(buf, "%d/%u", MyProc->vxid.backendId, MyProc->vxid.lxid); } else if (padding != 0) appendStringInfoSpaces(buf, diff --git a/src/backend/utils/error/jsonlog.c b/src/backend/utils/error/jsonlog.c index 2903561f1c4..067d9e30b16 100644 --- a/src/backend/utils/error/jsonlog.c +++ b/src/backend/utils/error/jsonlog.c @@ -197,9 +197,9 @@ write_jsonlog(ErrorData *edata) /* Virtual transaction id */ /* keep VXID format in sync with lockfuncs.c */ - if (MyProc != NULL && MyProc->backendId != InvalidBackendId) - appendJSONKeyValueFmt(&buf, "vxid", true, "%d/%u", MyProc->backendId, - MyProc->lxid); + if (MyProc != NULL && MyProc->vxid.backendId != InvalidBackendId) + appendJSONKeyValueFmt(&buf, "vxid", true, "%d/%u", + MyProc->vxid.backendId, MyProc->vxid.lxid); /* Transaction id */ appendJSONKeyValueFmt(&buf, "txid", false, "%u", diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c index 5ffe9bdd987..c49c048441b 100644 --- a/src/backend/utils/init/postinit.c +++ b/src/backend/utils/init/postinit.c @@ -742,18 +742,10 @@ InitPostgres(const char *in_dbname, Oid dboid, /* * Initialize my entry in the shared-invalidation manager's array of * per-backend data. - * - * Sets up MyBackendId, a unique backend identifier. */ - MyBackendId = InvalidBackendId; - SharedInvalBackendInit(false); - if (MyBackendId > MaxBackends || MyBackendId <= 0) - elog(FATAL, "bad backend ID: %d", MyBackendId); - - /* Now that we have a BackendId, we can participate in ProcSignal */ - ProcSignalInit(MyBackendId); + ProcSignalInit(); /* * Also set up timeout handlers needed for backend operation. We need diff --git a/src/backend/utils/time/snapmgr.c b/src/backend/utils/time/snapmgr.c index 675e81d82d7..a0916959b17 100644 --- a/src/backend/utils/time/snapmgr.c +++ b/src/backend/utils/time/snapmgr.c @@ -1154,7 +1154,8 @@ ExportSnapshot(Snapshot snapshot) * inside the transaction from 1. */ snprintf(path, sizeof(path), SNAPSHOT_EXPORT_DIR "/%08X-%08X-%d", - MyProc->backendId, MyProc->lxid, list_length(exportedSnapshots) + 1); + MyProc->vxid.backendId, MyProc->vxid.lxid, + list_length(exportedSnapshots) + 1); /* * Copy the snapshot into TopTransactionContext, add it to the @@ -1181,7 +1182,7 @@ ExportSnapshot(Snapshot snapshot) */ initStringInfo(&buf); - appendStringInfo(&buf, "vxid:%d/%u\n", MyProc->backendId, MyProc->lxid); + appendStringInfo(&buf, "vxid:%d/%u\n", MyProc->vxid.backendId, MyProc->vxid.lxid); appendStringInfo(&buf, "pid:%d\n", MyProcPid); appendStringInfo(&buf, "dbid:%u\n", MyDatabaseId); appendStringInfo(&buf, "iso:%d\n", XactIsoLevel); |