pgstat's on-proc-exit hook has to execute after the last transaction commit

or abort within a backend; rearrange InitPostgres processing to make it so.
Revealed by just-added Asserts along with ECPG regression tests (hm, I wonder
why the core regression tests didn't expose it?).  This possibly is another
reason for missing stats updates ...
This commit is contained in:
Tom Lane 2007-05-27 05:37:50 +00:00
parent 77947c51c0
commit 8d675c85c5
3 changed files with 36 additions and 18 deletions

View File

@ -13,7 +13,7 @@
* *
* Copyright (c) 2001-2007, PostgreSQL Global Development Group * Copyright (c) 2001-2007, PostgreSQL Global Development Group
* *
* $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.156 2007/05/27 03:50:39 tgl Exp $ * $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.157 2007/05/27 05:37:49 tgl Exp $
* ---------- * ----------
*/ */
#include "postgres.h" #include "postgres.h"
@ -1771,28 +1771,45 @@ CreateSharedBackendStatus(void)
} }
/* ----------
* pgstat_initialize() -
*
* Initialize pgstats state, and set up our on-proc-exit hook.
* Called from InitPostgres. MyBackendId must be set,
* but we must not have started any transaction yet (since the
* exit hook must run after the last transaction exit).
* ----------
*/
void
pgstat_initialize(void)
{
/* Initialize MyBEEntry */
Assert(MyBackendId >= 1 && MyBackendId <= MaxBackends);
MyBEEntry = &BackendStatusArray[MyBackendId - 1];
/* Set up a process-exit hook to clean up */
on_shmem_exit(pgstat_beshutdown_hook, 0);
}
/* ---------- /* ----------
* pgstat_bestart() - * pgstat_bestart() -
* *
* Initialize this backend's entry in the PgBackendStatus array, * Initialize this backend's entry in the PgBackendStatus array.
* and set up an on-proc-exit hook that will clear it again. * Called from InitPostgres. MyDatabaseId and session userid must be set
* Called from InitPostgres. MyBackendId and MyDatabaseId must be set. * (hence, this cannot be combined with pgstat_initialize).
* ---------- * ----------
*/ */
void void
pgstat_bestart(void) pgstat_bestart(void)
{ {
volatile PgBackendStatus *beentry;
TimestampTz proc_start_timestamp; TimestampTz proc_start_timestamp;
Oid userid; Oid userid;
SockAddr clientaddr; SockAddr clientaddr;
volatile PgBackendStatus *beentry;
Assert(MyBackendId >= 1 && MyBackendId <= MaxBackends);
MyBEEntry = &BackendStatusArray[MyBackendId - 1];
/* /*
* To minimize the time spent modifying the entry, fetch all the needed * To minimize the time spent modifying the PgBackendStatus entry,
* data first. * fetch all the needed data first.
* *
* If we have a MyProcPort, use its session start time (for consistency, * If we have a MyProcPort, use its session start time (for consistency,
* and to save a kernel call). * and to save a kernel call).
@ -1839,11 +1856,6 @@ pgstat_bestart(void)
beentry->st_changecount++; beentry->st_changecount++;
Assert((beentry->st_changecount & 1) == 0); Assert((beentry->st_changecount & 1) == 0);
/*
* Set up a process-exit hook to clean up.
*/
on_shmem_exit(pgstat_beshutdown_hook, 0);
} }
/* /*

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.175 2007/03/13 00:33:42 tgl Exp $ * $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.176 2007/05/27 05:37:49 tgl Exp $
* *
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
@ -435,6 +435,10 @@ InitPostgres(const char *in_dbname, Oid dboid, const char *username,
/* Initialize portal manager */ /* Initialize portal manager */
EnablePortalManager(); EnablePortalManager();
/* Initialize stats collection --- must happen before first xact */
if (!bootstrap)
pgstat_initialize();
/* /*
* Set up process-exit callback to do pre-shutdown cleanup. This has to * Set up process-exit callback to do pre-shutdown cleanup. This has to
* be after we've initialized all the low-level modules like the buffer * be after we've initialized all the low-level modules like the buffer
@ -587,7 +591,7 @@ InitPostgres(const char *in_dbname, Oid dboid, const char *username,
/* initialize client encoding */ /* initialize client encoding */
InitializeClientEncoding(); InitializeClientEncoding();
/* initialize statistics collection for this backend */ /* report this backend in the PgBackendStatus array */
if (!bootstrap) if (!bootstrap)
pgstat_bestart(); pgstat_bestart();

View File

@ -5,7 +5,7 @@
* *
* Copyright (c) 2001-2007, PostgreSQL Global Development Group * Copyright (c) 2001-2007, PostgreSQL Global Development Group
* *
* $PostgreSQL: pgsql/src/include/pgstat.h,v 1.59 2007/05/27 03:50:39 tgl Exp $ * $PostgreSQL: pgsql/src/include/pgstat.h,v 1.60 2007/05/27 05:37:50 tgl Exp $
* ---------- * ----------
*/ */
#ifndef PGSTAT_H #ifndef PGSTAT_H
@ -501,7 +501,9 @@ extern void pgstat_report_analyze(Oid tableoid, bool shared,
PgStat_Counter livetuples, PgStat_Counter livetuples,
PgStat_Counter deadtuples); PgStat_Counter deadtuples);
extern void pgstat_initialize(void);
extern void pgstat_bestart(void); extern void pgstat_bestart(void);
extern void pgstat_report_activity(const char *what); extern void pgstat_report_activity(const char *what);
extern void pgstat_report_txn_timestamp(TimestampTz tstamp); extern void pgstat_report_txn_timestamp(TimestampTz tstamp);
extern void pgstat_report_waiting(bool waiting); extern void pgstat_report_waiting(bool waiting);