LCOV - code coverage report
Current view: top level - libs/pageserver_api/src - record.rs (source / functions) Coverage Total Hit
Test: 07bee600374ccd486c69370d0972d9035964fe68.info Lines: 78.4 % 37 29
Test Date: 2025-02-20 13:11:02 Functions: 35.0 % 20 7

            Line data    Source code
       1              : //! This module defines the WAL record format used within the pageserver.
       2              : 
       3              : use bytes::Bytes;
       4              : use postgres_ffi::walrecord::{describe_postgres_wal_record, MultiXactMember};
       5              : use postgres_ffi::{MultiXactId, MultiXactOffset, TimestampTz, TransactionId};
       6              : use serde::{Deserialize, Serialize};
       7              : use utils::bin_ser::DeserializeError;
       8              : 
       9              : /// Each update to a page is represented by a NeonWalRecord. It can be a wrapper
      10              : /// around a PostgreSQL WAL record, or a custom neon-specific "record".
      11         2015 : #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
      12              : pub enum NeonWalRecord {
      13              :     /// Native PostgreSQL WAL record
      14              :     Postgres { will_init: bool, rec: Bytes },
      15              : 
      16              :     /// Clear bits in heap visibility map. ('flags' is bitmap of bits to clear)
      17              :     ClearVisibilityMapFlags {
      18              :         new_heap_blkno: Option<u32>,
      19              :         old_heap_blkno: Option<u32>,
      20              :         flags: u8,
      21              :     },
      22              :     /// Mark transaction IDs as committed on a CLOG page
      23              :     ClogSetCommitted {
      24              :         xids: Vec<TransactionId>,
      25              :         timestamp: TimestampTz,
      26              :     },
      27              :     /// Mark transaction IDs as aborted on a CLOG page
      28              :     ClogSetAborted { xids: Vec<TransactionId> },
      29              :     /// Extend multixact offsets SLRU
      30              :     MultixactOffsetCreate {
      31              :         mid: MultiXactId,
      32              :         moff: MultiXactOffset,
      33              :     },
      34              :     /// Extend multixact members SLRU.
      35              :     MultixactMembersCreate {
      36              :         moff: MultiXactOffset,
      37              :         members: Vec<MultiXactMember>,
      38              :     },
      39              :     /// Update the map of AUX files, either writing or dropping an entry
      40              :     AuxFile {
      41              :         file_path: String,
      42              :         content: Option<Bytes>,
      43              :     },
      44              :     // Truncate visibility map page
      45              :     TruncateVisibilityMap {
      46              :         trunc_byte: usize,
      47              :         trunc_offs: usize,
      48              :     },
      49              : 
      50              :     /// A testing record for unit testing purposes. It supports append data to an existing image, or clear it.
      51              :     #[cfg(feature = "testing")]
      52              :     Test {
      53              :         /// Append a string to the image.
      54              :         append: String,
      55              :         /// Clear the image before appending.
      56              :         clear: bool,
      57              :         /// Treat this record as an init record. `clear` should be set to true if this field is set
      58              :         /// to true. This record does not need the history WALs to reconstruct. See [`NeonWalRecord::will_init`] and
      59              :         /// its references in `timeline.rs`.
      60              :         will_init: bool,
      61              :     },
      62              : }
      63              : 
      64              : impl NeonWalRecord {
      65              :     /// Does replaying this WAL record initialize the page from scratch, or does
      66              :     /// it need to be applied over the previous image of the page?
      67       293379 :     pub fn will_init(&self) -> bool {
      68       293379 :         // If you change this function, you'll also need to change ValueBytes::will_init
      69       293379 :         match self {
      70       291252 :             NeonWalRecord::Postgres { will_init, rec: _ } => *will_init,
      71              :             #[cfg(feature = "testing")]
      72         2087 :             NeonWalRecord::Test { will_init, .. } => *will_init,
      73              :             // None of the special neon record types currently initialize the page
      74           40 :             _ => false,
      75              :         }
      76       293379 :     }
      77              : 
      78              :     #[cfg(feature = "testing")]
      79          427 :     pub fn wal_append(s: impl AsRef<str>) -> Self {
      80          427 :         Self::Test {
      81          427 :             append: s.as_ref().to_string(),
      82          427 :             clear: false,
      83          427 :             will_init: false,
      84          427 :         }
      85          427 :     }
      86              : 
      87              :     #[cfg(feature = "testing")]
      88            4 :     pub fn wal_clear(s: impl AsRef<str>) -> Self {
      89            4 :         Self::Test {
      90            4 :             append: s.as_ref().to_string(),
      91            4 :             clear: true,
      92            4 :             will_init: false,
      93            4 :         }
      94            4 :     }
      95              : 
      96              :     #[cfg(feature = "testing")]
      97          104 :     pub fn wal_init(s: impl AsRef<str>) -> Self {
      98          104 :         Self::Test {
      99          104 :             append: s.as_ref().to_string(),
     100          104 :             clear: true,
     101          104 :             will_init: true,
     102          104 :         }
     103          104 :     }
     104              : }
     105              : 
     106              : /// Build a human-readable string to describe a WAL record
     107              : ///
     108              : /// For debugging purposes
     109            0 : pub fn describe_wal_record(rec: &NeonWalRecord) -> Result<String, DeserializeError> {
     110            0 :     match rec {
     111            0 :         NeonWalRecord::Postgres { will_init, rec } => Ok(format!(
     112            0 :             "will_init: {}, {}",
     113            0 :             will_init,
     114            0 :             describe_postgres_wal_record(rec)?
     115              :         )),
     116            0 :         _ => Ok(format!("{:?}", rec)),
     117              :     }
     118            0 : }
        

Generated by: LCOV version 2.1-beta