Age Owner Branch data TLA Line data Source code
1 : : /*-------------------------------------------------------------------------
2 : : *
3 : : * sequence.c
4 : : * RMGR WAL routines for sequences.
5 : : *
6 : : * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
7 : : * Portions Copyright (c) 1994, Regents of the University of California
8 : : *
9 : : *
10 : : * IDENTIFICATION
11 : : * src/backend/commands/sequence_xlog.c
12 : : *
13 : : *-------------------------------------------------------------------------
14 : : */
15 : : #include "postgres.h"
16 : :
17 : : #include "access/bufmask.h"
18 : : #include "access/xlogutils.h"
19 : : #include "commands/sequence_xlog.h"
20 : : #include "storage/bufmgr.h"
21 : :
22 : : void
15 michael@paquier.xyz 23 :GNC 2336 : seq_redo(XLogReaderState *record)
24 : : {
25 : 2336 : XLogRecPtr lsn = record->EndRecPtr;
26 : 2336 : uint8 info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
27 : : Buffer buffer;
28 : : Page page;
29 : : Page localpage;
30 : : char *item;
31 : : Size itemsz;
32 : 2336 : xl_seq_rec *xlrec = (xl_seq_rec *) XLogRecGetData(record);
33 : : sequence_magic *sm;
34 : :
35 [ - + ]: 2336 : if (info != XLOG_SEQ_LOG)
15 michael@paquier.xyz 36 [ # # ]:UNC 0 : elog(PANIC, "seq_redo: unknown op code %u", info);
37 : :
15 michael@paquier.xyz 38 :GNC 2336 : buffer = XLogInitBufferForRedo(record, 0);
39 : 2336 : page = BufferGetPage(buffer);
40 : :
41 : : /*
42 : : * We always reinit the page. However, since this WAL record type is also
43 : : * used for updating sequences, it's possible that a hot-standby backend
44 : : * is examining the page concurrently; so we mustn't transiently trash the
45 : : * buffer. The solution is to build the correct new page contents in
46 : : * local workspace and then memcpy into the buffer. Then only bytes that
47 : : * are supposed to change will change, even transiently. We must palloc
48 : : * the local page for alignment reasons.
49 : : */
50 : 2336 : localpage = (Page) palloc(BufferGetPageSize(buffer));
51 : :
52 : 2336 : PageInit(localpage, BufferGetPageSize(buffer), sizeof(sequence_magic));
53 : 2336 : sm = (sequence_magic *) PageGetSpecialPointer(localpage);
54 : 2336 : sm->magic = SEQ_MAGIC;
55 : :
56 : 2336 : item = (char *) xlrec + sizeof(xl_seq_rec);
57 : 2336 : itemsz = XLogRecGetDataLen(record) - sizeof(xl_seq_rec);
58 : :
59 [ - + ]: 2336 : if (PageAddItem(localpage, item, itemsz, FirstOffsetNumber, false, false) == InvalidOffsetNumber)
15 michael@paquier.xyz 60 [ # # ]:UNC 0 : elog(PANIC, "seq_redo: failed to add item to page");
61 : :
15 michael@paquier.xyz 62 :GNC 2336 : PageSetLSN(localpage, lsn);
63 : :
64 : 2336 : memcpy(page, localpage, BufferGetPageSize(buffer));
65 : 2336 : MarkBufferDirty(buffer);
66 : 2336 : UnlockReleaseBuffer(buffer);
67 : :
68 : 2336 : pfree(localpage);
69 : 2336 : }
70 : :
71 : : /*
72 : : * Mask a Sequence page before performing consistency checks on it.
73 : : */
74 : : void
75 : 1206 : seq_mask(char *page, BlockNumber blkno)
76 : : {
77 : 1206 : mask_page_lsn_and_checksum(page);
78 : :
79 : 1206 : mask_unused_space(page);
80 : 1206 : }
|