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

Commitc76db55

Browse files
committed
Split pgstat_bestart() into three different routines
pgstat_bestart(), used post-authentication to set up a backend entryin the PgBackendStatus array, so as its data becomes visible inpg_stat_activity and related catalogs, has its logic divided into threeroutines with this commit, called in order at different steps of thebackend initialization:* pgstat_bestart_initial() sets up the backend entry with a minimalamount of information, reporting it with a new BackendState calledSTATE_STARTING while waiting for backend initialization and clientauthentication to complete. The main benefit that this offers isobservability, so as it is possible to monitor the backend activityduring authentication. This step happens earlier than in the logicprior to this commit. pgstat_beinit() happens earlier as well, beforeauthentication.* pgstat_bestart_security() reports the SSL/GSS status of theconnection, once authentication completes. Auxiliary processes, forexample, do not need to call this step, hence it is optional. Thisstep is called after performing authentication, same as previously.* pgstat_bestart_final() reports the user and database IDs, takes theentry out of STATE_STARTING, and reports its application_name. This iscalled as the last step of the three, once authentication completes.An injection point is added, with a test checking that the "starting"phase of a backend entry is visible in pg_stat_activity. Some follow-uppatches are planned to take advantage of this refactoring with moreinformation provided in backend entries during authentication (LDAPhanging was a problem for the author, initially).Author: Jacob Champion <jacob.champion@enterprisedb.com>Reviewed-by: Michael Paquier <michael@paquier.xyz>Reviewed-by: Andres Freund <andres@anarazel.de>Discussion:https://postgr.es/m/CAOYmi+=60deN20WDyCoHCiecgivJxr=98s7s7-C8SkXwrCfHXg@mail.gmail.com
1 parent40d3f82 commitc76db55

File tree

9 files changed

+272
-84
lines changed

9 files changed

+272
-84
lines changed

‎doc/src/sgml/monitoring.sgml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -899,6 +899,12 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser
899899
Current overall state of this backend.
900900
Possible values are:
901901
<itemizedlist>
902+
<listitem>
903+
<para>
904+
<literal>starting</literal>: The backend is in initial startup. Client
905+
authentication is performed during this phase.
906+
</para>
907+
</listitem>
902908
<listitem>
903909
<para>
904910
<literal>active</literal>: The backend is executing a query.

‎src/backend/postmaster/auxprocess.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ AuxiliaryProcessMainCommon(void)
7878

7979
/* Initialize backend status information */
8080
pgstat_beinit();
81-
pgstat_bestart();
81+
pgstat_bestart_initial();
82+
pgstat_bestart_final();
8283

8384
/* register a before-shutdown callback for LWLock cleanup */
8485
before_shmem_exit(ShutdownAuxiliaryProcess,0);

‎src/backend/utils/activity/backend_status.c

Lines changed: 138 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -255,29 +255,22 @@ pgstat_beinit(void)
255255

256256

257257
/* ----------
258-
*pgstat_bestart() -
258+
*pgstat_bestart_initial() -
259259
*
260-
*Initialize this backend's entry in the PgBackendStatus array.
261-
*Called from InitPostgres.
260+
*Initialize this backend's entry in the PgBackendStatus array. Called
261+
* from InitPostgres and AuxiliaryProcessMain.
262262
*
263-
*Apart from auxiliary processes, MyDatabaseId, session userid, and
264-
*application_name must already be set (hence, this cannot be combined
265-
*with pgstat_beinit). Note also that we must be inside a transaction
266-
*if this isn't an aux process, as we may need to do encoding conversion
267-
*on some strings.
268-
*----------
263+
* Clears out a new pgstat entry, initializing it to suitable defaults and
264+
* reporting STATE_STARTING. Backends should continue filling in any
265+
* transport security details as needed with pgstat_bestart_security(), and
266+
* must finally exit STATE_STARTING by calling pgstat_bestart_final().
267+
* ----------
269268
*/
270269
void
271-
pgstat_bestart(void)
270+
pgstat_bestart_initial(void)
272271
{
273272
volatilePgBackendStatus*vbeentry=MyBEEntry;
274273
PgBackendStatuslbeentry;
275-
#ifdefUSE_SSL
276-
PgBackendSSLStatuslsslstatus;
277-
#endif
278-
#ifdefENABLE_GSS
279-
PgBackendGSSStatuslgssstatus;
280-
#endif
281274

282275
/* pgstats state must be initialized from pgstat_beinit() */
283276
Assert(vbeentry!=NULL);
@@ -297,14 +290,6 @@ pgstat_bestart(void)
297290
unvolatize(PgBackendStatus*,vbeentry),
298291
sizeof(PgBackendStatus));
299292

