mirror of
https://github.com/neondatabase/neon.git
synced 2026-05-17 13:10:38 +00:00
pageserver: fix unlogged relations with sharding (#7454)
## Problem - #7451 INIT_FORKNUM blocks must be stored on shard 0 to enable including them in basebackup. This issue can be missed in simple tests because creating an unlogged table isn't sufficient -- to repro I had to create an _index_ on an unlogged table (then restart the endpoint). Closes: #7451 ## Summary of changes - Add a reproducer for the issue. - Tweak the condition for `key_is_shard0` to include anything that isn't a normal relation block _and_ any normal relation block whose forknum is INIT_FORKNUM. - To enable existing databases to recover from the issue, add a special case that omits relations if they were stored on the wrong INITFORK. This enables postgres to start and the user to drop the table and recreate it.
This commit is contained in:
committed by
Joonas Koivunen
parent
35e9fb360b
commit
459bc479dc
@@ -1201,3 +1201,45 @@ def test_sharding_backpressure(neon_env_builder: NeonEnvBuilder):
|
||||
max_lsn = max(Lsn(info["last_record_lsn"]) for info in infos)
|
||||
diff = max_lsn - min_lsn
|
||||
assert diff < 2 * 1024 * 1024, f"LSN diff={diff}, expected diff < 2MB due to backpressure"
|
||||
|
||||
|
||||
def test_sharding_unlogged_relation(neon_env_builder: NeonEnvBuilder):
|
||||
"""
|
||||
Check that an unlogged relation is handled properly on a sharded tenant
|
||||
|
||||
Reproducer for https://github.com/neondatabase/neon/issues/7451
|
||||
"""
|
||||
|
||||
neon_env_builder.num_pageservers = 2
|
||||
env = neon_env_builder.init_configs()
|
||||
neon_env_builder.start()
|
||||
|
||||
tenant_id = TenantId.generate()
|
||||
timeline_id = TimelineId.generate()
|
||||
env.neon_cli.create_tenant(tenant_id, timeline_id, shard_count=8)
|
||||
|
||||
# We will create many tables to ensure it's overwhelmingly likely that at least one
|
||||
# of them doesn't land on shard 0
|
||||
table_names = [f"my_unlogged_{i}" for i in range(0, 16)]
|
||||
|
||||
with env.endpoints.create_start("main", tenant_id=tenant_id) as ep:
|
||||
for table_name in table_names:
|
||||
ep.safe_psql(f"CREATE UNLOGGED TABLE {table_name} (id integer, value varchar(64));")
|
||||
ep.safe_psql(f"INSERT INTO {table_name} VALUES (1, 'foo')")
|
||||
result = ep.safe_psql(f"SELECT * from {table_name};")
|
||||
assert result == [(1, "foo")]
|
||||
ep.safe_psql(f"CREATE INDEX ON {table_name} USING btree (value);")
|
||||
|
||||
wait_for_last_flush_lsn(env, ep, tenant_id, timeline_id)
|
||||
|
||||
with env.endpoints.create_start("main", tenant_id=tenant_id) as ep:
|
||||
for table_name in table_names:
|
||||
# Check that table works: we can select and insert
|
||||
result = ep.safe_psql(f"SELECT * from {table_name};")
|
||||
assert result == []
|
||||
ep.safe_psql(f"INSERT INTO {table_name} VALUES (2, 'bar');")
|
||||
result = ep.safe_psql(f"SELECT * from {table_name};")
|
||||
assert result == [(2, "bar")]
|
||||
|
||||
# Ensure that post-endpoint-restart modifications are ingested happily by pageserver
|
||||
wait_for_last_flush_lsn(env, ep, tenant_id, timeline_id)
|
||||
|
||||
Reference in New Issue
Block a user