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

Commitb35617d

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 parent7a08f78 commitb35617d

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
@@ -354,7 +354,7 @@ BootstrapModeMain(int argc, char *argv[], bool check_only)
354354
if (pg_link_canary_is_frontend())
355355
elog(ERROR,"backend is incorrectly linked to frontend functions");
356356

357-
InitPostgres(NULL,InvalidOid,NULL,InvalidOid,NULL, false);
357+
InitPostgres(NULL,InvalidOid,NULL,InvalidOid,false, false,NULL);
358358

359359
/* Initialize stuff for bootstrap-file processing */
360360
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
@@ -5654,7 +5654,11 @@ BackgroundWorkerInitializeConnection(const char *dbname, const char *username, u
56545654
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
56555655
errmsg("database connection requirement not indicated during registration")));
56565656

5657-
InitPostgres(dbname,InvalidOid,username,InvalidOid,NULL, (flags&BGWORKER_BYPASS_ALLOWCONN)!=0);
5657+
InitPostgres(dbname,InvalidOid,/* database to connect to */
5658+
username,InvalidOid,/* role to connect as */
5659+
false,/* never honor session_preload_libraries */
5660+
(flags&BGWORKER_BYPASS_ALLOWCONN)!=0,/* ignore datallowconn? */
5661+
NULL);/* no out_dbname */
56585662

56595663
/* it had better not gotten out of "init" mode yet */
56605664
if (!IsInitProcessingMode())
@@ -5677,7 +5681,11 @@ BackgroundWorkerInitializeConnectionByOid(Oid dboid, Oid useroid, uint32 flags)
56775681
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
56785682
errmsg("database connection requirement not indicated during registration")));
56795683

5680-
InitPostgres(NULL,dboid,NULL,useroid,NULL, (flags&BGWORKER_BYPASS_ALLOWCONN)!=0);
5684+
InitPostgres(NULL,dboid,/* database to connect to */
5685+
NULL,useroid,/* role to connect as */
5686+
false,/* never honor session_preload_libraries */
5687+
(flags&BGWORKER_BYPASS_ALLOWCONN)!=0,/* ignore datallowconn? */
5688+
NULL);/* no out_dbname */
56815689

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

‎src/backend/tcop/postgres.c

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4076,7 +4076,11 @@ PostgresMain(const char *dbname, const char *username)
40764076
* it inside InitPostgres() instead. In particular, anything that
40774077
* involves database access should be there, not here.
40784078
*/
4079-
InitPostgres(dbname,InvalidOid,username,InvalidOid,NULL, false);
4079+
InitPostgres(dbname,InvalidOid,/* database to connect to */
4080+
username,InvalidOid,/* role to connect as */
4081+
!am_walsender,/* honor session_preload_libraries? */
4082+
false,/* don't ignore datallowconn */
4083+
NULL);/* no out_dbname */
40804084

40814085
/*
40824086
* If the PostmasterContext is still around, recycle the space; we don't
@@ -4112,12 +4116,6 @@ PostgresMain(const char *dbname, const char *username)
41124116
if (am_walsender)
41134117
InitWalSender();
41144118

4115-
/*
4116-
* process any libraries that should be preloaded at backend start (this
4117-
* likewise can't be done until GUC settings are complete)
4118-
*/
4119-
process_session_preload_libraries();
4120-
41214119
/*
41224120
* Send this backend's cancellation info to the frontend.
41234121
*/

‎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
@@ -449,8 +449,11 @@ extern PGDLLIMPORT AuxProcType MyAuxProcType;
449449
/* in utils/init/postinit.c */
450450
externvoidpg_split_opts(char**argv,int*argcp,constchar*optstr);
451451
externvoidInitializeMaxBackends(void);
452-
externvoidInitPostgres(constchar*in_dbname,Oiddboid,constchar*username,
453-
Oiduseroid,char*out_dbname,booloverride_allow_connections);
452+
externvoidInitPostgres(constchar*in_dbname,Oiddboid,
453+
constchar*username,Oiduseroid,
454+
boolload_session_libraries,
455+
booloverride_allow_connections,
456+
char*out_dbname);
454457
externvoidBaseInit(void);
455458

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

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp