summaryrefslogtreecommitdiff
path: root/src/backend/utils/activity/pgstat.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/activity/pgstat.c')
-rw-r--r--src/backend/utils/activity/pgstat.c36
1 files changed, 34 insertions, 2 deletions
diff --git a/src/backend/utils/activity/pgstat.c b/src/backend/utils/activity/pgstat.c
index b125802b21..f6edfc76ac 100644
--- a/src/backend/utils/activity/pgstat.c
+++ b/src/backend/utils/activity/pgstat.c
@@ -103,7 +103,7 @@
#include "storage/lwlock.h"
#include "storage/pg_shmem.h"
#include "storage/shmem.h"
-#include "utils/guc.h"
+#include "utils/guc_hooks.h"
#include "utils/memutils.h"
#include "utils/pgstat_internal.h"
#include "utils/timestamp.h"
@@ -228,6 +228,13 @@ static dlist_head pgStatPending = DLIST_STATIC_INIT(pgStatPending);
static bool pgStatForceNextFlush = false;
/*
+ * Force-clear existing snapshot before next use when stats_fetch_consistency
+ * is changed.
+ */
+static bool force_stats_snapshot_clear = false;
+
+
+/*
* For assertions that check pgstat is not used before initialization / after
* shutdown.
*/
@@ -760,7 +767,8 @@ pgstat_reset_of_kind(PgStat_Kind kind)
* request will cause new snapshots to be read.
*
* This is also invoked during transaction commit or abort to discard
- * the no-longer-wanted snapshot.
+ * the no-longer-wanted snapshot. Updates of stats_fetch_consistency can
+ * cause this routine to be called.
*/
void
pgstat_clear_snapshot(void)
@@ -787,6 +795,9 @@ pgstat_clear_snapshot(void)
* forward the reset request.
*/
pgstat_clear_backend_activity_snapshot();
+
+ /* Reset this flag, as it may be possible that a cleanup was forced. */
+ force_stats_snapshot_clear = false;
}
void *
@@ -885,6 +896,9 @@ pgstat_fetch_entry(PgStat_Kind kind, Oid dboid, Oid objoid)
TimestampTz
pgstat_get_stat_snapshot_timestamp(bool *have_snapshot)
{
+ if (force_stats_snapshot_clear)
+ pgstat_clear_snapshot();
+
if (pgStatLocal.snapshot.mode == PGSTAT_FETCH_CONSISTENCY_SNAPSHOT)
{
*have_snapshot = true;
@@ -929,6 +943,9 @@ pgstat_snapshot_fixed(PgStat_Kind kind)
static void
pgstat_prep_snapshot(void)
{
+ if (force_stats_snapshot_clear)
+ pgstat_clear_snapshot();
+
if (pgstat_fetch_consistency == PGSTAT_FETCH_CONSISTENCY_NONE ||
pgStatLocal.snapshot.stats != NULL)
return;
@@ -1671,3 +1688,18 @@ pgstat_reset_after_failure(void)
/* and drop variable-numbered ones */
pgstat_drop_all_entries();
}
+
+/*
+ * GUC assign_hook for stats_fetch_consistency.
+ */
+void
+assign_stats_fetch_consistency(int newval, void *extra)
+{
+ /*
+ * Changing this value in a transaction may cause snapshot state
+ * inconsistencies, so force a clear of the current snapshot on the next
+ * snapshot build attempt.
+ */
+ if (pgstat_fetch_consistency != newval)
+ force_stats_snapshot_clear = true;
+}