mirror of
				https://github.com/postgres/postgres.git
				synced 2025-10-31 00:03:57 -04:00 
			
		
		
		
	Allow background workers to bypass datallowconn
THis adds a "flags" field to the BackgroundWorkerInitializeConnection() and BackgroundWorkerInitializeConnectionByOid(). For now only one flag, BGWORKER_BYPASS_ALLOWCONN, is defined, which allows the worker to ignore datallowconn.
This commit is contained in:
		
							parent
							
								
									1664ae1978
								
							
						
					
					
						commit
						eed1ce72e1
					
				| @ -445,7 +445,7 @@ autoprewarm_database_main(Datum main_arg) | ||||
| 		ereport(ERROR, | ||||
| 				(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), | ||||
| 				 errmsg("could not map dynamic shared memory segment"))); | ||||
| 	BackgroundWorkerInitializeConnectionByOid(apw_state->database, InvalidOid); | ||||
| 	BackgroundWorkerInitializeConnectionByOid(apw_state->database, InvalidOid, 0); | ||||
| 	block_info = (BlockInfoRecord *) dsm_segment_address(seg); | ||||
| 	pos = apw_state->prewarm_start_idx; | ||||
| 
 | ||||
|  | ||||
| @ -1324,7 +1324,8 @@ ParallelWorkerMain(Datum main_arg) | ||||
| 
 | ||||
| 	/* Restore database connection. */ | ||||
| 	BackgroundWorkerInitializeConnectionByOid(fps->database_id, | ||||
| 											  fps->authenticated_user_id); | ||||
| 											  fps->authenticated_user_id, | ||||
| 											  0); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Set the client encoding to the database encoding, since that is what | ||||
|  | ||||
| @ -498,7 +498,7 @@ BootstrapModeMain(void) | ||||
| 	 */ | ||||
| 	InitProcess(); | ||||
| 
 | ||||
| 	InitPostgres(NULL, InvalidOid, NULL, InvalidOid, NULL); | ||||
| 	InitPostgres(NULL, InvalidOid, NULL, InvalidOid, NULL, false); | ||||
| 
 | ||||
| 	/* Initialize stuff for bootstrap-file processing */ | ||||
| 	for (i = 0; i < MAXATTR; i++) | ||||
|  | ||||
| @ -477,7 +477,7 @@ AutoVacLauncherMain(int argc, char *argv[]) | ||||
| 	InitProcess(); | ||||
| #endif | ||||
| 
 | ||||
| 	InitPostgres(NULL, InvalidOid, NULL, InvalidOid, NULL); | ||||
| 	InitPostgres(NULL, InvalidOid, NULL, InvalidOid, NULL, false); | ||||
| 
 | ||||
| 	SetProcessingMode(NormalProcessing); | ||||
| 
 | ||||
| @ -1693,7 +1693,7 @@ AutoVacWorkerMain(int argc, char *argv[]) | ||||
| 		 * Note: if we have selected a just-deleted database (due to using | ||||
| 		 * stale stats info), we'll fail and exit here. | ||||
| 		 */ | ||||
| 		InitPostgres(NULL, dbid, NULL, InvalidOid, dbname); | ||||
| 		InitPostgres(NULL, dbid, NULL, InvalidOid, dbname, false); | ||||
| 		SetProcessingMode(NormalProcessing); | ||||
| 		set_ps_display(dbname, false); | ||||
| 		ereport(DEBUG1, | ||||
|  | ||||
| @ -5582,7 +5582,7 @@ MaxLivePostmasterChildren(void) | ||||
|  * Connect background worker to a database. | ||||
|  */ | ||||
| void | ||||
| BackgroundWorkerInitializeConnection(const char *dbname, const char *username) | ||||
| BackgroundWorkerInitializeConnection(const char *dbname, const char *username, uint32 flags) | ||||
| { | ||||
| 	BackgroundWorker *worker = MyBgworkerEntry; | ||||
| 
 | ||||
| @ -5592,7 +5592,7 @@ BackgroundWorkerInitializeConnection(const char *dbname, const char *username) | ||||
| 				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), | ||||
| 				 errmsg("database connection requirement not indicated during registration"))); | ||||
| 
 | ||||
