We discovered major XC issue, that may lead to data loss and transactional inconsistency.
The source of the problem the GTM does not persist info about transactions.
Steps to reproduce:
Start cluster and open psql session
$ psql -d postgres
Create test tables
postgres=# create table t1 (a int, b int); CREATE TABLE postgres=# create table t2 (a int, b int); CREATE TABLE
Start a transaction and insert test rows
postgres=# begin; BEGIN postgres=# insert into t1 values (1,1); INSERT 0 1 postgres=# insert into t2 values (2,2); INSERT 0 1
Check the data are here
postgres=# select * from t1 union all select * from t2; a | b ---+--- 1 | 1 2 | 2 (2 rows)
Now restart GTM to simulate failure
$ gtm_ctl -D data-g -Z gtm restart waiting for server to shut down.... done server stopped server starting
Select from one of the tables in a new psql session
$ psql -d postgres postgres=# select * from t1; a | b ---+--- (0 rows)
Table is empty, that is correct - the transaction is not committed yet
Return to the first session, commit the transaction and check data:
postgres=# commit; COMMIT postgres=# select * from t1 union all select * from t2; a | b ---+--- 2 | 2 (1 row)
One row is here, other is disappeared.
What's going on behind the scene:
When GTM is restarted it "forgets" about active transaction. So transaction on second session is the only known to GTM and when it is about to read data it receives respective snapshot.
When t1 is scanned there is one newly inserted tuple. According to the snapshot, the inserting transaction has been finished already, and it is checked, if the transaction has been committed. It hasn't so visibility flag is set on the tuple, to shortcut further visibility checks of the tuple, making the tuple invisible. Second table is read for the first time after the commit, so opposite visibility flag is set on it.
Log in to post a comment.