mirror of
https://github.com/neondatabase/neon.git
synced 2026-10-03 18:35:35 +00:00
## Problem We reverted https://github.com/neondatabase/neon/pull/6661 a few days ago. The change led to OOMs in benchmarks followed by large WAL reingests. The issue was that we removed [this code](https://github.com/neondatabase/neon/blob/d04af08567cc3ff94ff19a2f6b3f7a2a1e3c55d1/pageserver/src/tenant/timeline/walreceiver/walreceiver_connection.rs#L409-L417). That call may trigger a roll of the open layer due to the keepalive messages received from the safekeeper. Removing it meant that enforcing of checkpoint timeout became even more lax and led to using up large amounts of memory for the in memory layer indices. ## Summary of changes Piggyback on keep alive messages to enforce checkpoint timeout. This is a hack, but it's exactly what the current code is doing. ## Alternatives Christhian, Joonas and myself sketched out a timer based approach [here](https://github.com/neondatabase/neon/pull/6940). While discussing it further, it became obvious that's also a bit of a hack and not the desired end state. I chose not to take that further since it's not what we ultimately want and it'll be harder to rip out. Right now it's unclear what the ideal system behaviour is: * early flushing on memory pressure, or ... * detaching tenants on memory pressure
39 lines
1.3 KiB
Python
39 lines
1.3 KiB
Python
import time
|
|
|
|
from fixtures.neon_fixtures import NeonEnvBuilder
|
|
|
|
|
|
#
|
|
# Benchmark searching the layer map, when there are a lot of small layer files.
|
|
#
|
|
def test_layer_map(neon_env_builder: NeonEnvBuilder, zenbenchmark):
|
|
env = neon_env_builder.init_start()
|
|
n_iters = 10
|
|
n_records = 100000
|
|
|
|
# We want to have a lot of lot of layer files to exercise the layer map. Disable
|
|
# GC, and make checkpoint_distance very small, so that we get a lot of small layer
|
|
# files.
|
|
tenant, _ = env.neon_cli.create_tenant(
|
|
conf={
|
|
"gc_period": "0s",
|
|
"checkpoint_distance": "16384",
|
|
"compaction_period": "1 s",
|
|
"compaction_threshold": "1",
|
|
"compaction_target_size": "16384",
|
|
}
|
|
)
|
|
|
|
env.neon_cli.create_timeline("test_layer_map", tenant_id=tenant)
|
|
endpoint = env.endpoints.create_start("test_layer_map", tenant_id=tenant)
|
|
cur = endpoint.connect().cursor()
|
|
cur.execute("create table t(x integer)")
|
|
for _ in range(n_iters):
|
|
cur.execute(f"insert into t values (generate_series(1,{n_records}))")
|
|
time.sleep(1)
|
|
|
|
cur.execute("vacuum t")
|
|
with zenbenchmark.record_duration("test_query"):
|
|
cur.execute("SELECT count(*) from t")
|
|
assert cur.fetchone() == (n_iters * n_records,)
|