Skip to content

Commit

Permalink
Fix update duplication after crashfix
Browse files Browse the repository at this point in the history
Issue: with the fix in percona#67, pgtde decrypts tuples during update into
a new memory region, and changes the t_data pointer to this new region.

Because of this, later updates to tuple flags also happen in the new
data, and the original persisted tuple flags are never updated.

Fix: after the update statement is done with the decrypted data,
restore the t_data pointer to the original. This way, flag changes
happen where they should.

Fixes percona#68
  • Loading branch information
dutow committed Nov 13, 2023
1 parent 2b7ecbe commit 8cb7659
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 8 deletions.
12 changes: 4 additions & 8 deletions expected/trigger_on_view.out
Original file line number Diff line number Diff line change
Expand Up @@ -157,8 +157,7 @@ CONTEXT: PL/pgSQL function city_update() line 9 at RAISE
city_id | city_name | population | country_name | continent
---------+-----------+------------+--------------+-----------
1 | Tokyo | 13010279 | Japan | Asia
1 | Tokyo | 13010279 | |
(2 rows)
(1 row)

UPDATE city_view SET country_name = 'UK' WHERE city_name = 'New York' RETURNING *;
city_id | city_name | population | country_name | continent
Expand All @@ -170,23 +169,20 @@ CONTEXT: PL/pgSQL function city_update() line 9 at RAISE
city_id | city_name | population | country_name | continent
---------+-----------+------------+--------------+---------------
123456 | New York | 8391881 | USA | North America
123456 | New York | 8391881 | USA | North America
(2 rows)
(1 row)

UPDATE city_view SET continent = 'EU' WHERE continent = 'Europe' RETURNING *;
city_id | city_name | population | country_name | continent
---------+------------+------------+--------------+-----------
234567 | Birmingham | 1016800 | UK | Europe
123456 | New York | | UK | Europe
(2 rows)
(1 row)

UPDATE city_view v1 SET country_name = v2.country_name FROM city_view v2
WHERE v2.city_name = 'Birmingham' AND v1.city_name = 'London' RETURNING *;
city_id | city_name | population | country_name | continent | city_id | city_name | population | country_name | continent
---------+-----------+------------+--------------+-----------+---------+------------+------------+--------------+-----------
2 | London | 7556900 | UK | Europe | 234567 | Birmingham | 1016800 | UK | Europe
2 | London | 7556900 | UK | Europe | 234567 | Birmingham | 1016800 | UK | Europe
(2 rows)
(1 row)


-- DELETE .. RETURNING
Expand Down
4 changes: 4 additions & 0 deletions src/access/pg_tdeam.c
Original file line number Diff line number Diff line change
Expand Up @@ -3012,6 +3012,7 @@ pg_tde_update(Relation relation, ItemPointer otid, HeapTuple newtup,
ItemId lp;
HeapTupleData oldtup;
HeapTupleData oldtup2;
void* oldtupptr;
HeapTuple heaptup;
HeapTuple old_key_tuple = NULL;
bool old_key_copied = false;
Expand Down Expand Up @@ -3111,6 +3112,7 @@ pg_tde_update(Relation relation, ItemPointer otid, HeapTuple newtup,
*/
oldtup.t_tableOid = RelationGetRelid(relation);
oldtup.t_data = (HeapTupleHeader) PageGetItem(page, lp);
oldtupptr = oldtup.t_data;
oldtup.t_len = ItemIdGetLength(lp);
oldtup.t_self = *otid;
/* decrypt the old tuple */
Expand Down Expand Up @@ -3186,6 +3188,8 @@ pg_tde_update(Relation relation, ItemPointer otid, HeapTuple newtup,
* use otid anymore.
*/

oldtup.t_data = oldtupptr;

l2:
checked_lockers = false;
locker_remains = false;
Expand Down

0 comments on commit 8cb7659

Please sign in to comment.