You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

bufmask.c 3.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  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-2019, 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. #include "postgres.h"
  18. #include "access/bufmask.h"
  19. /*
  20. * mask_page_lsn
  21. *
  22. * In consistency checks, the LSN of the two pages compared will likely be
  23. * different because of concurrent operations when the WAL is generated and
  24. * the state of the page when WAL is applied. Also, mask out checksum as
  25. * masking anything else on page means checksum is not going to match as well.
  26. */
  27. void
  28. mask_page_lsn_and_checksum(Page page)
  29. {
  30. PageHeader phdr = (PageHeader) page;
  31. PageXLogRecPtrSet(phdr->pd_lsn, (uint64) MASK_MARKER);
  32. phdr->pd_checksum = MASK_MARKER;
  33. }
  34. /*
  35. * mask_page_hint_bits
  36. *
  37. * Mask hint bits in PageHeader. We want to ignore differences in hint bits,
  38. * since they can be set without emitting any WAL.
  39. */
  40. void
  41. mask_page_hint_bits(Page page)
  42. {
  43. PageHeader phdr = (PageHeader) page;
  44. /* Ignore prune_xid (it's like a hint-bit) */
  45. phdr->pd_prune_xid = MASK_MARKER;
  46. /* Ignore PD_PAGE_FULL and PD_HAS_FREE_LINES flags, they are just hints. */
  47. PageClearFull(page);
  48. PageClearHasFreeLinePointers(page);
  49. /*
  50. * During replay, if the page LSN has advanced past our XLOG record's LSN,
  51. * we don't mark the page all-visible. See heap_xlog_visible() for
  52. * details.
  53. */
  54. PageClearAllVisible(page);
  55. }
  56. /*
  57. * mask_unused_space
  58. *
  59. * Mask the unused space of a page between pd_lower and pd_upper.
  60. */
  61. void
  62. mask_unused_space(Page page)
  63. {
  64. int pd_lower = ((PageHeader) page)->pd_lower;
  65. int pd_upper = ((PageHeader) page)->pd_upper;
  66. int pd_special = ((PageHeader) page)->pd_special;
  67. /* Sanity check */
  68. if (pd_lower > pd_upper || pd_special < pd_upper ||
  69. pd_lower < SizeOfPageHeaderData || pd_special > BLCKSZ)
  70. {
  71. elog(ERROR, "invalid page pd_lower %u pd_upper %u pd_special %u\n",
  72. pd_lower, pd_upper, pd_special);
  73. }
  74. memset(page + pd_lower, MASK_MARKER, pd_upper - pd_lower);
  75. }
  76. /*
  77. * mask_lp_flags
  78. *
  79. * In some index AMs, line pointer flags can be modified in master without
  80. * emitting any WAL record.
  81. */
  82. void
  83. mask_lp_flags(Page page)
  84. {
  85. OffsetNumber offnum,
  86. maxoff;
  87. maxoff = PageGetMaxOffsetNumber(page);
  88. for (offnum = FirstOffsetNumber;
  89. offnum <= maxoff;
  90. offnum = OffsetNumberNext(offnum))
  91. {
  92. ItemId itemId = PageGetItemId(page, offnum);
  93. if (ItemIdIsUsed(itemId))
  94. itemId->lp_flags = LP_UNUSED;
  95. }
  96. }
  97. /*
  98. * mask_page_content
  99. *
  100. * In some index AMs, the contents of deleted pages need to be almost
  101. * completely ignored.
  102. */
  103. void
  104. mask_page_content(Page page)
  105. {
  106. /* Mask Page Content */
  107. memset(page + SizeOfPageHeaderData, MASK_MARKER,
  108. BLCKSZ - SizeOfPageHeaderData);
  109. /* Mask pd_lower and pd_upper */
  110. memset(&((PageHeader) page)->pd_lower, MASK_MARKER,
  111. sizeof(uint16));
  112. memset(&((PageHeader) page)->pd_upper, MASK_MARKER,
  113. sizeof(uint16));
  114. }