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
This commit is contained in:
parent
c27090bd60
commit
b860848232
@ -5652,7 +5652,7 @@ StartupXLOG(void)
|
||||
if (didCrash)
|
||||
pgstat_discard_stats();
|
||||
else
|
||||
pgstat_restore_stats();
|
||||
pgstat_restore_stats(checkPoint.redo);
|
||||
|
||||
lastFullPageWrites = checkPoint.fullPageWrites;
|
||||
|
||||
|
@ -94,6 +94,7 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "access/xact.h"
|
||||
#include "access/xlog.h"
|
||||
#include "lib/dshash.h"
|
||||
#include "pgstat.h"
|
||||
#include "port/atomics.h"
|
||||
@ -171,8 +172,8 @@ typedef struct PgStat_SnapshotEntry
|
||||
* ----------
|
||||
*/
|
||||
|
||||
static void pgstat_write_statsfile(void);
|
||||
static void pgstat_read_statsfile(void);
|
||||
static void pgstat_write_statsfile(XLogRecPtr redo);
|
||||
static void pgstat_read_statsfile(XLogRecPtr redo);
|
||||
|
||||
static void pgstat_reset_after_failure(void);
|
||||
|
||||
@ -448,9 +449,9 @@ static const PgStat_KindInfo pgstat_kind_infos[PGSTAT_NUM_KINDS] = {
|
||||
* Should only be called by the startup process or in single user mode.
|
||||
*/
|
||||
void
|
||||
pgstat_restore_stats(void)
|
||||
pgstat_restore_stats(XLogRecPtr redo)
|
||||
{
|
||||
pgstat_read_statsfile();
|
||||
pgstat_read_statsfile(redo);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -526,7 +527,7 @@ pgstat_before_server_shutdown(int code, Datum arg)
|
||||
if (code == 0)
|
||||
{
|
||||
pgStatLocal.shmem->is_shutdown = true;
|
||||
pgstat_write_statsfile();
|
||||
pgstat_write_statsfile(GetRedoRecPtr());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1349,7 +1350,7 @@ write_chunk(FILE *fpout, void *ptr, size_t len)
|
||||
* stats so locking is not required.
|
||||
*/
|
||||
static void
|
||||
pgstat_write_statsfile(void)
|
||||
pgstat_write_statsfile(XLogRecPtr redo)
|
||||
{
|
||||
FILE *fpout;
|
||||
int32 format_id;
|
||||
@ -1366,7 +1367,8 @@ pgstat_write_statsfile(void)
|
||||
/* we're shutting down, so it's ok to just override this */
|
||||
pgstat_fetch_consistency = PGSTAT_FETCH_CONSISTENCY_NONE;
|
||||
|
||||
elog(DEBUG2, "writing stats file \"%s\"", statfile);
|
||||
elog(DEBUG2, "writing stats file \"%s\" with redo %X/%X", statfile,
|
||||
LSN_FORMAT_ARGS(redo));
|
||||
|
||||
/*
|
||||
* Open the statistics temp file to write out the current values.
|
||||
@ -1387,6 +1389,9 @@ pgstat_write_statsfile(void)
|
||||
format_id = PGSTAT_FILE_FORMAT_ID;
|
||||
write_chunk_s(fpout, &format_id);
|
||||
|
||||
/* Write the redo LSN, used to cross check the file read */
|
||||
write_chunk_s(fpout, &redo);
|
||||
|
||||
/* Write various stats structs for fixed number of objects */
|
||||
for (int kind = PGSTAT_KIND_FIRST_VALID; kind <= PGSTAT_KIND_LAST; kind++)
|
||||
{
|
||||
@ -1501,18 +1506,20 @@ read_chunk(FILE *fpin, void *ptr, size_t len)
|
||||
* stats so locking is not required.
|
||||
*/
|
||||
static void
|
||||
pgstat_read_statsfile(void)
|
||||
pgstat_read_statsfile(XLogRecPtr redo)
|
||||
{
|
||||
FILE *fpin;
|
||||
int32 format_id;
|
||||
bool found;
|
||||
const char *statfile = PGSTAT_STAT_PERMANENT_FILENAME;
|
||||
PgStat_ShmemControl *shmem = pgStatLocal.shmem;
|
||||
XLogRecPtr file_redo;
|
||||
|
||||
/* shouldn't be called from postmaster */
|
||||
Assert(IsUnderPostmaster || !IsPostmasterEnvironment);
|
||||
|
||||
elog(DEBUG2, "reading stats file \"%s\"", statfile);
|
||||
elog(DEBUG2, "reading stats file \"%s\" with redo %X/%X", statfile,
|
||||
LSN_FORMAT_ARGS(redo));
|
||||
|
||||
/*
|
||||
* Try to open the stats file. If it doesn't exist, the backends simply
|
||||
@ -1550,6 +1557,22 @@ pgstat_read_statsfile(void)
|
||||
goto error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the redo LSN stored in the file.
|
||||
*/
|
||||
if (!read_chunk_s(fpin, &file_redo))
|
||||
{
|
||||
elog(WARNING, "could not read redo LSN");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (file_redo != redo)
|
||||
{
|
||||
elog(WARNING, "found incorrect redo LSN %X/%X (expected %X/%X)",
|
||||
LSN_FORMAT_ARGS(file_redo), LSN_FORMAT_ARGS(redo));
|
||||
goto error;
|
||||
}
|
||||
|
||||
/*
|
||||
* We found an existing statistics file. Read it and put all the stats
|
||||
* data into place.
|
||||
|
@ -11,6 +11,7 @@
|
||||
#ifndef PGSTAT_H
|
||||
#define PGSTAT_H
|
||||
|
||||
#include "access/xlogdefs.h"
|
||||
#include "datatype/timestamp.h"
|
||||
#include "portability/instr_time.h"
|
||||
#include "postmaster/pgarch.h" /* for MAX_XFN_CHARS */
|
||||
@ -235,7 +236,7 @@ typedef struct PgStat_TableXactStatus
|
||||
* ------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#define PGSTAT_FILE_FORMAT_ID 0x01A5BCAD
|
||||
#define PGSTAT_FILE_FORMAT_ID 0x01A5BCAE
|
||||
|
||||
typedef struct PgStat_ArchiverStats
|
||||
{
|
||||
@ -466,7 +467,7 @@ extern Size StatsShmemSize(void);
|
||||
extern void StatsShmemInit(void);
|
||||
|
||||
/* Functions called during server startup / shutdown */
|
||||
extern void pgstat_restore_stats(void);
|
||||
extern void pgstat_restore_stats(XLogRecPtr redo);
|
||||
extern void pgstat_discard_stats(void);
|
||||
extern void pgstat_before_server_shutdown(int code, Datum arg);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user