| 	InitPostgres(dbname, InvalidOid, username, InvalidOid, NULL); | ||||
| 	InitPostgres(dbname, InvalidOid, username, InvalidOid, NULL, (flags & BGWORKER_BYPASS_ALLOWCONN) != 0); | ||||
| 
 | ||||
| 	/* it had better not gotten out of "init" mode yet */ | ||||
| 	if (!IsInitProcessingMode()) | ||||
| @ -5605,7 +5605,7 @@ BackgroundWorkerInitializeConnection(const char *dbname, const char *username) | ||||
|  * Connect background worker to a database using OIDs. | ||||
|  */ | ||||
| void | ||||
| BackgroundWorkerInitializeConnectionByOid(Oid dboid, Oid useroid) | ||||
| BackgroundWorkerInitializeConnectionByOid(Oid dboid, Oid useroid, uint32 flags) | ||||
| { | ||||
| 	BackgroundWorker *worker = MyBgworkerEntry; | ||||
| 
 | ||||
| @ -5615,7 +5615,7 @@ BackgroundWorkerInitializeConnectionByOid(Oid dboid, Oid useroid) | ||||
| 				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), | ||||
| 				 errmsg("database connection requirement not indicated during registration"))); | ||||
| 
 | ||||
| 	InitPostgres(NULL, dboid, NULL, useroid, NULL); | ||||
| 	InitPostgres(NULL, dboid, NULL, useroid, NULL, (flags & BGWORKER_BYPASS_ALLOWCONN) != 0); | ||||
| 
 | ||||
| 	/* it had better not gotten out of "init" mode yet */ | ||||
| 	if (!IsInitProcessingMode()) | ||||
|  | ||||
| @ -901,7 +901,7 @@ ApplyLauncherMain(Datum main_arg) | ||||
| 	 * Establish connection to nailed catalogs (we only ever access | ||||
| 	 * pg_subscription). | ||||
| 	 */ | ||||
| 	BackgroundWorkerInitializeConnection(NULL, NULL); | ||||
| 	BackgroundWorkerInitializeConnection(NULL, NULL, 0); | ||||
| 
 | ||||
| 	/* Enter main loop */ | ||||
| 	for (;;) | ||||
|  | ||||
| @ -1544,7 +1544,8 @@ ApplyWorkerMain(Datum main_arg) | ||||
| 
 | ||||
| 	/* Connect to our database. */ | ||||
| 	BackgroundWorkerInitializeConnectionByOid(MyLogicalRepWorker->dbid, | ||||
| 											  MyLogicalRepWorker->userid); | ||||
| 											  MyLogicalRepWorker->userid, | ||||
| 											  0); | ||||
| 
 | ||||
