Fix remote_txn_heal_data_node() for multiple DB's

Since pg_prepared_xacts is shared between databases, the healing
function tried to resolve prepared transactions created by other
distributed databases.

This change makes the healing function to work only with current
database.

Fix #3433
This commit is contained in:
Dmitry Simonenko 2021-07-25 17:50:49 +03:00 committed by Dmitry Simonenko
parent 3a8f396bc7
commit bad2fc14e2
3 changed files with 55 additions and 9 deletions

View File

@ -28,15 +28,22 @@ remote_txn_resolution(Oid foreign_server, const RemoteTxnId *transaction_id)
return REMOTE_TXN_RESOLUTION_ABORT;
}
/* Resolve any unresolved 2-pc transaction on a data node.
Since the remote_txn log can be long, and most txn there
will have been resolved, do not iterate that list.
Instead query the data node for the list of unresolved txns
via the pg_prepared_xacts view. Using that list, then check
remote_txn. Use this as an opportunity to clean up remote_txn
as well.
*/
#define GET_PREPARED_XACT_SQL "SELECT gid FROM pg_prepared_xacts"
/*
* Resolve any unresolved 2-pc transaction on a data node.
* Since the remote_txn log can be long, and most txn there
* will have been resolved, do not iterate that list.
*
* Instead query the data node for the list of unresolved txns
* via the pg_prepared_xacts view. Using that list, then check
* remote_txn. Use this as an opportunity to clean up remote_txn
* as well.
*
* Note that pg_prepared_xacts shared across other databases which
* also could be distributed. Right now we interested only in
* the current one.
*/
#define GET_PREPARED_XACT_SQL \
"SELECT gid FROM pg_prepared_xacts WHERE database = current_database()"
Datum
remote_txn_heal_data_node(PG_FUNCTION_ARGS)

View File

@ -184,3 +184,24 @@ SELECT count(*) FROM _timescaledb_catalog.remote_txn;
0
(1 row)
-- test that healing function does not conflict with other databases
--
-- #3433
-- create additional database and simulate remote txn activity
CREATE DATABASE test_an2;
\c test_an2
BEGIN;
CREATE TABLE unused(id int);
PREPARE TRANSACTION 'ts-1-10-20-30';
\c :TEST_DBNAME :ROLE_SUPERUSER
-- should not fail
SELECT _timescaledb_internal.remote_txn_heal_data_node((SELECT OID FROM pg_foreign_server WHERE srvname = 'loopback'));
remote_txn_heal_data_node
---------------------------
0
(1 row)
\c test_an2
ROLLBACK PREPARED 'ts-1-10-20-30';
\c :TEST_DBNAME :ROLE_SUPERUSER
DROP DATABASE test_an2;

View File

@ -74,3 +74,21 @@ COMMIT PREPARED 'non-ts-txn';
SELECT * FROM table_modified_by_txns;
SELECT count(*) FROM pg_prepared_xacts;
SELECT count(*) FROM _timescaledb_catalog.remote_txn;
-- test that healing function does not conflict with other databases
--
-- #3433
-- create additional database and simulate remote txn activity
CREATE DATABASE test_an2;
\c test_an2
BEGIN;
CREATE TABLE unused(id int);
PREPARE TRANSACTION 'ts-1-10-20-30';
\c :TEST_DBNAME :ROLE_SUPERUSER
-- should not fail
SELECT _timescaledb_internal.remote_txn_heal_data_node((SELECT OID FROM pg_foreign_server WHERE srvname = 'loopback'));
\c test_an2
ROLLBACK PREPARED 'ts-1-10-20-30';
\c :TEST_DBNAME :ROLE_SUPERUSER
DROP DATABASE test_an2;