diff --git a/compute_tools/src/compute.rs b/compute_tools/src/compute.rs index 7566626d57..9c4d22b7b9 100644 --- a/compute_tools/src/compute.rs +++ b/compute_tools/src/compute.rs @@ -1280,7 +1280,7 @@ impl ComputeNode { let start_time = Utc::now(); let mut sync_handle = maybe_cgexec(&self.params.pgbin) - .args(["--sync-safekeepers"]) + .args(["--sync-safekeepers"]) // CF walproposer.c:289 .env("PGDATA", &self.params.pgdata) // we cannot use -D in this mode .envs(if let Some(storage_auth_token) = &storage_auth_token { vec![("NEON_AUTH_TOKEN", storage_auth_token)] diff --git a/libs/postgres_ffi/src/waldecoder_handler.rs b/libs/postgres_ffi/src/waldecoder_handler.rs index 9cd40645ec..0060305ec5 100644 --- a/libs/postgres_ffi/src/waldecoder_handler.rs +++ b/libs/postgres_ffi/src/waldecoder_handler.rs @@ -162,9 +162,9 @@ impl WalStreamDecoderHandler for WalStreamDecoder { // Fast path for the common case that the whole record fits on the page. let pageleft = self.lsn.remaining_in_block() as u32; if self.inputbuf.remaining() >= xl_tot_len as usize && xl_tot_len <= pageleft { - self.lsn += xl_tot_len as u64; + self.lsn += xl_tot_len as u64; /* we set self.lsn to the exclusive end of the record */ let recordbuf = self.inputbuf.copy_to_bytes(xl_tot_len as usize); - return Ok(Some(self.complete_record(recordbuf)?)); + return Ok(Some(self.complete_record(recordbuf)?)); // this returns (start LSN of NEXT!? record, this record's Bytes), wtf } else { // Need to assemble the record from pieces. Remember the size of the // record, and loop back. On next iterations, we will reach the branch diff --git a/libs/wal_decoder/src/models.rs b/libs/wal_decoder/src/models.rs index 94a00c0e53..278c659239 100644 --- a/libs/wal_decoder/src/models.rs +++ b/libs/wal_decoder/src/models.rs @@ -80,8 +80,8 @@ pub struct InterpretedWalRecord { /// by the pageserver pub batch: SerializedValueBatch, /// Byte offset within WAL for the start of the next PG WAL record. - /// Usually this is the end LSN of the current record, but in case of - /// XLOG SWITCH records it will be within the next segment. + /// Usually this is the byte following the last byte of this record here, + /// but in case of XLOG SWITCH records it will be within the next segment. pub next_record_lsn: Lsn, /// Whether to flush all uncommitted modifications to the storage engine /// before ingesting this record. This is currently only used for legacy PG @@ -213,6 +213,7 @@ pub struct XactCommon { pub origin_id: u16, // Fields below are only used for logging pub xl_xid: TransactionId, + // The `next_record_lsn` returned by wal decoder when we decoded this record. pub lsn: Lsn, } @@ -255,6 +256,7 @@ pub enum XlogRecord { #[derive(Clone, Serialize, Deserialize)] pub struct RawXlogRecord { pub info: u8, + // The `next_record_lsn` returned by wal decoder when we decoded this record. pub lsn: Lsn, pub buf: Bytes, } diff --git a/libs/wal_decoder/src/serialized_batch.rs b/libs/wal_decoder/src/serialized_batch.rs index ab38ff3d73..ecf40277f0 100644 --- a/libs/wal_decoder/src/serialized_batch.rs +++ b/libs/wal_decoder/src/serialized_batch.rs @@ -80,6 +80,8 @@ impl Eq for OrderedValueMeta {} #[derive(Serialize, Deserialize, Clone)] pub struct SerializedValueMeta { pub key: CompactKey, + // The `next_record_lsn` emitted by the wal_decoder for the WAL record + // that corresponds to this value. pub lsn: Lsn, /// Starting offset of the value for the (key, LSN) tuple /// in [`SerializedValueBatch::raw`] @@ -92,6 +94,8 @@ pub struct SerializedValueMeta { #[derive(Serialize, Deserialize, Clone)] pub struct ObservedValueMeta { pub key: CompactKey, + // The `next_record_lsn` emitted by the wal_decoder for the WAL record + // that corresponds to this value. pub lsn: Lsn, } @@ -109,7 +113,12 @@ pub struct SerializedValueBatch { /// by LSN. Note that entries for a key do not have to be contiguous. pub metadata: Vec, - /// The highest LSN of any value in the batch + /// The highest LSN of any value in the batch. + /// + /// The "LSN of a Value" is the `next_record_lsn` that the wal_decoder + /// emitted for that value, i.e., the LSN of a Value is + /// an LSN that is >= the next byte after the last byte of this value's + /// WAL record. pub max_lsn: Lsn, /// Number of values encoded by [`Self::raw`] diff --git a/pageserver/src/pgdatadir_mapping.rs b/pageserver/src/pgdatadir_mapping.rs index 31f38d485f..3aad6a83ad 100644 --- a/pageserver/src/pgdatadir_mapping.rs +++ b/pageserver/src/pgdatadir_mapping.rs @@ -1494,7 +1494,7 @@ pub struct DatadirModification<'a> { /// in the state in 'tline' yet. pub tline: &'a Timeline, - /// Current LSN of the modification + /// Current LSN of the modification. lsn: Lsn, // The modifications are not applied directly to the underlying key-value store.