diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c index 62baaf0ab3..d74e8aa1d5 100644 --- a/src/backend/utils/init/postinit.c +++ b/src/backend/utils/init/postinit.c @@ -71,6 +71,7 @@ static HeapTuple GetDatabaseTupleByOid(Oid dboid); static void PerformAuthentication(Port *port); static void CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connections); static void InitCommunication(void); +static void ReleaseLWLocks(int code, Datum arg); static void ShutdownPostgres(int code, Datum arg); static void StatementTimeoutHandler(void); static void LockTimeoutHandler(void); @@ -653,6 +654,7 @@ InitPostgres(const char *in_dbname, Oid dboid, const char *username, * way, start up the XLOG machinery, and register to have it closed * down at exit. */ + on_shmem_exit(ReleaseLWLocks, 0); StartupXLOG(); on_shmem_exit(ShutdownXLOG, 0); } @@ -1214,6 +1216,23 @@ process_settings(Oid databaseid, Oid roleid) heap_close(relsetting, AccessShareLock); } +/* + * There are 2 types of buffer locks on-holding when AtProcExit_Buffers() is + * invoked in a bootstrap process or a standalone backend: + * (1) Exceptions thrown during StartupXLOG() + * (2) Exceptions thrown during exception-handling in ShutdownXLOG() + * So we need this on_shmem_exit callback for single user mode. + * For processes under postmaster, ShutdownAuxiliaryProcess() will release + * the lw-locks and ShutdownXLOG() is not registered as a callback, so there + * is no such issue. Also, please note this callback should be registered in + * the order after AtProcExit_buffers() and before ShutdownXLOG(). + */ +static void +ReleaseLWLocks(int code, Datum arg) +{ + LWLockReleaseAll(); +} + /* * Backend-shutdown callback. Do cleanup that we want to be sure happens * before all the supporting modules begin to nail their doors shut via