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

Commit63c3eed

Browse files
author
Amit Kapila
committed
Invalidate relcache when changing REPLICA IDENTITY index.
When changing REPLICA IDENTITY INDEX to another one, the target table'srelcache was not being invalidated. This leads to skipping update/deleteoperations during apply on the subscriber side as the columns required tosearch corresponding rows won't get logged.Author: Tang Haiying, Hou ZhijieReviewed-by: Euler Taveira, Amit KapilaBackpatch-through: 10Discussion:https://postgr.es/m/OS0PR01MB61133CA11630DAE45BC6AD95FB939@OS0PR01MB6113.jpnprd01.prod.outlook.com
1 parent843925f commit63c3eed

File tree

2 files changed

+89
-1
lines changed

2 files changed

+89
-1
lines changed

‎src/backend/commands/tablecmds.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14891,6 +14891,12 @@ relation_mark_replica_identity(Relation rel, char ri_type, Oid indexOid,
1489114891
CatalogTupleUpdate(pg_index, &pg_index_tuple->t_self, pg_index_tuple);
1489214892
InvokeObjectPostAlterHookArg(IndexRelationId, thisIndexOid, 0,
1489314893
InvalidOid, is_internal);
14894+
/*
14895+
* Invalidate the relcache for the table, so that after we commit
14896+
* all sessions will refresh the table's replica identity index
14897+
* before attempting any UPDATE or DELETE on the table.
14898+
*/
14899+
CacheInvalidateRelcache(rel);
1489414900
}
1489514901
heap_freetuple(pg_index_tuple);
1489614902
}

‎src/test/subscription/t/100_bugs.pl

Lines changed: 83 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use warnings;
44
use PostgresNode;
55
use TestLib;
6-
use Test::Moretests=>5;
6+
use Test::Moretests=>7;
77

88
# Bug #15114
99

@@ -153,3 +153,85 @@
153153
$rows * 2,"2x$rows rows in t");
154154
is($node_twoways->safe_psql('d2',"SELECT count(f) FROM t2"),
155155
$rows * 2,"2x$rows rows in t2");
156+
157+
# https://postgr.es/m/OS0PR01MB61133CA11630DAE45BC6AD95FB939%40OS0PR01MB6113.jpnprd01.prod.outlook.com
158+
159+
# The bug was that when changing the REPLICA IDENTITY INDEX to another one, the
160+
# target table's relcache was not being invalidated. This leads to skipping
161+
# UPDATE/DELETE operations during apply on the subscriber side as the columns
162+
# required to search corresponding rows won't get logged.
163+
$node_publisher = get_new_node('publisher3');
164+
$node_publisher->init(allows_streaming=>'logical');
165+
$node_publisher->start;
166+
167+
$node_subscriber = get_new_node('subscriber3');
168+
$node_subscriber->init(allows_streaming=>'logical');
169+
$node_subscriber->start;
170+
171+
$node_publisher->safe_psql('postgres',
172+
"CREATE TABLE tab_replidentity_index(a int not null, b int not null)");
173+
$node_publisher->safe_psql('postgres',
174+
"CREATE UNIQUE INDEX idx_replidentity_index_a ON tab_replidentity_index(a)"
175+
);
176+
$node_publisher->safe_psql('postgres',
177+
"CREATE UNIQUE INDEX idx_replidentity_index_b ON tab_replidentity_index(b)"
178+
);
179+
180+
# use index idx_replidentity_index_a as REPLICA IDENTITY on publisher.
181+
$node_publisher->safe_psql('postgres',
182+
"ALTER TABLE tab_replidentity_index REPLICA IDENTITY USING INDEX idx_replidentity_index_a"
183+
);
184+
185+
$node_publisher->safe_psql('postgres',
186+
"INSERT INTO tab_replidentity_index VALUES(1, 1),(2, 2)");
187+
188+
$node_subscriber->safe_psql('postgres',
189+
"CREATE TABLE tab_replidentity_index(a int not null, b int not null)");
190+
$node_subscriber->safe_psql('postgres',
191+
"CREATE UNIQUE INDEX idx_replidentity_index_a ON tab_replidentity_index(a)"
192+
);
193+
$node_subscriber->safe_psql('postgres',
194+
"CREATE UNIQUE INDEX idx_replidentity_index_b ON tab_replidentity_index(b)"
195+
);
196+
# use index idx_replidentity_index_b as REPLICA IDENTITY on subscriber because
197+
# it reflects the future scenario we are testing: changing REPLICA IDENTITY
198+
# INDEX.
199+
$node_subscriber->safe_psql('postgres',
200+
"ALTER TABLE tab_replidentity_index REPLICA IDENTITY USING INDEX idx_replidentity_index_b"
201+
);
202+
203+
$publisher_connstr =$node_publisher->connstr .' dbname=postgres';
204+
$node_publisher->safe_psql('postgres',
205+
"CREATE PUBLICATION tap_pub FOR TABLE tab_replidentity_index");
206+
$node_subscriber->safe_psql('postgres',
207+
"CREATE SUBSCRIPTION tap_sub CONNECTION '$publisher_connstr' PUBLICATION tap_pub"
208+
);
209+
210+
$node_publisher->wait_for_catchup('tap_sub');
211+
212+
# Also wait for initial table sync to finish
213+
$node_subscriber->poll_query_until('postgres',$synced_query)
214+
ordie"Timed out while waiting for subscriber to synchronize data";
215+
216+
is($node_subscriber->safe_psql(
217+
'postgres',"SELECT * FROM tab_replidentity_index"),
218+
qq(1|1
219+
2|2),
220+
"check initial data on subscriber");
221+
222+
# Set REPLICA IDENTITY to idx_replidentity_index_b on publisher, then run UPDATE and DELETE.
223+
$node_publisher->safe_psql(
224+
'postgres',qq[
225+
ALTER TABLE tab_replidentity_index REPLICA IDENTITY USING INDEX idx_replidentity_index_b;
226+
UPDATE tab_replidentity_index SET a = -a WHERE a = 1;
227+
DELETE FROM tab_replidentity_index WHERE a = 2;
228+
]);
229+
230+
$node_publisher->wait_for_catchup('tap_sub');
231+
is($node_subscriber->safe_psql(
232+
'postgres',"SELECT * FROM tab_replidentity_index"),
233+
qq(-1|1),
234+
"update works with REPLICA IDENTITY");
235+
236+
$node_publisher->stop('fast');
237+
$node_subscriber->stop('fast');

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp