[MDEV-29723] ROW START not always set correctly in transaction-precise tables Created: 2022-10-06  Updated: 2023-02-21

Status: Open
Project: MariaDB Server
Component/s: Versioned Tables
Affects Version/s: 10.9.3
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Dennis DK Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Docker


Attachments: PNG File image-2022-10-06-15-47-28-122.png     PNG File image-2022-10-06-15-50-20-076.png    
Issue Links:
Relates
relates to MDEV-25644 UPDATE not working properly on transa... Closed
relates to MDEV-30701 row_start not set properly when updat... Open

 Description   

For transaction-precise system-versioned tables, when a user makes a "non-update" (i.e. update a value in a row to the same value), the ROW START ID is not set to the current transaction for the updated row.

Here are two system verisioned tables, one "normal" and one transaction-precise:

DROP TABLE IF EXISTS timebased;
CREATE TABLE timebased (colPri INT NOT NULL PRIMARY KEY, col int) WITH SYSTEM VERSIONING;
INSERT INTO timebased VALUES (1, 2);
INSERT INTO timebased VALUES (3,4);
 
DROP TABLE IF EXISTS transactionbased;
CREATE TABLE transactionbased (colPri INT NOT NULL PRIMARY KEY, col int, trx_start BIGINT UNSIGNED GENERATED ALWAYS AS ROW START,
                    trx_end BIGINT UNSIGNED GENERATED ALWAYS AS ROW END,
                    PERIOD FOR SYSTEM_TIME(trx_start, trx_end)) WITH SYSTEM VERSIONING;
INSERT INTO transactionbased (colPri, col) VALUES (1, 2);
INSERT INTO transactionbased (colPri, col) VALUES (3,4);

We then update the column "col" to the same value for one of the rows and get the resulting table with history. First for the timebased table:

UPDATE timebased SET col = 2 WHERE colPri = 1;
SELECT colPri, col, row_start, row_end FROM timebased FOR SYSTEM_TIME ALL;

This gives the expected result:

The updated row shows a "row_start" as the old one ends, and the max-value for "row_end"

But if we do the same for the transactionbased table:

UPDATE transactionbased SET col = 2 WHERE colPri = 1;
SELECT * FROM transactionbased FOR SYSTEM_TIME ALL;

The result is quite different:

trx_start for the updated row is exactly the same as for the original row.

Is this on purpose? It seems quite... Wrong. Now, in normal "what was it at that time", I don't think it matters much, and I haven't seen issues around it... But when you're trying to get a list of changes (at least the way I do it), it is very annoying. My only workaround is this WHERE clause to get the changed rows for a specific transaction (:trxid is the value that I'm looking for)

WHERE :trxid = trx_start OR (:trxid = trx_end AND
    ID NOT IN (SELECT ID FROM someTable FOR SYSTEM_TIME AS OF TRANSACTION :trxid t2 WHERE t2.trx_start <> someTable.trx_end));

If I simply used

WHERE :trxid = start_trxid OR :trxid = end_trxid

(as I could without the issue), it would look like the row was deleted, as I'd only get the old row and not the new one.



 Comments   
Comment by Dennis DK [ 2022-10-07 ]

Seems to be related. The issue starts out the same way (weird trx_start value on old row version), but then fails on a proper update to the row.

Mine may be a duplicate, but I'll let you be the judge of that.

Generated at Thu Feb 08 10:10:48 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.