mirror of
https://github.com/neondatabase/neon.git
synced 2026-01-13 08:22:55 +00:00
postgres_ffi/wal_generate: add last_wal_record_xlog_switch and use it in tests
Fix #1190: WalDecoder did not return correct LSN of the next record after processing a XLOG_SWITCH record
This commit is contained in:
committed by
Egor Suvorov
parent
52f445094a
commit
85bda437de
@@ -226,10 +226,10 @@ impl WalStreamDecoder {
|
||||
self.padlen = self.lsn.calc_padding(8u32) as u32;
|
||||
}
|
||||
|
||||
// Always align resulting LSN on 0x8 boundary -- that is important for getPage()
|
||||
// and WalReceiver integration. Since this code is used both for WalReceiver and
|
||||
// initial WAL import let's force alignment right here.
|
||||
let result = (self.lsn.align(), recordbuf);
|
||||
// We should return LSN of the next record, not the last byte of this record or
|
||||
// the byte immediately after. Note that this handles both XLOG_SWITCH and usual
|
||||
// records, the former "spans" until the next WAL segment (see test_xlog_switch).
|
||||
let result = (self.lsn + self.padlen as u64, recordbuf);
|
||||
Ok(Some(result))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ fn main() -> Result<()> {
|
||||
.help("Type of WAL to generate")
|
||||
.possible_values([
|
||||
"simple",
|
||||
"last_wal_record_xlog_switch",
|
||||
"last_wal_record_crossing_segment",
|
||||
"wal_record_crossing_segment_followed_by_small_one",
|
||||
])
|
||||
@@ -57,6 +58,7 @@ fn main() -> Result<()> {
|
||||
let wal_generate = |arg_matches: &ArgMatches, client| {
|
||||
let lsn = match arg_matches.value_of("type").unwrap() {
|
||||
"simple" => generate_simple(client)?,
|
||||
"last_wal_record_xlog_switch" => generate_last_wal_record_xlog_switch(client)?,
|
||||
"last_wal_record_crossing_segment" => {
|
||||
generate_last_wal_record_crossing_segment(client)?
|
||||
}
|
||||
|
||||
@@ -250,6 +250,25 @@ pub fn generate_simple(client: &mut impl postgres::GenericClient) -> Result<PgLs
|
||||
})
|
||||
}
|
||||
|
||||
pub fn generate_last_wal_record_xlog_switch(
|
||||
client: &mut impl postgres::GenericClient,
|
||||
) -> Result<PgLsn> {
|
||||
// Do not use generate_internal because here we end up with flush_lsn exactly on
|
||||
// the segment boundary and insert_lsn after the initial page header, which is unusual.
|
||||
ensure_server_config(client)?;
|
||||
|
||||
client.execute("CREATE table t(x int)", &[])?;
|
||||
let after_xlog_switch: PgLsn = client.query_one("SELECT pg_switch_wal()", &[])?.get(0);
|
||||
let next_segment = PgLsn::from(0x0200_0000);
|
||||
ensure!(
|
||||
after_xlog_switch <= next_segment,
|
||||
"XLOG_SWITCH message ended after the expected segment boundary: {} > {}",
|
||||
after_xlog_switch,
|
||||
next_segment
|
||||
);
|
||||
Ok(next_segment)
|
||||
}
|
||||
|
||||
fn generate_single_logical_message(
|
||||
client: &mut impl postgres::GenericClient,
|
||||
transactional: bool,
|
||||
|
||||
@@ -9,6 +9,7 @@ import pytest
|
||||
@pytest.mark.parametrize('wal_type',
|
||||
[
|
||||
'simple',
|
||||
'last_wal_record_xlog_switch',
|
||||
'last_wal_record_crossing_segment',
|
||||
'wal_record_crossing_segment_followed_by_small_one',
|
||||
])
|
||||
|
||||
Reference in New Issue
Block a user