Skip to content

Commit b860848

Browse files
committed
Add redo LSN to pgstats files
This is used in the startup process to check that the pgstats file we are reading includes the redo LSN referring to the shutdown checkpoint where it has been written. The redo LSN in the pgstats file needs to match with what the control file has. This is intended to be used for an upcoming change that will extend the write of the stats file to happen during checkpoints, rather than only shutdown sequences. Bump PGSTAT_FILE_FORMAT_ID. Reviewed-by: Bertrand Drouvot Discussion: https://postgr.es/m/Zp8o6_cl0KSgsnvS@paquier.xyz
1 parent c27090b commit b860848

File tree

3 files changed

+36
-12
lines changed

3 files changed

+36
-12
lines changed

src/backend/access/transam/xlog.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5652,7 +5652,7 @@ StartupXLOG(void)
56525652
if (didCrash)
56535653
pgstat_discard_stats();
56545654
else
5655-
pgstat_restore_stats();
5655+
pgstat_restore_stats(checkPoint.redo);
56565656

56575657
lastFullPageWrites = checkPoint.fullPageWrites;
56585658

src/backend/utils/activity/pgstat.c

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@
9494
#include <unistd.h>
9595

9696
#include "access/xact.h"
97+
#include "access/xlog.h"
9798
#include "lib/dshash.h"
9899
#include "pgstat.h"
99100
#include "port/atomics.h"
@@ -171,8 +172,8 @@ typedef struct PgStat_SnapshotEntry
171172
* ----------
172173
*/
173174

174-
static void pgstat_write_statsfile(void);
175-
static void pgstat_read_statsfile(void);
175+
static void pgstat_write_statsfile(XLogRecPtr redo);
176+
static void pgstat_read_statsfile(XLogRecPtr redo);
176177

177178
static void pgstat_reset_after_failure(void);
178179

@@ -448,9 +449,9 @@ static const PgStat_KindInfo pgstat_kind_infos[PGSTAT_NUM_KINDS] = {
448449
* Should only be called by the startup process or in single user mode.
449450
*/
450451
void
451-
pgstat_restore_stats(void)
452+
pgstat_restore_stats(XLogRecPtr redo)
452453
{
453-
pgstat_read_statsfile();
454+
pgstat_read_statsfile(redo);
454455
}
455456

456457
/*
@@ -526,7 +527,7 @@ pgstat_before_server_shutdown(int code, Datum arg)
526527
if (code == 0)
527528
{
528529
pgStatLocal.shmem->is_shutdown = true;
529-
pgstat_write_statsfile();
530+
pgstat_write_statsfile(GetRedoRecPtr());
530531
}
531532
}
532533

@@ -1349,7 +1350,7 @@ write_chunk(FILE *fpout, void *ptr, size_t len)
13491350
* stats so locking is not required.
13501351
*/
13511352
static void
1352-
pgstat_write_statsfile(void)
1353+
pgstat_write_statsfile(XLogRecPtr redo)
13531354
{
13541355
FILE *fpout;
13551356
int32 format_id;
@@ -1366,7 +1367,8 @@ pgstat_write_statsfile(void)
13661367
/* we're shutting down, so it's ok to just override this */
13671368
pgstat_fetch_consistency = PGSTAT_FETCH_CONSISTENCY_NONE;
13681369

1369-
elog(DEBUG2, "writing stats file \"%s\"", statfile);
1370+
elog(DEBUG2, "writing stats file \"%s\" with redo %X/%X", statfile,
1371+
LSN_FORMAT_ARGS(redo));
13701372

13711373
/*
13721374
* Open the statistics temp file to write out the current values.
@@ -1387,6 +1389,9 @@ pgstat_write_statsfile(void)
13871389
format_id = PGSTAT_FILE_FORMAT_ID;
13881390
write_chunk_s(fpout, &format_id);
13891391

1392+
/* Write the redo LSN, used to cross check the file read */
1393+
write_chunk_s(fpout, &redo);
1394+
13901395
/* Write various stats structs for fixed number of objects */
13911396
for (int kind = PGSTAT_KIND_FIRST_VALID; kind <= PGSTAT_KIND_LAST; kind++)
13921397
{
@@ -1501,18 +1506,20 @@ read_chunk(FILE *fpin, void *ptr, size_t len)
15011506
* stats so locking is not required.
15021507
*/
15031508
static void
1504-
pgstat_read_statsfile(void)
1509+
pgstat_read_statsfile(XLogRecPtr redo)
15051510
{
15061511
FILE *fpin;
15071512
int32 format_id;
15081513
bool found;
15091514
const char *statfile = PGSTAT_STAT_PERMANENT_FILENAME;
15101515
PgStat_ShmemControl *shmem = pgStatLocal.shmem;
1516+
XLogRecPtr file_redo;
15111517

15121518
/* shouldn't be called from postmaster */
15131519
Assert(IsUnderPostmaster || !IsPostmasterEnvironment);
15141520

1515-
elog(DEBUG2, "reading stats file \"%s\"", statfile);
1521+
elog(DEBUG2, "reading stats file \"%s\" with redo %X/%X", statfile,
1522+
LSN_FORMAT_ARGS(redo));
15161523

15171524
/*
15181525
* Try to open the stats file. If it doesn't exist, the backends simply
@@ -1550,6 +1557,22 @@ pgstat_read_statsfile(void)
15501557
goto error;
15511558
}
15521559

1560+
/*
1561+
* Read the redo LSN stored in the file.
1562+
*/
1563+
if (!read_chunk_s(fpin, &file_redo))
1564+
{
1565+
elog(WARNING, "could not read redo LSN");
1566+
goto error;
1567+
}
1568+
1569+
if (file_redo != redo)
1570+
{
1571+
elog(WARNING, "found incorrect redo LSN %X/%X (expected %X/%X)",
1572+
LSN_FORMAT_ARGS(file_redo), LSN_FORMAT_ARGS(redo));
1573+
goto error;
1574+
}
1575+
15531576
/*
15541577
* We found an existing statistics file. Read it and put all the stats
15551578
* data into place.

src/include/pgstat.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#ifndef PGSTAT_H
1212
#define PGSTAT_H
1313

14+
#include "access/xlogdefs.h"
1415
#include "datatype/timestamp.h"
1516
#include "portability/instr_time.h"
1617
#include "postmaster/pgarch.h" /* for MAX_XFN_CHARS */
@@ -235,7 +236,7 @@ typedef struct PgStat_TableXactStatus
235236
* ------------------------------------------------------------
236237
*/
237238

238-
#define PGSTAT_FILE_FORMAT_ID 0x01A5BCAD
239+
#define PGSTAT_FILE_FORMAT_ID 0x01A5BCAE
239240

240241
typedef struct PgStat_ArchiverStats
241242
{
@@ -466,7 +467,7 @@ extern Size StatsShmemSize(void);
466467
extern void StatsShmemInit(void);
467468

468469
/* Functions called during server startup / shutdown */
469-
extern void pgstat_restore_stats(void);
470+
extern void pgstat_restore_stats(XLogRecPtr redo);
470471
extern void pgstat_discard_stats(void);
471472
extern void pgstat_before_server_shutdown(int code, Datum arg);
472473

0 commit comments

Comments
 (0)