Skip to content

Commit

Permalink
Fix flaky pg_dump test
Browse files Browse the repository at this point in the history
This is a very known flaky test where we need to create another database
as a template of the TEST_DBNAME but some background workers didn't had
enough time to properly shutdown and disconnect from the database.

Fixed it by forcing other processes to terminate just after waiting for
background workers to discinnect from the database.

Closes #4766

Signed-off-by: Fabrízio de Royes Mello <[email protected]>
  • Loading branch information
fabriziomello committed Nov 27, 2023
1 parent b3a7f29 commit 144e1de
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 12 deletions.
16 changes: 14 additions & 2 deletions test/expected/pg_dump.out
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ INSERT INTO "two_Partitions"("timeCustom", device_id, series_0, series_1) VALUES
\set QUIET on
\o
\c :TEST_DBNAME :ROLE_SUPERUSER
CREATE OR REPLACE FUNCTION bgw_wait(database TEXT, timeout INT)
CREATE OR REPLACE FUNCTION bgw_wait(database TEXT, timeout INT, raise_error BOOLEAN DEFAULT TRUE)
RETURNS VOID
AS :MODULE_PATHNAME, 'ts_bgw_wait'
LANGUAGE C VOLATILE;
Expand Down Expand Up @@ -609,12 +609,24 @@ SELECT timescaledb_pre_restore();
t
(1 row)

SELECT bgw_wait(:'TEST_DBNAME', 60);
SELECT bgw_wait(:'TEST_DBNAME', 60, FALSE);
bgw_wait
----------

(1 row)

-- Force other sessions connected to the TEST_DBNAME to be finished
SET client_min_messages TO ERROR;
SELECT COUNT(pg_catalog.pg_terminate_backend(pid))>=0
FROM pg_stat_activity
WHERE pid <> pg_backend_pid()
AND datname = ':TEST_DBNAME';
?column?
----------
t
(1 row)

RESET client_min_messages;
CREATE DATABASE :TEST_DBNAME_EXTRA WITH TEMPLATE :TEST_DBNAME;
-- Connect to the database and do some basic stuff to check that the
-- extension works.
Expand Down
12 changes: 10 additions & 2 deletions test/sql/pg_dump.sql
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
\o
\c :TEST_DBNAME :ROLE_SUPERUSER

CREATE OR REPLACE FUNCTION bgw_wait(database TEXT, timeout INT)
CREATE OR REPLACE FUNCTION bgw_wait(database TEXT, timeout INT, raise_error BOOLEAN DEFAULT TRUE)
RETURNS VOID
AS :MODULE_PATHNAME, 'ts_bgw_wait'
LANGUAGE C VOLATILE;
Expand Down Expand Up @@ -197,7 +197,15 @@ drop function get_sqlstate(TEXT);
-- cannot have any backends connected to the database when cloning it.
\c :TEST_DBNAME :ROLE_SUPERUSER
SELECT timescaledb_pre_restore();
SELECT bgw_wait(:'TEST_DBNAME', 60);
SELECT bgw_wait(:'TEST_DBNAME', 60, FALSE);

-- Force other sessions connected to the TEST_DBNAME to be finished
SET client_min_messages TO ERROR;
SELECT COUNT(pg_catalog.pg_terminate_backend(pid))>=0
FROM pg_stat_activity
WHERE pid <> pg_backend_pid()
AND datname = ':TEST_DBNAME';
RESET client_min_messages;

CREATE DATABASE :TEST_DBNAME_EXTRA WITH TEMPLATE :TEST_DBNAME;

Expand Down
22 changes: 14 additions & 8 deletions test/src/test_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ ts_bgw_wait(PG_FUNCTION_ARGS)
/* The timeout is given in seconds, so we compute the number of iterations
* necessary to get a coverage of that time */
uint32 iterations = PG_ARGISNULL(1) ? 5 : (PG_GETARG_UINT32(1) + 4) / 5;
bool raise_error = PG_ARGISNULL(2) ? true : PG_GETARG_BOOL(2);
Oid dboid = get_database_oid(text_to_cstring(datname), false);

/* This function contains a timeout of 5 seconds, so we iterate a few
Expand All @@ -269,14 +270,19 @@ ts_bgw_wait(PG_FUNCTION_ARGS)
notherbackends,
npreparedxacts)));
}
ereport(ERROR,
(errcode(ERRCODE_OBJECT_IN_USE),
errmsg("source database \"%s\" is being accessed by other users",
text_to_cstring(datname)),
errdetail("There are %d other session(s) and %d prepared transaction(s) using the "
"database.",
notherbackends,
npreparedxacts)));

if (raise_error)
{
ereport(ERROR,
(errcode(ERRCODE_OBJECT_IN_USE),
errmsg("source database \"%s\" is being accessed by other users",
text_to_cstring(datname)),
errdetail("There are %d other session(s) and %d prepared transaction(s) using the "
"database.",
notherbackends,
npreparedxacts)));
}

pg_unreachable();
}

Expand Down

0 comments on commit 144e1de

Please sign in to comment.