Age Owner Branch data TLA Line data Source code
1 : : /*-------------------------------------------------------------------------
2 : : *
3 : : * bufmask.c
4 : : * Routines for buffer masking. Used to mask certain bits
5 : : * in a page which can be different when the WAL is generated
6 : : * and when the WAL is applied.
7 : : *
8 : : * Portions Copyright (c) 2016-2026, PostgreSQL Global Development Group
9 : : *
10 : : * Contains common routines required for masking a page.
11 : : *
12 : : * IDENTIFICATION
13 : : * src/backend/access/common/bufmask.c
14 : : *
15 : : *-------------------------------------------------------------------------
16 : : */
17 : :
18 : : #include "postgres.h"
19 : :
20 : : #include "access/bufmask.h"
21 : :
22 : : /*
23 : : * mask_page_lsn_and_checksum
24 : : *
25 : : * In consistency checks, the LSN of the two pages compared will likely be
26 : : * different because of concurrent operations when the WAL is generated and
27 : : * the state of the page when WAL is applied. Also, mask out checksum as
28 : : * masking anything else on page means checksum is not going to match as well.
29 : : */
30 : : void
3147 rhaas@postgresql.org 31 :CBC 4814880 : mask_page_lsn_and_checksum(Page page)
32 : : {
3373 33 : 4814880 : PageHeader phdr = (PageHeader) page;
34 : :
55 tomas.vondra@postgre 35 :GNC 4814880 : PageXLogRecPtrSet(&phdr->pd_lsn, (uint64) MASK_MARKER);
3147 rhaas@postgresql.org 36 :CBC 4814880 : phdr->pd_checksum = MASK_MARKER;
3373 37 : 4814880 : }
38 : :
39 : : /*
40 : : * mask_page_hint_bits
41 : : *
42 : : * Mask hint bits in PageHeader. We want to ignore differences in hint bits,
43 : : * since they can be set without emitting any WAL.
44 : : */
45 : : void
46 : 4813668 : mask_page_hint_bits(Page page)
47 : : {
48 : 4813668 : PageHeader phdr = (PageHeader) page;
49 : :
50 : : /* Ignore prune_xid (it's like a hint-bit) */
51 : 4813668 : phdr->pd_prune_xid = MASK_MARKER;
52 : :
53 : : /* Ignore PD_PAGE_FULL and PD_HAS_FREE_LINES flags, they are just hints. */
54 : 4813668 : PageClearFull(page);
55 : 4813668 : PageClearHasFreeLinePointers(page);
56 : :
57 : : /*
58 : : * PD_ALL_VISIBLE is masked during WAL consistency checking. XXX: It is
59 : : * worth investigating if we could stop doing this.
60 : : */
61 : 4813668 : PageClearAllVisible(page);
62 : 4813668 : }
63 : :
64 : : /*
65 : : * mask_unused_space
66 : : *
67 : : * Mask the unused space of a page between pd_lower and pd_upper.
68 : : */
69 : : void
70 : 4813580 : mask_unused_space(Page page)
71 : : {
72 : 4813580 : int pd_lower = ((PageHeader) page)->pd_lower;
73 : 4813580 : int pd_upper = ((PageHeader) page)->pd_upper;
74 : 4813580 : int pd_special = ((PageHeader) page)->pd_special;
75 : :
76 : : /* Sanity check */
77 [ + - + - ]: 4813580 : if (pd_lower > pd_upper || pd_special < pd_upper ||
78 [ + - - + ]: 4813580 : pd_lower < SizeOfPageHeaderData || pd_special > BLCKSZ)
79 : : {
1218 michael@paquier.xyz 80 [ # # ]:UBC 0 : elog(ERROR, "invalid page pd_lower %u pd_upper %u pd_special %u",
81 : : pd_lower, pd_upper, pd_special);
82 : : }
83 : :
3373 rhaas@postgresql.org 84 :CBC 4813580 : memset(page + pd_lower, MASK_MARKER, pd_upper - pd_lower);
85 : 4813580 : }
86 : :
87 : : /*
88 : : * mask_lp_flags
89 : : *
90 : : * In some index AMs, line pointer flags can be modified on the primary
91 : : * without emitting any WAL record.
92 : : */
93 : : void
94 : 1276908 : mask_lp_flags(Page page)
95 : : {
96 : : OffsetNumber offnum,
97 : : maxoff;
98 : :
99 : 1276908 : maxoff = PageGetMaxOffsetNumber(page);
100 : 1276908 : for (offnum = FirstOffsetNumber;
101 [ + + ]: 227065406 : offnum <= maxoff;
102 : 225788498 : offnum = OffsetNumberNext(offnum))
103 : : {
104 : 225788498 : ItemId itemId = PageGetItemId(page, offnum);
105 : :
106 [ + + ]: 225788498 : if (ItemIdIsUsed(itemId))
107 : 225785326 : itemId->lp_flags = LP_UNUSED;
108 : : }
109 : 1276908 : }
110 : :
111 : : /*
112 : : * mask_page_content
113 : : *
114 : : * In some index AMs, the contents of deleted pages need to be almost
115 : : * completely ignored.
116 : : */
117 : : void
118 : 358 : mask_page_content(Page page)
119 : : {
120 : : /* Mask Page Content */
121 : 358 : memset(page + SizeOfPageHeaderData, MASK_MARKER,
122 : : BLCKSZ - SizeOfPageHeaderData);
123 : :
124 : : /* Mask pd_lower and pd_upper */
125 : 358 : memset(&((PageHeader) page)->pd_lower, MASK_MARKER,
126 : : sizeof(uint16));
127 : 358 : memset(&((PageHeader) page)->pd_upper, MASK_MARKER,
128 : : sizeof(uint16));
129 : 358 : }
|