Coverage Report

Created: 2026-11-09 07:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/postgres/src/backend/commands/sequence_xlog.c
Line
Count
Source
1
/*-------------------------------------------------------------------------
2
 *
3
 * sequence.c
4
 *    RMGR WAL routines for sequences.
5
 *
6
 * Portions Copyright (c) 1996-2026, 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
23
seq_redo(XLogReaderState *record)
24
0
{
25
0
  XLogRecPtr  lsn = record->EndRecPtr;
26
0
  uint8   info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
27
0
  Buffer    buffer;
28
0
  Page    page;
29
0
  Page    localpage;
30
0
  char     *item;
31
0
  Size    itemsz;
32
0
  xl_seq_rec *xlrec = (xl_seq_rec *) XLogRecGetData(record);
33
0
  sequence_magic *sm;
34
35
0
  if (info != XLOG_SEQ_LOG)
36
0
    elog(PANIC, "seq_redo: unknown op code %u", info);
37
38
0
  buffer = XLogInitBufferForRedo(record, 0);
39
0
  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
0
  localpage = (Page) palloc(BufferGetPageSize(buffer));
51
52
0
  PageInit(localpage, BufferGetPageSize(buffer), sizeof(sequence_magic));
53
0
  sm = (sequence_magic *) PageGetSpecialPointer(localpage);
54
0
  sm->magic = SEQ_MAGIC;
55
56
0
  item = (char *) xlrec + sizeof(xl_seq_rec);
57
0
  itemsz = XLogRecGetDataLen(record) - sizeof(xl_seq_rec);
58
59
0
  if (PageAddItem(localpage, item, itemsz, FirstOffsetNumber, false, false) == InvalidOffsetNumber)
60
0
    elog(PANIC, "seq_redo: failed to add item to page");
61
62
0
  PageSetLSN(localpage, lsn);
63
64
0
  memcpy(page, localpage, BufferGetPageSize(buffer));
65
0
  MarkBufferDirty(buffer);
66
0
  XLogFlushBufferForRedoIfInit(record, 0, buffer);
67
0
  UnlockReleaseBuffer(buffer);
68
69
0
  pfree(localpage);
70
0
}
71
72
/*
73
 * Mask a Sequence page before performing consistency checks on it.
74
 */
75
void
76
seq_mask(char *page, BlockNumber blkno)
77
0
{
78
0
  mask_page_lsn_and_checksum(page);
79
80
0
  mask_unused_space(page);
81
0
}