mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-09-04 19:27:19 +02:00
logical decoding: old/newtuple in spooled UPDATE changes was switched around.
Somehow I managed to flip the order of restoring old & new tuples when de-spooling a change in a large transaction from disk. This happens to only take effect when a change is spooled to disk which has old/new versions of the tuple. That only is the case for UPDATEs where he primary key changed or where replica identity is changed to FULL. The tests didn't catch this because either spooled updates, or updates that changed primary keys, were tested; not both at the same time. Found while adding tests for the following commit. Backpatch: 9.4, where logical decoding was added
This commit is contained in:
parent
6e759cefe8
commit
e76e365be9
@ -240,6 +240,21 @@ ORDER BY 1,2;
|
||||
20467 | table public.tr_etoomuch: DELETE: id[integer]:1 | table public.tr_etoomuch: UPDATE: id[integer]:9999 data[integer]:-9999
|
||||
(3 rows)
|
||||
|
||||
-- check updates of primary keys work correctly
|
||||
BEGIN;
|
||||
CREATE TABLE spoolme AS SELECT g.i FROM generate_series(1, 5000) g(i);
|
||||
UPDATE tr_etoomuch SET id = -id WHERE id = 5000;
|
||||
DELETE FROM spoolme;
|
||||
DROP TABLE spoolme;
|
||||
COMMIT;
|
||||
SELECT data
|
||||
FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1')
|
||||
WHERE data ~ 'UPDATE';
|
||||
data
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
table public.tr_etoomuch: UPDATE: old-key: id[integer]:5000 new-tuple: id[integer]:-5000 data[integer]:5000
|
||||
(1 row)
|
||||
|
||||
-- check that a large, spooled, upsert works
|
||||
INSERT INTO tr_etoomuch (id, data)
|
||||
SELECT g.i, -g.i FROM generate_series(8000, 12000) g(i)
|
||||
|
@ -123,6 +123,18 @@ FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids',
|
||||
GROUP BY substring(data, 1, 24)
|
||||
ORDER BY 1,2;
|
||||
|
||||
-- check updates of primary keys work correctly
|
||||
BEGIN;
|
||||
CREATE TABLE spoolme AS SELECT g.i FROM generate_series(1, 5000) g(i);
|
||||
UPDATE tr_etoomuch SET id = -id WHERE id = 5000;
|
||||
DELETE FROM spoolme;
|
||||
DROP TABLE spoolme;
|
||||
COMMIT;
|
||||
|
||||
SELECT data
|
||||
FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1')
|
||||
WHERE data ~ 'UPDATE';
|
||||
|
||||
-- check that a large, spooled, upsert works
|
||||
INSERT INTO tr_etoomuch (id, data)
|
||||
SELECT g.i, -g.i FROM generate_series(8000, 12000) g(i)
|
||||
|
@ -2335,18 +2335,6 @@ ReorderBufferRestoreChange(ReorderBuffer *rb, ReorderBufferTXN *txn,
|
||||
case REORDER_BUFFER_CHANGE_UPDATE:
|
||||
case REORDER_BUFFER_CHANGE_DELETE:
|
||||
case REORDER_BUFFER_CHANGE_INTERNAL_SPEC_INSERT:
|
||||
if (change->data.tp.newtuple)
|
||||
{
|
||||
Size len = offsetof(ReorderBufferTupleBuf, t_data) +
|
||||
((ReorderBufferTupleBuf *) data)->tuple.t_len;
|
||||
|
||||
change->data.tp.newtuple = ReorderBufferGetTupleBuf(rb);
|
||||
memcpy(change->data.tp.newtuple, data, len);
|
||||
change->data.tp.newtuple->tuple.t_data =
|
||||
&change->data.tp.newtuple->t_data.header;
|
||||
data += len;
|
||||
}
|
||||
|
||||
if (change->data.tp.oldtuple)
|
||||
{
|
||||
Size len = offsetof(ReorderBufferTupleBuf, t_data) +
|
||||
@ -2358,6 +2346,18 @@ ReorderBufferRestoreChange(ReorderBuffer *rb, ReorderBufferTXN *txn,
|
||||
&change->data.tp.oldtuple->t_data.header;
|
||||
data += len;
|
||||
}
|
||||
|
||||
if (change->data.tp.newtuple)
|
||||
{
|
||||
Size len = offsetof(ReorderBufferTupleBuf, t_data) +
|
||||
((ReorderBufferTupleBuf *) data)->tuple.t_len;
|
||||
|
||||
change->data.tp.newtuple = ReorderBufferGetTupleBuf(rb);
|
||||
memcpy(change->data.tp.newtuple, data, len);
|
||||
change->data.tp.newtuple->tuple.t_data =
|
||||
&change->data.tp.newtuple->t_data.header;
|
||||
data += len;
|
||||
}
|
||||
break;
|
||||
case REORDER_BUFFER_CHANGE_INTERNAL_SNAPSHOT:
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user