Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit31ed3cf

Browse files
committed
Process session_preload_libraries within InitPostgres's transaction.
Previously we did this after InitPostgres, at a somewhat randomly chosenplace within PostgresMain. However, since commita0ffa88 doing thisoutside a transaction can cause a crash, if we need to check permissionswhile replacing a placeholder GUC. (Besides which, a preloaded librarycould itself want to do database access within _PG_init.)To avoid needing an additional transaction start/end in every session,move the process_session_preload_libraries call to within InitPostgres'stransaction. That requires teaching the code not to call it whenInitPostgres is called from somewhere other than PostgresMain, sincewe don't want session_preload_libraries to affect background workers.The most future-proof solution here seems to be to add an additionalflag parameter to InitPostgres; fortunately, we're not yet very worriedabout API stability for v15.Doing this also exposed the fact that we're currently honoringsession_preload_libraries in walsenders, even those not connected toany database. This seems, at minimum, a POLA violation: walsendersare not interactive sessions. Let's stop doing that.(All these comments also apply to local_preload_libraries, of course.)Per report from Gurjeet Singh (thanks also to Nathan Bossart and KyotaroHoriguchi for review). Backpatch to v15 wherea0ffa88 came in.Discussion:https://postgr.es/m/CABwTF4VEpwTHhRQ+q5MiC5ucngN-whN-PdcKeufX7eLSoAfbZA@mail.gmail.com
1 parent19f8232 commit31ed3cf

File tree

6 files changed

+64
-25
lines changed

6 files changed

+64
-25
lines changed

‎src/backend/bootstrap/bootstrap.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ BootstrapModeMain(int argc, char *argv[], bool check_only)
355355
if (pg_link_canary_is_frontend())
356356
elog(ERROR,"backend is incorrectly linked to frontend functions");
357357

358-
InitPostgres(NULL,InvalidOid,NULL,InvalidOid,NULL, false);
358+
InitPostgres(NULL,InvalidOid,NULL,InvalidOid,false, false,NULL);
359359

360360
/* Initialize stuff for bootstrap-file processing */
361361
for (i=0;i<MAXATTR;i++)

‎src/backend/postmaster/autovacuum.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,7 @@ AutoVacLauncherMain(int argc, char *argv[])
475475
/* Early initialization */
476476
BaseInit();
477477

478-
InitPostgres(NULL,InvalidOid,NULL,InvalidOid,NULL, false);
478+
InitPostgres(NULL,InvalidOid,NULL,InvalidOid,false, false,NULL);
479479

480480
SetProcessingMode(NormalProcessing);
481481

@@ -1694,12 +1694,13 @@ AutoVacWorkerMain(int argc, char *argv[])
16941694
pgstat_report_autovac(dbid);
16951695

16961696
/*
1697-
* Connect to the selected database
1697+
* Connect to the selected database, specifying no particular user
16981698
*
16991699
* Note: if we have selected a just-deleted database (due to using
17001700
* stale stats info), we'll fail and exit here.
17011701
*/
1702-
InitPostgres(NULL,dbid,NULL,InvalidOid,dbname, false);
1702+
InitPostgres(NULL,dbid,NULL,InvalidOid, false, false,
1703+
dbname);
17031704
SetProcessingMode(NormalProcessing);
17041705
set_ps_display(dbname);
17051706
ereport(DEBUG1,

‎src/backend/postmaster/postmaster.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5668,7 +5668,11 @@ BackgroundWorkerInitializeConnection(const char *dbname, const char *username, u
56685668
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
56695669
errmsg("database connection requirement not indicated during registration")));
56705670

5671-
InitPostgres(dbname,InvalidOid,username,InvalidOid,NULL, (flags&BGWORKER_BYPASS_ALLOWCONN)!=0);
5671+
InitPostgres(dbname,InvalidOid,/* database to connect to */
5672+
username,InvalidOid,/* role to connect as */
5673+
false,/* never honor session_preload_libraries */
5674+
(flags&BGWORKER_BYPASS_ALLOWCONN)!=0,/* ignore datallowconn? */
5675+
NULL);/* no out_dbname */
56725676

56735677
/* it had better not gotten out of "init" mode yet */
56745678
if (!IsInitProcessingMode())
@@ -5691,7 +5695,11 @@ BackgroundWorkerInitializeConnectionByOid(Oid dboid, Oid useroid, uint32 flags)
56915695
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
56925696
errmsg("database connection requirement not indicated during registration")));
56935697

5694-
InitPostgres(NULL,dboid,NULL,useroid,NULL, (flags&BGWORKER_BYPASS_ALLOWCONN)!=0);
5698+
InitPostgres(NULL,dboid,/* database to connect to */
5699+
NULL,useroid,/* role to connect as */
5700+
false,/* never honor session_preload_libraries */
5701+
(flags&BGWORKER_BYPASS_ALLOWCONN)!=0,/* ignore datallowconn? */
5702+
NULL);/* no out_dbname */
56955703

56965704
/* it had better not gotten out of "init" mode yet */
56975705
if (!IsInitProcessingMode())

‎src/backend/tcop/postgres.c

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4152,7 +4152,11 @@ PostgresMain(const char *dbname, const char *username)
41524152
* it inside InitPostgres() instead. In particular, anything that
41534153
* involves database access should be there, not here.
41544154
*/
4155-
InitPostgres(dbname,InvalidOid,username,InvalidOid,NULL, false);
4155+
InitPostgres(dbname,InvalidOid,/* database to connect to */
4156+
username,InvalidOid,/* role to connect as */
4157+
!am_walsender,/* honor session_preload_libraries? */
4158+
false,/* don't ignore datallowconn */
4159+
NULL);/* no out_dbname */
41564160

