From: Tom Lane Date: Sun, 27 May 2007 05:37:50 +0000 (+0000) Subject: pgstat's on-proc-exit hook has to execute after the last transaction commit X-Git-Tag: REL8_3_BETA1~645 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8d675c85c58065076b673ea8ee61fa1285748ee3;p=postgresql 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 ... --- diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c index b41a16de44..2870d33585 100644 --- a/src/backend/postmaster/pgstat.c +++ b/src/backend/postmaster/pgstat.c @@ -13,7 +13,7 @@ * * 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" @@ -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() - * - * 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. MyBackendId and MyDatabaseId must be set. + * Initialize this backend's entry in the PgBackendStatus array. + * Called from InitPostgres. MyDatabaseId and session userid must be set + * (hence, this cannot be combined with pgstat_initialize). * ---------- */ void pgstat_bestart(void) { - volatile PgBackendStatus *beentry; TimestampTz proc_start_timestamp; Oid userid; SockAddr clientaddr; - - Assert(MyBackendId >= 1 && MyBackendId <= MaxBackends); - MyBEEntry = &BackendStatusArray[MyBackendId - 1]; + volatile PgBackendStatus *beentry; /* - * To minimize the time spent modifying the entry, fetch all the needed - * data first. + * To minimize the time spent modifying the PgBackendStatus entry, + * fetch all the needed data first. * * If we have a MyProcPort, use its session start time (for consistency, * and to save a kernel call). @@ -1839,11 +1856,6 @@ pgstat_bestart(void) beentry->st_changecount++; Assert((beentry->st_changecount & 1) == 0); - - /* - * Set up a process-exit hook to clean up. - */ - on_shmem_exit(pgstat_beshutdown_hook, 0); } /* diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c index daef3199fa..ff70c8d6a6 100644 --- a/src/backend/utils/init/postinit.c +++ b/src/backend/utils/init/postinit.c @@ -8,7 +8,7 @@ * * * 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 */ 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 * 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 */ InitializeClientEncoding(); - /* initialize statistics collection for this backend */ + /* report this backend in the PgBackendStatus array */ if (!bootstrap) pgstat_bestart(); diff --git a/src/include/pgstat.h b/src/include/pgstat.h index 476fd47dc7..02010c7d89 100644 --- a/src/include/pgstat.h +++ b/src/include/pgstat.h @@ -5,7 +5,7 @@ * * 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 @@ -501,7 +501,9 @@ extern void pgstat_report_analyze(Oid tableoid, bool shared, PgStat_Counter livetuples, PgStat_Counter deadtuples); +extern void pgstat_initialize(void); extern void pgstat_bestart(void); + extern void pgstat_report_activity(const char *what); extern void pgstat_report_txn_timestamp(TimestampTz tstamp); extern void pgstat_report_waiting(bool waiting);