From d1d2d5ce6946e578799755ba91749e4a65d24901 Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas Date: Thu, 27 May 2021 20:00:52 +0300 Subject: [PATCH] Make multixact test more robust There was no guarantee that the SELECT FOR KEY SHARE queries actually run in parallel. With unlucky timing, one query might finish before the next one starts, so that the server doesn't need to create a multixact. I got a failure like that on the CI: batch_others/test_multixact.py:56: in test_multixact assert(int(next_multixact_id) > int(next_multixact_id_old)) E AssertionError: assert 1 > 1 E + where 1 = int('1') E + and 1 = int('1') This could be reproduced by adding a random sleep in the runQuery function, to make each query run at different times. To fix, keep the transactions open after running the queries, so that they will surely be open concurrently. With that, we can run the queries serially, and don't need the 'multiprocessing' module anymore. Fixes https://github.com/zenithdb/zenith/issues/196 --- test_runner/batch_others/test_multixact.py | 24 +++++++++------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/test_runner/batch_others/test_multixact.py b/test_runner/batch_others/test_multixact.py index c5d3f4b34e..2119c9f7b4 100644 --- a/test_runner/batch_others/test_multixact.py +++ b/test_runner/batch_others/test_multixact.py @@ -1,7 +1,6 @@ import pytest import os import psycopg2 -import multiprocessing pytest_plugins = ("fixtures.zenith_fixtures") @@ -11,14 +10,6 @@ pytest_plugins = ("fixtures.zenith_fixtures") # it only checks next_multixact_id field in restored pg_control, # since we don't have functions to check multixact internals. # - -def runQuery(connstr): - con = psycopg2.connect(connstr) - con.set_isolation_level(psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT) - cur = con.cursor() - cur.execute('select * from t1 for key share;') - - def test_multixact(pageserver, postgres, pg_bin, zenith_cli, base_dir): # Create a branch for us @@ -38,11 +29,16 @@ def test_multixact(pageserver, postgres, pg_bin, zenith_cli, base_dir): # Lock entries in parallel connections to set multixact nclients = 3 - pool = multiprocessing.Pool(nclients) - args = [pg.connstr()] * nclients - pool.map(runQuery, args) - pool.close() - pool.join() + connections = [] + for i in range(nclients): + con = psycopg2.connect(pg.connstr()) + # Do not turn on autocommit. We want to hold the key-share locks. + con.cursor().execute('select * from t1 for key share;') + connections.append(con) + + # We should have a multixact now. We can close the connections. + for c in connections: + c.close() # force wal flush cur.execute('checkpoint')