41574161
/*
41584162
* If the PostmasterContext is still around, recycle the space; we don't
@@ -4188,12 +4192,6 @@ PostgresMain(const char *dbname, const char *username)
41884192
if (am_walsender)
41894193
InitWalSender();
41904194

4191-
/*
4192-
* process any libraries that should be preloaded at backend start (this
4193-
* likewise can't be done until GUC settings are complete)
4194-
*/
4195-
process_session_preload_libraries();
4196-
41974195
/*
41984196
* Send this backend's cancellation info to the frontend.
41994197
*/

‎src/backend/utils/init/postinit.c

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -622,29 +622,48 @@ BaseInit(void)
622622
* InitPostgres
623623
*Initialize POSTGRES.
624624
*
625+
* Parameters:
626+
*in_dbname, dboid: specify database to connect to, as described below
627+
*username, useroid: specify role to connect as, as described below
628+
*load_session_libraries: TRUE to honor [session|local]_preload_libraries
629+
*override_allow_connections: TRUE to connect despite !datallowconn
630+
*out_dbname: optional output parameter, see below; pass NULL if not used
631+
*
625632
* The database can be specified by name, using the in_dbname parameter, or by
626-
* OID, using the dboid parameter. In the latter case, the actual database
633+
* OID, using the dboid parameter. Specify NULL or InvalidOid respectively
634+
* for the unused parameter. If dboid is provided, the actual database
627635
* name can be returned to the caller in out_dbname. If out_dbname isn't
628636
* NULL, it must point to a buffer of size NAMEDATALEN.
629637
*
630-
* Similarly, theusername can be passed by name, using the username parameter,
638+
* Similarly, therole can be passed by name, using the username parameter,
631639
* or by OID using the useroid parameter.
632640
*
633-
* In bootstrap mode no parameters are used. The autovacuum launcher process
634-
* doesn't use any parameters either, because it only goes far enough to be
635-
* able to read pg_database; it doesn't connect to any particular database.
636-
* In walsender mode only username is used.
641+
* In bootstrap mode the database and username parameters are NULL/InvalidOid.
642+
* The autovacuum launcher process doesn't specify these parameters either,
643+
* because it only goes far enough to be able to read pg_database; it doesn't
644+
* connect to any particular database. An autovacuum worker specifies a
645+
* database but not a username; conversely, a physical walsender specifies
646+
* username but not database.
647+
*
648+
* By convention, load_session_libraries should be passed as true in
649+
* "interactive" sessions (including standalone backends), but false in
650+
* background processes such as autovacuum. Note in particular that it
651+
* shouldn't be true in parallel worker processes; those have another
652+
* mechanism for replicating their leader's set of loaded libraries.
637653
*
638-
*As of PostgreSQL 8.2, weexpect InitProcess() was already called, so we
639-
*already have aPGPROC struct ... but it's not completely filled in yet.
654+
*WeexpectthatInitProcess() was already called, so we already have a
655+
* PGPROC struct ... but it's not completely filled in yet.
640656
*
641657
* Note:
642658
*Be very careful with the order of calls in the InitPostgres function.
643659
* --------------------------------
644660
*/
645661
void
646-
InitPostgres(constchar*in_dbname,Oiddboid,constchar*username,
647-
Oiduseroid,char*out_dbname,booloverride_allow_connections)
662+
InitPostgres(constchar*in_dbname,Oiddboid,
663+
constchar*username,Oiduseroid,
664+
boolload_session_libraries,
665+
booloverride_allow_connections,
666+
char*out_dbname)
648667
{
649668
boolbootstrap=IsBootstrapProcessingMode();
650669
boolam_superuser;
@@ -1108,6 +1127,16 @@ InitPostgres(const char *in_dbname, Oid dboid, const char *username,
11081127
/* Initialize this backend's session state. */
11091128
InitializeSession();
11101129

1130+
/*
1131+
* If this is an interactive session, load any libraries that should be
1132+
* preloaded at backend start. Since those are determined by GUCs, this
1133+
* can't happen until GUC settings are complete, but we want it to happen
1134+
* during the initial transaction in case anything that requires database
1135+
* access needs to be done.
1136+
*/
1137+
if (load_session_libraries)
1138+
process_session_preload_libraries();
1139+
11111140
/* report this backend in the PgBackendStatus array */
11121141
if (!bootstrap)
11131142
pgstat_bestart();

‎src/include/miscadmin.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -457,8 +457,11 @@ extern PGDLLIMPORT AuxProcType MyAuxProcType;
457457
/* in utils/init/postinit.c */
458458
externvoidpg_split_opts(char**argv,int*argcp,constchar*optstr);
459459
externvoidInitializeMaxBackends(void);
460-
externvoidInitPostgres(constchar*in_dbname,Oiddboid,constchar*username,
461-
Oiduseroid,char*out_dbname,booloverride_allow_connections);
460+
externvoidInitPostgres(constchar*in_dbname,Oiddboid,
461+
constchar*username,Oiduseroid,
462+
boolload_session_libraries,
463+
booloverride_allow_connections,
464+
char*out_dbname);
462465
externvoidBaseInit(void);
463466

464467
/* in utils/init/miscinit.c */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp