diff options
author | Robert Haas <rhaas@postgresql.org> | 2022-05-13 09:31:06 -0400 |
---|---|---|
committer | Robert Haas <rhaas@postgresql.org> | 2022-05-13 09:31:06 -0400 |
commit | 4f2400cb3f10aa79f99fba680c198237da28dd38 (patch) | |
tree | 4f96c3499f0ad60ee18431317e7068a21f498358 /src | |
parent | 8c8d307f82976122980bbccf940319d1b8a71403 (diff) | |
download | postgresql-4f2400cb3f10aa79f99fba680c198237da28dd38.tar.gz postgresql-4f2400cb3f10aa79f99fba680c198237da28dd38.zip |
Add a new shmem_request_hook hook.
Currently, preloaded libraries are expected to request additional
shared memory and LWLocks in _PG_init(). However, it is not unusal
for such requests to depend on MaxBackends, which won't be
initialized at that time. Such requests could also depend on GUCs
that other modules might change. This introduces a new hook where
modules can safely use MaxBackends and GUCs to request additional
shared memory and LWLocks.
Furthermore, this change restricts requests for shared memory and
LWLocks to this hook. Previously, libraries could make requests
until the size of the main shared memory segment was calculated.
Unlike before, we no longer silently ignore requests received at
invalid times. Instead, we FATAL if someone tries to request
additional shared memory or LWLocks outside of the hook.
Nathan Bossart and Julien Rouhaud
Discussion: https://postgr.es/m/20220412210112.GA2065815%40nathanxps13
Discussion: https://postgr.es/m/Yn2jE/lmDhKtkUdr@paquier.xyz
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/postmaster/postmaster.c | 5 | ||||
-rw-r--r-- | src/backend/storage/ipc/ipci.c | 20 | ||||
-rw-r--r-- | src/backend/storage/lmgr/lwlock.c | 18 | ||||
-rw-r--r-- | src/backend/utils/init/miscinit.c | 15 | ||||
-rw-r--r-- | src/include/miscadmin.h | 5 | ||||
-rw-r--r-- | src/tools/pgindent/typedefs.list | 1 |
6 files changed, 37 insertions, 27 deletions
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index bf591f048d4..3b73e269564 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -1043,6 +1043,11 @@ PostmasterMain(int argc, char *argv[]) InitializeMaxBackends(); /* + * Give preloaded libraries a chance to request additional shared memory. + */ + process_shmem_requests(); + + /* * Now that loadable modules have had their chance to request additional * shared memory, determine the value of any runtime-computed GUCs that * depend on the amount of shared memory required. diff --git a/src/backend/storage/ipc/ipci.c b/src/backend/storage/ipc/ipci.c index 75e456360be..26372d95b38 100644 --- a/src/backend/storage/ipc/ipci.c +++ b/src/backend/storage/ipc/ipci.c @@ -55,25 +55,21 @@ int shared_memory_type = DEFAULT_SHARED_MEMORY_TYPE; shmem_startup_hook_type shmem_startup_hook = NULL; static Size total_addin_request = 0; -static bool addin_request_allowed = true; - /* * RequestAddinShmemSpace * Request that extra shmem space be allocated for use by * a loadable module. * - * This is only useful if called from the _PG_init hook of a library that - * is loaded into the postmaster via shared_preload_libraries. Once - * shared memory has been allocated, calls will be ignored. (We could - * raise an error, but it seems better to make it a no-op, so that - * libraries containing such calls can be reloaded if needed.) + * This may only be called via the shmem_request_hook of a library that is + * loaded into the postmaster via shared_preload_libraries. Calls from + * elsewhere will fail. */ void RequestAddinShmemSpace(Size size) { - if (IsUnderPostmaster || !addin_request_allowed) - return; /* too late */ + if (!process_shmem_requests_in_progress) + elog(FATAL, "cannot request additional shared memory outside shmem_request_hook"); total_addin_request = add_size(total_addin_request, size); } @@ -83,9 +79,6 @@ RequestAddinShmemSpace(Size size) * * If num_semaphores is not NULL, it will be set to the number of semaphores * required. - * - * Note that this function freezes the additional shared memory request size - * from loadable modules. */ Size CalculateShmemSize(int *num_semaphores) @@ -152,8 +145,7 @@ CalculateShmemSize(int *num_semaphores) size = add_size(size, ShmemBackendArraySize()); #endif - /* freeze the addin request size and include it */ - addin_request_allowed = false; + /* include additional requested shmem from preload libraries */ size = add_size(size, total_addin_request); /* might as well round it off to a multiple of a typical page size */ diff --git a/src/backend/storage/lmgr/lwlock.c b/src/backend/storage/lmgr/lwlock.c index fef462b1102..8aef909037d 100644 --- a/src/backend/storage/lmgr/lwlock.c +++ b/src/backend/storage/lmgr/lwlock.c @@ -243,8 +243,6 @@ int NamedLWLockTrancheRequests = 0; /* points to data in shared memory: */ NamedLWLockTranche *NamedLWLockTrancheArray = NULL; -static bool lock_named_request_allowed = true; - static void InitializeLWLocks(void); static inline void LWLockReportWaitStart(LWLock *lock); static inline void LWLockReportWaitEnd(void); @@ -458,9 +456,6 @@ LWLockShmemSize(void) for (i = 0; i < NamedLWLockTrancheRequests; i++) size = add_size(size, strlen(NamedLWLockTrancheRequestArray[i].tranche_name) + 1); - /* Disallow adding any more named tranches. */ - lock_named_request_allowed = false; - return size; } @@ -691,12 +686,9 @@ LWLockRegisterTranche(int tranche_id, const char *tranche_name) * Request that extra LWLocks be allocated during postmaster * startup. * - * This is only useful for extensions if called from the _PG_init hook - * of a library that is loaded into the postmaster via - * shared_preload_libraries. Once shared memory has been allocated, calls - * will be ignored. (We could raise an error, but it seems better to make - * it a no-op, so that libraries containing such calls can be reloaded if - * needed.) + * This may only be called via the shmem_request_hook of a library that is + * loaded into the postmaster via shared_preload_libraries. Calls from + * elsewhere will fail. * * The tranche name will be user-visible as a wait event name, so try to * use a name that fits the style for those. @@ -706,8 +698,8 @@ RequestNamedLWLockTranche(const char *tranche_name, int num_lwlocks) { NamedLWLockTrancheRequest *request; - if (IsUnderPostmaster || !lock_named_request_allowed) - return; /* too late */ + if (!process_shmem_requests_in_progress) + elog(FATAL, "cannot request additional LWLocks outside shmem_request_hook"); if (NamedLWLockTrancheRequestArray == NULL) { diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c index 6ed584e1143..ec6a61594a4 100644 --- a/src/backend/utils/init/miscinit.c +++ b/src/backend/utils/init/miscinit.c @@ -1618,6 +1618,9 @@ char *local_preload_libraries_string = NULL; bool process_shared_preload_libraries_in_progress = false; bool process_shared_preload_libraries_done = false; +shmem_request_hook_type shmem_request_hook = NULL; +bool process_shmem_requests_in_progress = false; + /* * load the shared libraries listed in 'libraries' * @@ -1701,6 +1704,18 @@ process_session_preload_libraries(void) true); } +/* + * process any shared memory requests from preloaded libraries + */ +void +process_shmem_requests(void) +{ + process_shmem_requests_in_progress = true; + if (shmem_request_hook) + shmem_request_hook(); + process_shmem_requests_in_progress = false; +} + void pg_bindtextdomain(const char *domain) { diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h index 53fd168d93c..0af130fbc5d 100644 --- a/src/include/miscadmin.h +++ b/src/include/miscadmin.h @@ -465,6 +465,7 @@ extern void BaseInit(void); extern PGDLLIMPORT bool IgnoreSystemIndexes; extern PGDLLIMPORT bool process_shared_preload_libraries_in_progress; extern PGDLLIMPORT bool process_shared_preload_libraries_done; +extern PGDLLIMPORT bool process_shmem_requests_in_progress; extern PGDLLIMPORT char *session_preload_libraries_string; extern PGDLLIMPORT char *shared_preload_libraries_string; extern PGDLLIMPORT char *local_preload_libraries_string; @@ -478,9 +479,13 @@ extern bool RecheckDataDirLockFile(void); extern void ValidatePgVersion(const char *path); extern void process_shared_preload_libraries(void); extern void process_session_preload_libraries(void); +extern void process_shmem_requests(void); extern void pg_bindtextdomain(const char *domain); extern bool has_rolreplication(Oid roleid); +typedef void (*shmem_request_hook_type) (void); +extern PGDLLIMPORT shmem_request_hook_type shmem_request_hook; + /* in executor/nodeHash.c */ extern size_t get_hash_memory_limit(void); diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list index dd1214977a8..4fb746930aa 100644 --- a/src/tools/pgindent/typedefs.list +++ b/src/tools/pgindent/typedefs.list @@ -3651,6 +3651,7 @@ shm_mq_result shm_toc shm_toc_entry shm_toc_estimator +shmem_request_hook_type shmem_startup_hook_type sig_atomic_t sigjmp_buf |