From 740fc090763da20ba7988683d5481feed35b6545 Mon Sep 17 00:00:00 2001 From: vignesh Date: Sat, 10 Apr 2021 11:33:01 +0530 Subject: [PATCH v6 4/5] Handle overwriting of replication slot statistic issue. There is a remote scenario where one of the replication slots is dropped and the drop slot statistics message is not received by the statistic collector process, now if the max_replication_slots is reduced to the actual number of replication slots that are in use and the server is re-started then the statistics process will not be aware of this and the statistic collector process will write beyond the slots available, fixed it by writing the replication slot count in statistics file and increasing max_replication_slots if required at statup time base on the value updated in the statistics file. --- src/backend/postmaster/pgstat.c | 36 +++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c index e1ec7d8b7d..066829234b 100644 --- a/src/backend/postmaster/pgstat.c +++ b/src/backend/postmaster/pgstat.c @@ -3741,6 +3741,13 @@ pgstat_write_statsfiles(bool permanent, bool allDbs) (void) rc; /* we'll check for error with ferror */ } + if (nReplSlotStats > 0) + { + fputc('N', fpout); + rc = fwrite(&nReplSlotStats, sizeof(nReplSlotStats), 1, fpout); + (void) rc; /* we'll check for error with ferror */ + } + /* * Write replication slot stats struct */ @@ -3960,6 +3967,7 @@ pgstat_read_statsfiles(Oid onlydb, bool permanent, bool deep) bool found; const char *statfile = permanent ? PGSTAT_STAT_PERMANENT_FILENAME : pgstat_stat_filename; int i; + int replslotcount; /* * The tables will live in pgStatLocalContext. @@ -4196,6 +4204,34 @@ pgstat_read_statsfiles(Oid onlydb, bool permanent, bool deep) break; + /* + * 'N' Indicates the number of replication slot statistics + * present. + */ + case 'N': + if (fread(&replslotcount, 1, sizeof(replslotcount), fpin) + !=sizeof(replslotcount)) + { + ereport(pgStatRunningInCollector ? LOG : WARNING, + (errmsg("corrupted statistics file \"%s\"", + statfile))); + goto done; + } + + if (replslotcount > max_replication_slots) + { + max_replication_slots = replslotcount; + replSlotStats = repalloc(replSlotStats, + max_replication_slots + * sizeof(PgStat_ReplSlotStats)); + /* + * Set the same reset timestamp for all replication slots too. + */ + for (i = 0; i < max_replication_slots; i++) + replSlotStats[i].stat_reset_timestamp = globalStats.stat_reset_timestamp; + } + break; + /* * 'R' A PgStat_ReplSlotStats struct describing a replication * slot follows. -- 2.25.1