| 	/* Load the subscription into persistent memory context. */ | ||||
| 	ApplyContext = AllocSetContextCreate(TopMemoryContext, | ||||
|  | ||||
| @ -3775,7 +3775,7 @@ PostgresMain(int argc, char *argv[], | ||||
| 	 * it inside InitPostgres() instead.  In particular, anything that | ||||
| 	 * involves database access should be there, not here. | ||||
| 	 */ | ||||
| 	InitPostgres(dbname, InvalidOid, username, InvalidOid, NULL); | ||||
| 	InitPostgres(dbname, InvalidOid, username, InvalidOid, NULL, false); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * If the PostmasterContext is still around, recycle the space; we don't | ||||
|  | ||||
| @ -66,7 +66,7 @@ | ||||
| static HeapTuple GetDatabaseTuple(const char *dbname); | ||||
| static HeapTuple GetDatabaseTupleByOid(Oid dboid); | ||||
| static void PerformAuthentication(Port *port); | ||||
| static void CheckMyDatabase(const char *name, bool am_superuser); | ||||
| static void CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connections); | ||||
| static void InitCommunication(void); | ||||
| static void ShutdownPostgres(int code, Datum arg); | ||||
| static void StatementTimeoutHandler(void); | ||||
| @ -290,7 +290,7 @@ PerformAuthentication(Port *port) | ||||
|  * CheckMyDatabase -- fetch information from the pg_database entry for our DB | ||||
|  */ | ||||
| static void | ||||
| CheckMyDatabase(const char *name, bool am_superuser) | ||||
| CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connections) | ||||
| { | ||||
| 	HeapTuple	tup; | ||||
| 	Form_pg_database dbform; | ||||
| @ -326,7 +326,7 @@ CheckMyDatabase(const char *name, bool am_superuser) | ||||
| 		/*
 | ||||
| 		 * Check that the database is currently allowing connections. | ||||
| 		 */ | ||||
| 		if (!dbform->datallowconn) | ||||
| 		if (!dbform->datallowconn && !override_allow_connections) | ||||
| 			ereport(FATAL, | ||||
| 					(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), | ||||
| 					 errmsg("database \"%s\" is not currently accepting connections", | ||||
| @ -563,7 +563,7 @@ BaseInit(void) | ||||
|  */ | ||||
| void | ||||
| InitPostgres(const char *in_dbname, Oid dboid, const char *username, | ||||
| 			 Oid useroid, char *out_dbname) | ||||
| 			 Oid useroid, char *out_dbname, bool override_allow_connections) | ||||
| { | ||||
| 	bool		bootstrap = IsBootstrapProcessingMode(); | ||||
| 	bool		am_superuser; | ||||
| @ -1006,7 +1006,7 @@ InitPostgres(const char *in_dbname, Oid dboid, const char *username, | ||||
| 	 * user is a superuser, so the above stuff has to happen first.) | ||||
| 	 */ | ||||
| 	if (!bootstrap) | ||||
| 		CheckMyDatabase(dbname, am_superuser); | ||||
| 		CheckMyDatabase(dbname, am_superuser, override_allow_connections); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Now process any command-line switches and any additional GUC variable | ||||
|  | ||||
| @ -421,7 +421,7 @@ extern AuxProcType MyAuxProcType; | ||||
| extern void pg_split_opts(char **argv, int *argcp, const char *optstr); | ||||
| extern void InitializeMaxBackends(void); | ||||
| extern void InitPostgres(const char *in_dbname, Oid dboid, const char *username, | ||||
| 			 Oid useroid, char *out_dbname); | ||||
| 			 Oid useroid, char *out_dbname, bool override_allow_connections); | ||||
| extern void BaseInit(void); | ||||
| 
 | ||||
| /* in utils/init/miscinit.c */ | ||||
|  | ||||
| @ -140,10 +140,13 @@ extern PGDLLIMPORT BackgroundWorker *MyBgworkerEntry; | ||||
|  * If dbname is NULL, connection is made to no specific database; | ||||
|  * only shared catalogs can be accessed. | ||||
|  */ | ||||
| extern void BackgroundWorkerInitializeConnection(const char *dbname, const char *username); | ||||
| extern void BackgroundWorkerInitializeConnection(const char *dbname, const char *username, uint32 flags); | ||||
| 
 | ||||
| /* Just like the above, but specifying database and user by OID. */ | ||||
| extern void BackgroundWorkerInitializeConnectionByOid(Oid dboid, Oid useroid); | ||||
| extern void BackgroundWorkerInitializeConnectionByOid(Oid dboid, Oid useroid, uint32 flags); | ||||
| 
 | ||||
| /* Flags to BackgroundWorkerInitializeConnection et al */ | ||||
| #define BGWORKER_BYPASS_ALLOWCONN 1 | ||||
| 
 | ||||
| /* Block/unblock signals in a background worker process */ | ||||
| extern void BackgroundWorkerBlockSignals(void); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user