Skip to content

Commit df87a55

Browse files
authored
tests: Speed up test_pgdata_import_smoke on Postgres v17 (#10567)
The test runs this query: select count(*), sum(data::bigint)::bigint from t to validate the test results between each part of the test. It performs a simple sequential scan and aggregation, but was taking an order of magnitude longer on v17 than on previous Postgres versions, which sometimes caused the test to time out. There were two reasons for that: 1. On v17, the planner estimates the table to have only only one row. In reality it has 305790 rows, and older versions estimated it at 611580, which is not too bad given that the table has not been analyzed so the planner bases that estimate just on the number of pages and the widths of the datatypes. The new estimate of 1 row is much worse, and it leads the planner to disregard parallel plans, whereas on older versions you got a Parallel Seq Scan. I tracked this down to upstream commit 29cf61ade3, "Consider fillfactor when estimating relation size". With that commit, table_block_relation_estimate_size() function calculates that each page accommodates less than 1 row when the fillfactor is taken into account, which rounds down to 0. In reality, the executor will always place at least one row on a page regardless of fillfactor, but the new estimation formula doesn't take that into account. I reported this to pgsql-hackers (https://www.postgresql.org/message-id/2bf9d973-7789-4937-a7ca-0af9fb49c71e%40iki.fi), we don't need to do anything more about it in neon. It's OK to not use parallel scans here; once issue 2. below is addressed, the queries are fast enough without parallelism.. 2. On v17, prefetching was not happening for the sequential scan. That's because starting with v17, buffers are reserved in the shared buffer cache before prefetching is initiated, and we use a tiny shared_buffers=1MB setting in the tests. The prefetching is effectively disabled with such a small shared_buffers setting, to protect the system from completely starving out of buffers. To address that, simply bump up shared_buffers in the test. This patch addresses the second issue, which is enough to fix the problem.
1 parent 5e0c407 commit df87a55

File tree

1 file changed

+20
-4
lines changed

1 file changed

+20
-4
lines changed

test_runner/regress/test_import_pgdata.py

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,12 @@ def handler(request: Request) -> Response:
7070
env.pageserver.stop()
7171
env.pageserver.start()
7272

73+
# By default our tests run with a tiny shared_buffers=1MB setting. That
74+
# doesn't allow any prefetching on v17 and above, where the new streaming
75+
# read machinery keeps buffers pinned while prefetching them. Use a higher
76+
# setting to enable prefetching and speed up the tests
77+
ep_config = ["shared_buffers=64MB"]
78+
7379
#
7480
# Put data in vanilla pg
7581
#
@@ -246,7 +252,11 @@ def validate_vanilla_equivalence(ep):
246252
#
247253

248254
ro_endpoint = env.endpoints.create_start(
249-
branch_name=import_branch_name, endpoint_id="ro", tenant_id=tenant_id, lsn=last_record_lsn
255+
branch_name=import_branch_name,
256+
endpoint_id="ro",
257+
tenant_id=tenant_id,
258+
lsn=last_record_lsn,
259+
config_lines=ep_config,
250260
)
251261

252262
validate_vanilla_equivalence(ro_endpoint)
@@ -276,7 +286,10 @@ def validate_vanilla_equivalence(ep):
276286
# validate that we can write
277287
#
278288
rw_endpoint = env.endpoints.create_start(
279-
branch_name=import_branch_name, endpoint_id="rw", tenant_id=tenant_id
289+
branch_name=import_branch_name,
290+
endpoint_id="rw",
291+
tenant_id=tenant_id,
292+
config_lines=ep_config,
280293
)
281294
rw_endpoint.safe_psql("create table othertable(values text)")
282295
rw_lsn = Lsn(rw_endpoint.safe_psql_scalar("select pg_current_wal_flush_lsn()"))
@@ -296,7 +309,7 @@ def validate_vanilla_equivalence(ep):
296309
ancestor_start_lsn=rw_lsn,
297310
)
298311
br_tip_endpoint = env.endpoints.create_start(
299-
branch_name="br-tip", endpoint_id="br-tip-ro", tenant_id=tenant_id
312+
branch_name="br-tip", endpoint_id="br-tip-ro", tenant_id=tenant_id, config_lines=ep_config
300313
)
301314
validate_vanilla_equivalence(br_tip_endpoint)
302315
br_tip_endpoint.safe_psql("select * from othertable")
@@ -309,7 +322,10 @@ def validate_vanilla_equivalence(ep):
309322
ancestor_start_lsn=initdb_lsn,
310323
)
311324
br_initdb_endpoint = env.endpoints.create_start(
312-
branch_name="br-initdb", endpoint_id="br-initdb-ro", tenant_id=tenant_id
325+
branch_name="br-initdb",
326+
endpoint_id="br-initdb-ro",
327+
tenant_id=tenant_id,
328+
config_lines=ep_config,
313329
)
314330
validate_vanilla_equivalence(br_initdb_endpoint)
315331
with pytest.raises(psycopg2.errors.UndefinedTable):

0 commit comments

Comments
 (0)