300-
/* These structs can just start from zeroes each time, though */
301-
#ifdefUSE_SSL
302-
memset(&lsslstatus,0,sizeof(lsslstatus));
303-
#endif
304-
#ifdefENABLE_GSS
305-
memset(&lgssstatus,0,sizeof(lgssstatus));
306-
#endif
307-
308293
/*
309294
* Now fill in all the fields of lbeentry, except for strings that are
310295
* out-of-line data. Those have to be handled separately, below.
@@ -315,15 +300,8 @@ pgstat_bestart(void)
315300
lbeentry.st_activity_start_timestamp=0;
316301
lbeentry.st_state_start_timestamp=0;
317302
lbeentry.st_xact_start_timestamp=0;
318-
lbeentry.st_databaseid=MyDatabaseId;
319-
320-
/* We have userid for client-backends, wal-sender and bgworker processes */
321-
if (lbeentry.st_backendType==B_BACKEND
322-
||lbeentry.st_backendType==B_WAL_SENDER
323-
||lbeentry.st_backendType==B_BG_WORKER)
324-
lbeentry.st_userid=GetSessionUserId();
325-
else
326-
lbeentry.st_userid=InvalidOid;
303+
lbeentry.st_databaseid=InvalidOid;
304+
lbeentry.st_userid=InvalidOid;
327305

328306
/*
329307
* We may not have a MyProcPort (eg, if this is the autovacuum process).
@@ -336,46 +314,10 @@ pgstat_bestart(void)
336314
else
337315
MemSet(&lbeentry.st_clientaddr,0,sizeof(lbeentry.st_clientaddr));
338316

339-
#ifdefUSE_SSL
340-
if (MyProcPort&&MyProcPort->ssl_in_use)
341-
{
342-
lbeentry.st_ssl= true;
343-
lsslstatus.ssl_bits=be_tls_get_cipher_bits(MyProcPort);
344-
strlcpy(lsslstatus.ssl_version,be_tls_get_version(MyProcPort),NAMEDATALEN);
345-
strlcpy(lsslstatus.ssl_cipher,be_tls_get_cipher(MyProcPort),NAMEDATALEN);
346-
be_tls_get_peer_subject_name(MyProcPort,lsslstatus.ssl_client_dn,NAMEDATALEN);
347-
be_tls_get_peer_serial(MyProcPort,lsslstatus.ssl_client_serial,NAMEDATALEN);
348-
be_tls_get_peer_issuer_name(MyProcPort,lsslstatus.ssl_issuer_dn,NAMEDATALEN);
349-
}
350-
else
351-
{
352-
lbeentry.st_ssl= false;
353-
}
354-
#else
355317
lbeentry.st_ssl= false;
356-
#endif
357-
358-
#ifdefENABLE_GSS
359-
if (MyProcPort&&MyProcPort->gss!=NULL)
360-
{
361-
constchar*princ=be_gssapi_get_princ(MyProcPort);
362-
363-
lbeentry.st_gss= true;
364-
lgssstatus.gss_auth=be_gssapi_get_auth(MyProcPort);
365-
lgssstatus.gss_enc=be_gssapi_get_enc(MyProcPort);
366-
lgssstatus.gss_delegation=be_gssapi_get_delegation(MyProcPort);
367-
if (princ)
368-
strlcpy(lgssstatus.gss_princ,princ,NAMEDATALEN);
369-
}
370-
else
371-
{
372-
lbeentry.st_gss= false;
373-
}
374-
#else
375318
lbeentry.st_gss= false;
376-
#endif
377319

378-
lbeentry.st_state=STATE_UNDEFINED;
320+
lbeentry.st_state=STATE_STARTING;
379321
lbeentry.st_progress_command=PROGRESS_COMMAND_INVALID;
380322
lbeentry.st_progress_command_target=InvalidOid;
381323
lbeentry.st_query_id=UINT64CONST(0);
@@ -417,14 +359,138 @@ pgstat_bestart(void)
417359
lbeentry.st_clienthostname[NAMEDATALEN-1]='\0';
418360
lbeentry.st_activity_raw[pgstat_track_activity_query_size-1]='\0';
419361

362+
/* These structs can just start from zeroes each time */
420363
#ifdefUSE_SSL
421-
memcpy(lbeentry.st_sslstatus,&lsslstatus,sizeof(PgBackendSSLStatus));
364+
memset(lbeentry.st_sslstatus,0,sizeof(PgBackendSSLStatus));
422365
#endif
423366
#ifdefENABLE_GSS
424-
memcpy(lbeentry.st_gssstatus,&lgssstatus,sizeof(PgBackendGSSStatus));
367+
memset(lbeentry.st_gssstatus,0,sizeof(PgBackendGSSStatus));
425368
#endif
426369

