LCOV - code coverage report
Current view: top level - libs/pageserver_api/src - record.rs (source / functions) Coverage Total Hit
Test: 49aa928ec5b4b510172d8b5c6d154da28e70a46c.info Lines: 78.4 % 37 29
Test Date: 2024-11-13 18:23:39 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              : 
      45              :     /// A testing record for unit testing purposes. It supports append data to an existing image, or clear it.
      46              :     #[cfg(feature = "testing")]
      47              :     Test {
      48              :         /// Append a string to the image.
      49              :         append: String,
      50              :         /// Clear the image before appending.
      51              :         clear: bool,
      52              :         /// Treat this record as an init record. `clear` should be set to true if this field is set
      53              :         /// to true. This record does not need the history WALs to reconstruct. See [`NeonWalRecord::will_init`] and
      54              :         /// its references in `timeline.rs`.
      55              :         will_init: bool,
      56              :     },
      57              : }
      58              : 
      59              : impl NeonWalRecord {
      60              :     /// Does replaying this WAL record initialize the page from scratch, or does
      61              :     /// it need to be applied over the previous image of the page?
      62       146997 :     pub fn will_init(&self) -> bool {
      63       146997 :         // If you change this function, you'll also need to change ValueBytes::will_init
      64       146997 :         match self {
      65       145626 :             NeonWalRecord::Postgres { will_init, rec: _ } => *will_init,
      66              :             #[cfg(feature = "testing")]
      67         1351 :             NeonWalRecord::Test { will_init, .. } => *will_init,
      68              :             // None of the special neon record types currently initialize the page
      69           20 :             _ => false,
      70              :         }
      71       146997 :     }
      72              : 
      73              :     #[cfg(feature = "testing")]
      74          201 :     pub fn wal_append(s: impl AsRef<str>) -> Self {
      75          201 :         Self::Test {
      76          201 :             append: s.as_ref().to_string(),
      77          201 :             clear: false,
      78          201 :             will_init: false,
      79          201 :         }
      80          201 :     }
      81              : 
      82              :     #[cfg(feature = "testing")]
      83            2 :     pub fn wal_clear(s: impl AsRef<str>) -> Self {
      84            2 :         Self::Test {
      85            2 :             append: s.as_ref().to_string(),
      86            2 :             clear: true,
      87            2 :             will_init: false,
      88            2 :         }
      89            2 :     }
      90              : 
      91              :     #[cfg(feature = "testing")]
      92           52 :     pub fn wal_init(s: impl AsRef<str>) -> Self {
      93           52 :         Self::Test {
      94           52 :             append: s.as_ref().to_string(),
      95           52 :             clear: true,
      96           52 :             will_init: true,
      97           52 :         }
      98           52 :     }
      99              : }
     100              : 
     101              : /// Build a human-readable string to describe a WAL record
     102              : ///
     103              : /// For debugging purposes
     104            0 : pub fn describe_wal_record(rec: &NeonWalRecord) -> Result<String, DeserializeError> {
     105            0 :     match rec {
     106            0 :         NeonWalRecord::Postgres { will_init, rec } => Ok(format!(
     107            0 :             "will_init: {}, {}",
     108            0 :             will_init,
     109            0 :             describe_postgres_wal_record(rec)?
     110              :         )),
     111            0 :         _ => Ok(format!("{:?}", rec)),
     112              :     }
     113            0 : }
        

Generated by: LCOV version 2.1-beta