From 215eb06b11e917d21fd2560583b230026cb47495 Mon Sep 17 00:00:00 2001 From: Bojan Serafimov Date: Wed, 17 May 2023 09:52:17 -0400 Subject: [PATCH] Add test --- pageserver/src/tenant/timeline.rs | 4 ++ test_runner/regress/test_duplicate_layers.py | 42 ++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 test_runner/regress/test_duplicate_layers.py diff --git a/pageserver/src/tenant/timeline.rs b/pageserver/src/tenant/timeline.rs index 6ae23c584b..eab7b63f97 100644 --- a/pageserver/src/tenant/timeline.rs +++ b/pageserver/src/tenant/timeline.rs @@ -2839,6 +2839,10 @@ impl Timeline { drop(all_keys_iter); // So that deltas_to_compact is no longer borrowed + fail_point!("compact-level0-phase1-finish", |_| { + Err(anyhow::anyhow!("failpoint compact-level0-phase1-finish").into()) + }); + Ok(CompactLevel0Phase1Result { new_layers, deltas_to_compact, diff --git a/test_runner/regress/test_duplicate_layers.py b/test_runner/regress/test_duplicate_layers.py new file mode 100644 index 0000000000..77d79cfcc0 --- /dev/null +++ b/test_runner/regress/test_duplicate_layers.py @@ -0,0 +1,42 @@ +import time + +import pytest +from fixtures.neon_fixtures import NeonEnvBuilder, PgBin + + +# Test duplicate layer detection +# +# This test sets fail point at the end of first compaction phase: +# after flushing new L1 layers but before deletion of L0 layes +# It should cause generation of duplicate L1 layer by compaction after restart +@pytest.mark.timeout(600) +def test_duplicate_layers(neon_env_builder: NeonEnvBuilder, pg_bin: PgBin): + env = neon_env_builder.init_start() + + # These warnings are expected, when the pageserver is restarted abruptly + env.pageserver.allowed_errors.append(".*found future image layer.*") + env.pageserver.allowed_errors.append(".*found future delta layer.*") + env.pageserver.allowed_errors.append(".*duplicate layer.*") + + pageserver_http = env.pageserver.http_client() + + # Use aggressive compaction and checkpoint settings + tenant_id, _ = env.neon_cli.create_tenant( + conf={ + "checkpoint_distance": f"{1024 ** 2}", + "compaction_target_size": f"{1024 ** 2}", + "compaction_period": "1 s", + "compaction_threshold": "3", + } + ) + endpoint = env.endpoints.create_start("main", tenant_id=tenant_id) + connstr = endpoint.connstr(options="-csynchronous_commit=off") + pg_bin.run_capture(["pgbench", "-i", "-s10", connstr]) + + pageserver_http.configure_failpoints(("compact-level0-phase1-finish", "exit")) + + with pytest.raises(Exception): + pg_bin.run_capture(["pgbench", "-P1", "-N", "-c5", "-T500", "-Mprepared", connstr]) + env.pageserver.stop() + env.pageserver.start() + time.sleep(10) # let compaction to be performed