427370
PGSTAT_END_WRITE_ACTIVITY(vbeentry);
371+
}
372+
373+
/* ----------
374+
* pgstat_bestart_security() -
375+
*
376+
* Fill in SSL and GSS information for the pgstat entry. This is the second
377+
* optional step taken when filling a backend's entry, not required for
378+
* auxiliary processes.
379+
*
380+
* This should only be called from backends with a MyProcPort.
381+
* ----------
382+
*/
383+
void
384+
pgstat_bestart_security(void)
385+
{
386+
volatilePgBackendStatus*beentry=MyBEEntry;
387+
boolssl= false;
388+
boolgss= false;
389+
#ifdefUSE_SSL
390+
PgBackendSSLStatuslsslstatus;
391+
PgBackendSSLStatus*st_sslstatus;
392+
#endif
393+
#ifdefENABLE_GSS
394+
PgBackendGSSStatuslgssstatus;
395+
PgBackendGSSStatus*st_gssstatus;
396+
#endif
397+
398+
/* pgstats state must be initialized from pgstat_beinit() */
399+
Assert(beentry!=NULL);
400+
Assert(MyProcPort);/* otherwise there's no point */
401+
402+
#ifdefUSE_SSL
403+
st_sslstatus=beentry->st_sslstatus;
404+
memset(&lsslstatus,0,sizeof(lsslstatus));
405+
406+
if (MyProcPort->ssl_in_use)
407+
{
408+
ssl= true;
409+
lsslstatus.ssl_bits=be_tls_get_cipher_bits(MyProcPort);
410+
strlcpy(lsslstatus.ssl_version,be_tls_get_version(MyProcPort),NAMEDATALEN);
411+
strlcpy(lsslstatus.ssl_cipher,be_tls_get_cipher(MyProcPort),NAMEDATALEN);
412+
be_tls_get_peer_subject_name(MyProcPort,lsslstatus.ssl_client_dn,NAMEDATALEN);
413+
be_tls_get_peer_serial(MyProcPort,lsslstatus.ssl_client_serial,NAMEDATALEN);
414+
be_tls_get_peer_issuer_name(MyProcPort,lsslstatus.ssl_issuer_dn,NAMEDATALEN);
415+
}
416+
#endif
417+
418+
#ifdefENABLE_GSS
419+
st_gssstatus=beentry->st_gssstatus;
420+
memset(&lgssstatus,0,sizeof(lgssstatus));
421+
422+
if (MyProcPort->gss!=NULL)
423+
{
424+
constchar*princ=be_gssapi_get_princ(MyProcPort);
425+
426+
gss= true;
427+
lgssstatus.gss_auth=be_gssapi_get_auth(MyProcPort);
428+
lgssstatus.gss_enc=be_gssapi_get_enc(MyProcPort);
429+
lgssstatus.gss_delegation=be_gssapi_get_delegation(MyProcPort);
430+
if (princ)
431+
strlcpy(lgssstatus.gss_princ,princ,NAMEDATALEN);
432+
}
433+
#endif
434+
435+
/*
436+
* Update my status entry, following the protocol of bumping
437+
* st_changecount before and after. We use a volatile pointer here to
438+
* ensure the compiler doesn't try to get cute.
439+
*/
440+
PGSTAT_BEGIN_WRITE_ACTIVITY(beentry);
441+
442+
beentry->st_ssl=ssl;
443+
beentry->st_gss=gss;
444+
445+
#ifdefUSE_SSL
446+
memcpy(st_sslstatus,&lsslstatus,sizeof(PgBackendSSLStatus));
447+
#endif
448+
#ifdefENABLE_GSS
449+
memcpy(st_gssstatus,&lgssstatus,sizeof(PgBackendGSSStatus));
450+
#endif
451+
452+
PGSTAT_END_WRITE_ACTIVITY(beentry);
453+
}
454+
455+
/* ----------
456+
* pgstat_bestart_final() -
457+
*
458+
* Finalizes the state of this backend's entry by filling in the user and
459+
* database IDs, clearing STATE_STARTING, and reporting the application_name.
460+
*
461+
* We must be inside a transaction if this is not an auxiliary process, as
462+
* we may need to do encoding conversion.
463+
* ----------
464+
*/
465+
void
466+
pgstat_bestart_final(void)
467+
{
468+
volatilePgBackendStatus*beentry=MyBEEntry;
469+
Oiduserid;
470+
471+
/* pgstats state must be initialized from pgstat_beinit() */
472+
Assert(beentry!=NULL);
473+
474+
/* We have userid for client-backends, wal-sender and bgworker processes */
475+
if (MyBackendType==B_BACKEND
476+
||MyBackendType==B_WAL_SENDER
477+
||MyBackendType==B_BG_WORKER)
478+
userid=GetSessionUserId();
479+
else
480+
userid=InvalidOid;
481+
482+
/*
483+
* Update my status entry, following the protocol of bumping
484+
* st_changecount before and after. We use a volatile pointer here to
485+
* ensure the compiler doesn't try to get cute.
486+
*/
487+
PGSTAT_BEGIN_WRITE_ACTIVITY(beentry);
488+
489+
beentry->st_databaseid=MyDatabaseId;
490+
beentry->st_userid=userid;
491+
beentry->st_state=STATE_UNDEFINED;
492+
493+
PGSTAT_END_WRITE_ACTIVITY(beentry);
428494

429495
/* Create the backend statistics entry */
430496
if (pgstat_tracks_backend_bktype(MyBackendType))

‎src/backend/utils/adt/pgstatfuncs.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,9 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
393393

394394
switch (beentry->st_state)
395395
{
396+
caseSTATE_STARTING:
397+
values[4]=CStringGetTextDatum("starting");
398+
break;
396399
caseSTATE_IDLE:
397400
values[4]=CStringGetTextDatum("idle");
398401
break;

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

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
#include"utils/builtins.h"
6060
#include"utils/fmgroids.h"
6161
#include"utils/guc_hooks.h"
62+
#include"utils/injection_point.h"
6263
#include"utils/memutils.h"
6364
#include"utils/pg_locale.h"
6465
#include"utils/portal.h"
@@ -718,6 +719,20 @@ InitPostgres(const char *in_dbname, Oid dboid,
718719
*/
719720
InitProcessPhase2();
720721

722+
/* Initialize status reporting */
723+
pgstat_beinit();
724+
725+
/*
726+
* And initialize an entry in the PgBackendStatus array. That way, if
727+
* LWLocks or third-party authentication should happen to hang, it is
728+
* possible to retrieve some information about what is going on.
729+
*/
730+
if (!bootstrap)
731+
{
732+
pgstat_bestart_initial();
733+
INJECTION_POINT("init-pre-auth");
734+
}
735+
721736
/*
722737
* Initialize my entry in the shared-invalidation manager's array of
723738
* per-backend data.
@@ -786,9 +801,6 @@ InitPostgres(const char *in_dbname, Oid dboid,
786801
/* Initialize portal manager */
787802
EnablePortalManager();
788803

789-
/* Initialize status reporting */
790-
pgstat_beinit();
791-
792804
/*
793805
* Load relcache entries for the shared system catalogs. This must create
794806
* at least entries for pg_database and catalogs used for authentication.
@@ -809,8 +821,8 @@ InitPostgres(const char *in_dbname, Oid dboid,
809821
/* The autovacuum launcher is done here */
810822
if (AmAutoVacuumLauncherProcess())
811823
{
812-
/*reportthisbackend in the PgBackendStatus array */
813-
pgstat_bestart();
824+
/*fill in the remainder ofthisentry in the PgBackendStatus array */
825+
pgstat_bestart_final();
814826

815827
return;
816828
}
@@ -884,6 +896,14 @@ InitPostgres(const char *in_dbname, Oid dboid,
884896
am_superuser=superuser();
885897
}
886898

899+
/* Report any SSL/GSS details for the session. */
900+
if (MyProcPort!=NULL)
901+
{
902+
Assert(!bootstrap);
903+
904+
pgstat_bestart_security();
905+
}
906+
887907
/*
888908
* Binary upgrades only allowed super-user connections
889909
*/
@@ -953,8 +973,8 @@ InitPostgres(const char *in_dbname, Oid dboid,
953973
/* initialize client encoding */
954974
InitializeClientEncoding();
955975

956-
/*reportthisbackend in the PgBackendStatus array */
957-
pgstat_bestart();
976+
/*fill in the remainder ofthisentry in the PgBackendStatus array */
977+
pgstat_bestart_final();
958978

959979
/* close the transaction we started above */
960980
CommitTransactionCommand();
@@ -997,7 +1017,7 @@ InitPostgres(const char *in_dbname, Oid dboid,
9971017
*/
9981018
if (!bootstrap)
9991019
{
1000-
pgstat_bestart();
1020+
pgstat_bestart_final();
10011021
CommitTransactionCommand();
10021022
}
10031023
return;
@@ -1197,9 +1217,9 @@ InitPostgres(const char *in_dbname, Oid dboid,
11971217
if ((flags&INIT_PG_LOAD_SESSION_LIBS)!=0)
11981218
process_session_preload_libraries();
11991219

1200-
/*reportthisbackend in the PgBackendStatus array */
1220+
/*fill in the remainder ofthisentry in the PgBackendStatus array */
12011221
if (!bootstrap)
1202-
pgstat_bestart();
1222+
pgstat_bestart_final();
12031223

12041224
/* close the transaction we started above */
12051225
if (!bootstrap)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp