LCOV - code coverage report
Current view: top level - libs/pageserver_api/src - record.rs (source / functions) Coverage Total Hit
Test: 2e3a7638747e564a4f6d1af1cc0c3b3438fbb740.info Lines: 78.4 % 37 29
Test Date: 2024-11-20 01:36:58 Functions: 34.5 % 29 10

            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         2277 : #[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       146997 :     pub fn will_init(&self) -> bool {
      68       146997 :         // If you change this function, you'll also need to change ValueBytes::will_init
      69       146997 :         match self {
      70       145626 :             NeonWalRecord::Postgres { will_init, rec: _ } => *will_init,
      71              :             #[cfg(feature = "testing")]
      72         1351 :             NeonWalRecord::Test { will_init, .. } => *will_init,
      73              :             // None of the special neon record types currently initialize the page
      74           20 :             _ => false,
      75              :         }
      76       146997 :     }
      77              : 
      78              :     #[cfg(feature = "testing")]
      79          201 :     pub fn wal_append(s: impl AsRef<str>) -> Self {
      80          201 :         Self::Test {
      81          201 :             append: s.as_ref().to_string(),
      82          201 :             clear: false,
      83          201 :             will_init: false,
      84          201 :         }
      85          201 :     }
      86              : 
      87              :     #[cfg(feature = "testing")]
      88            2 :     pub fn wal_clear(s: impl AsRef<str>) -> Self {
      89            2 :         Self::Test {
      90            2 :             append: s.as_ref().to_string(),
      91            2 :             clear: true,
      92            2 :             will_init: false,
      93            2 :         }
      94            2 :     }
      95              : 
      96              :     #[cfg(feature = "testing")]
      97           52 :     pub fn wal_init(s: impl AsRef<str>) -> Self {
      98           52 :         Self::Test {
      99           52 :             append: s.as_ref().to_string(),
     100           52 :             clear: true,
     101           52 :             will_init: true,
     102           52 :         }
     103           52 :     }
     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