Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit0bda14d

Browse files
committed
logical decoding: old/newtuple in spooled UPDATE changes was switched around.
Somehow I managed to flip the order of restoring old & new tuples whende-spooling a change in a large transaction from disk. This happens toonly take effect when a change is spooled to disk which has old/newversions of the tuple. That only is the case for UPDATEs where heprimary key changed or where replica identity is changed to FULL.The tests didn't catch this because either spooled updates, or updatesthat 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
1 parentd9e903f commit0bda14d

File tree

3 files changed

+37
-10
lines changed

3 files changed

+37
-10
lines changed

‎contrib/test_decoding/expected/ddl.out

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,21 @@ ORDER BY 1,2;
240240
20467 | table public.tr_etoomuch: DELETE: id[integer]:1 | table public.tr_etoomuch: UPDATE: id[integer]:9999 data[integer]:-9999
241241
(3 rows)
242242

243+
-- check updates of primary keys work correctly
244+
BEGIN;
245+
CREATE TABLE spoolme AS SELECT g.i FROM generate_series(1, 5000) g(i);
246+
UPDATE tr_etoomuch SET id = -id WHERE id = 5000;
247+
DELETE FROM spoolme;
248+
DROP TABLE spoolme;
249+
COMMIT;
250+
SELECT data
251+
FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1')
252+
WHERE data ~ 'UPDATE';
253+
data
254+
-------------------------------------------------------------------------------------------------------------
255+
table public.tr_etoomuch: UPDATE: old-key: id[integer]:5000 new-tuple: id[integer]:-5000 data[integer]:5000
256+
(1 row)
257+
243258
-- check that a large, spooled, upsert works
244259
INSERT INTO tr_etoomuch (id, data)
245260
SELECT g.i, -g.i FROM generate_series(8000, 12000) g(i)

‎contrib/test_decoding/sql/ddl.sql

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,18 @@ FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids',
123123
GROUP BYsubstring(data,1,24)
124124
ORDER BY1,2;
125125

126+
-- check updates of primary keys work correctly
127+
BEGIN;
128+
CREATETABLEspoolmeASSELECTg.iFROM generate_series(1,5000) g(i);
129+
UPDATE tr_etoomuchSET id=-idWHERE id=5000;
130+
DELETEFROM spoolme;
131+
DROPTABLE spoolme;
132+
COMMIT;
133+
134+
SELECT data
135+
FROM pg_logical_slot_get_changes('regression_slot',NULL,NULL,'include-xids','0','skip-empty-xacts','1')
136+
WHERE data ~'UPDATE';
137+
126138
-- check that a large, spooled, upsert works
127139
INSERT INTO tr_etoomuch (id, data)
128140
SELECTg.i,-g.iFROM generate_series(8000,12000) g(i)

‎src/backend/replication/logical/reorderbuffer.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2335,27 +2335,27 @@ ReorderBufferRestoreChange(ReorderBuffer *rb, ReorderBufferTXN *txn,
23352335
caseREORDER_BUFFER_CHANGE_UPDATE:
23362336
caseREORDER_BUFFER_CHANGE_DELETE:
23372337
caseREORDER_BUFFER_CHANGE_INTERNAL_SPEC_INSERT:
2338-
if (change->data.tp.newtuple)
2338+
if (change->data.tp.oldtuple)
23392339
{
23402340
Sizelen= offsetof(ReorderBufferTupleBuf,t_data)+
23412341
((ReorderBufferTupleBuf*)data)->tuple.t_len;
23422342

2343-
change->data.tp.newtuple=ReorderBufferGetTupleBuf(rb);
2344-
memcpy(change->data.tp.newtuple,data,len);
2345-
change->data.tp.newtuple->tuple.t_data=
2346-
&change->data.tp.newtuple->t_data.header;
2343+
change->data.tp.oldtuple=ReorderBufferGetTupleBuf(rb);
2344+
memcpy(change->data.tp.oldtuple,data,len);
2345+
change->data.tp.oldtuple->tuple.t_data=
2346+
&change->data.tp.oldtuple->t_data.header;
23472347
data+=len;
23482348
}
23492349

2350-
if (change->data.tp.oldtuple)
2350+
if (change->data.tp.newtuple)
23512351
{
23522352
Sizelen= offsetof(ReorderBufferTupleBuf,t_data)+
23532353
((ReorderBufferTupleBuf*)data)->tuple.t_len;
23542354

2355-
change->data.tp.oldtuple=ReorderBufferGetTupleBuf(rb);
2356-
memcpy(change->data.tp.oldtuple,data,len);
2357-
change->data.tp.oldtuple->tuple.t_data=
2358-
&change->data.tp.oldtuple->t_data.header;
2355+
change->data.tp.newtuple=ReorderBufferGetTupleBuf(rb);
2356+
memcpy(change->data.tp.newtuple,data,len);
2357+
change->data.tp.newtuple->tuple.t_data=
2358+
&change->data.tp.newtuple->t_data.header;
23592359
data+=len;
23602360
}
23612361
break;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp