mirror of https://github.com/postgres/postgres
This split exists for most of the other RMGRs, and makes cleaner the separation between the WAL code, the redo code and the record description code (already in its own file) when it comes to the sequence RMGR. The redo and masking routines are moved to a new file, sequence_xlog.c. All the RMGR routines are now located in a new header, sequence_xlog.h. This separation is useful for a different patch related to sequences that I have been working on, where it makes a refactoring of sequence.c easier if its RMGR routines and its core routines are split. Reviewed-by: Heikki Linnakangas <hlinnaka@iki.fi> Reviewed-by: Kirill Reshke <reshkekirill@gmail.com> Discussion: https://postgr.es/m/aSfTxIWjiXkTKh1E@paquier.xyzpull/255/head
parent
d03668ea05
commit
a87987cafc
@ -0,0 +1,80 @@ |
||||
/*-------------------------------------------------------------------------
|
||||
* |
||||
* sequence.c |
||||
* RMGR WAL routines for sequences. |
||||
* |
||||
* Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group |
||||
* Portions Copyright (c) 1994, Regents of the University of California |
||||
* |
||||
* |
||||
* IDENTIFICATION |
||||
* src/backend/commands/sequence_xlog.c |
||||
* |
||||
*------------------------------------------------------------------------- |
||||
*/ |
||||
#include "postgres.h" |
||||
|
||||
#include "access/bufmask.h" |
||||
#include "access/xlogutils.h" |
||||
#include "commands/sequence_xlog.h" |
||||
#include "storage/bufmgr.h" |
||||
|
||||
void |
||||
seq_redo(XLogReaderState *record) |
||||
{ |
||||
XLogRecPtr lsn = record->EndRecPtr; |
||||
uint8 info = XLogRecGetInfo(record) & ~XLR_INFO_MASK; |
||||
Buffer buffer; |
||||
Page page; |
||||
Page localpage; |
||||
char *item; |
||||
Size itemsz; |
||||
xl_seq_rec *xlrec = (xl_seq_rec *) XLogRecGetData(record); |
||||
sequence_magic *sm; |
||||
|
||||
if (info != XLOG_SEQ_LOG) |
||||
elog(PANIC, "seq_redo: unknown op code %u", info); |
||||
|
||||
buffer = XLogInitBufferForRedo(record, 0); |
||||
page = BufferGetPage(buffer); |
||||
|
||||
/*
|
||||
* We always reinit the page. However, since this WAL record type is also |
||||
* used for updating sequences, it's possible that a hot-standby backend |
||||
* is examining the page concurrently; so we mustn't transiently trash the |
||||
* buffer. The solution is to build the correct new page contents in |
||||
* local workspace and then memcpy into the buffer. Then only bytes that |
||||
* are supposed to change will change, even transiently. We must palloc |
||||
* the local page for alignment reasons. |
||||
*/ |
||||
localpage = (Page) palloc(BufferGetPageSize(buffer)); |
||||
|
||||
PageInit(localpage, BufferGetPageSize(buffer), sizeof(sequence_magic)); |
||||
sm = (sequence_magic *) PageGetSpecialPointer(localpage); |
||||
sm->magic = SEQ_MAGIC; |
||||
|
||||
item = (char *) xlrec + sizeof(xl_seq_rec); |
||||
itemsz = XLogRecGetDataLen(record) - sizeof(xl_seq_rec); |
||||
|
||||
if (PageAddItem(localpage, item, itemsz, FirstOffsetNumber, false, false) == InvalidOffsetNumber) |
||||
elog(PANIC, "seq_redo: failed to add item to page"); |
||||
|
||||
PageSetLSN(localpage, lsn); |
||||
|
||||
memcpy(page, localpage, BufferGetPageSize(buffer)); |
||||
MarkBufferDirty(buffer); |
||||
UnlockReleaseBuffer(buffer); |
||||
|
||||
pfree(localpage); |
||||
} |
||||
|
||||
/*
|
||||
* Mask a Sequence page before performing consistency checks on it. |
||||
*/ |
||||
void |
||||
seq_mask(char *page, BlockNumber blkno) |
||||
{ |
||||
mask_page_lsn_and_checksum(page); |
||||
|
||||
mask_unused_space(page); |
||||
} |
||||
@ -0,0 +1,45 @@ |
||||
/*-------------------------------------------------------------------------
|
||||
* |
||||
* sequence_xlog.h |
||||
* Sequence WAL definitions. |
||||
* |
||||
* Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group |
||||
* Portions Copyright (c) 1994, Regents of the University of California |
||||
* |
||||
* src/include/commands/sequence_xlog.h |
||||
* |
||||
*------------------------------------------------------------------------- |
||||
*/ |
||||
|
||||
#ifndef SEQUENCE_XLOG_H |
||||
#define SEQUENCE_XLOG_H |
||||
|
||||
#include "access/xlogreader.h" |
||||
#include "lib/stringinfo.h" |
||||
|
||||
/* Record identifier */ |
||||
#define XLOG_SEQ_LOG 0x00 |
||||
|
||||
/*
|
||||
* The "special area" of a sequence's buffer page looks like this. |
||||
*/ |
||||
#define SEQ_MAGIC 0x1717 |
||||
|
||||
typedef struct sequence_magic |
||||
{ |
||||
uint32 magic; |
||||
} sequence_magic; |
||||
|
||||
/* Sequence WAL record */ |
||||
typedef struct xl_seq_rec |
||||
{ |
||||
RelFileLocator locator; |
||||
/* SEQUENCE TUPLE DATA FOLLOWS AT THE END */ |
||||
} xl_seq_rec; |
||||
|
||||
extern void seq_redo(XLogReaderState *record); |
||||
extern void seq_desc(StringInfo buf, XLogReaderState *record); |
||||
extern const char *seq_identify(uint8 info); |
||||
extern void seq_mask(char *page, BlockNumber blkno); |
||||
|
||||
#endif /* SEQUENCE_XLOG_H */ |
||||
Loading…
Reference in new issue