mirror of
https://github.com/postgres/postgres.git
synced 2026-05-27 03:42:28 -04:00
Fix double table_close of sequence_rel in copy_sequences().
sequence_rel was declared at batch scope, so when a row is skipped due to concurrent drop or insufficient privileges, the end-of-row cleanup closes the stale pointer from the previous row, tripping the relcache refcount assertion. Move sequence_rel inside the per-row loop. Author: Ayush Tiwari <ayushtiwari.slg01@gmail.com> Reviewed-by: vignesh C <vignesh21@gmail.com> Reviewed-by: Hayato Kuroda <kuroda.hayato@fujitsu.com> Discussion: https://postgr.es/m/CAJTYsWWOuw-yfmzotV4jCJ6LLxEsb=STLcGtDYXOxRcU9Te3Pw@mail.gmail.com
This commit is contained in:
parent
5941e7f092
commit
2bf6c9ff71
2 changed files with 42 additions and 3 deletions
|
|
@ -254,8 +254,8 @@ get_and_validate_seq_info(TupleTableSlot *slot, Relation *sequence_rel,
|
||||||
(LogicalRepSequenceInfo *) list_nth(seqinfos, *seqidx);
|
(LogicalRepSequenceInfo *) list_nth(seqinfos, *seqidx);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* last_value can be NULL if the sequence was dropped concurrently (see
|
* The sequence data can be NULL due to insufficient privileges or if the
|
||||||
* pg_get_sequence_data()).
|
* sequence was dropped concurrently (see pg_get_sequence_data()).
|
||||||
*/
|
*/
|
||||||
datum = slot_getattr(slot, ++col, &isnull);
|
datum = slot_getattr(slot, ++col, &isnull);
|
||||||
if (isnull)
|
if (isnull)
|
||||||
|
|
@ -411,7 +411,6 @@ copy_sequences(WalReceiverConn *conn)
|
||||||
int batch_skipped_count = 0;
|
int batch_skipped_count = 0;
|
||||||
int batch_insuffperm_count = 0;
|
int batch_insuffperm_count = 0;
|
||||||
int batch_missing_count;
|
int batch_missing_count;
|
||||||
Relation sequence_rel = NULL;
|
|
||||||
|
|
||||||
WalRcvExecResult *res;
|
WalRcvExecResult *res;
|
||||||
TupleTableSlot *slot;
|
TupleTableSlot *slot;
|
||||||
|
|
@ -494,6 +493,7 @@ copy_sequences(WalReceiverConn *conn)
|
||||||
{
|
{
|
||||||
CopySeqResult sync_status;
|
CopySeqResult sync_status;
|
||||||
LogicalRepSequenceInfo *seqinfo;
|
LogicalRepSequenceInfo *seqinfo;
|
||||||
|
Relation sequence_rel = NULL;
|
||||||
int seqidx;
|
int seqidx;
|
||||||
|
|
||||||
CHECK_FOR_INTERRUPTS();
|
CHECK_FOR_INTERRUPTS();
|
||||||
|
|
|
||||||
|
|
@ -221,4 +221,43 @@ $node_subscriber->wait_for_log(
|
||||||
qr/WARNING: ( [A-Z0-9]+:)? missing sequence on publisher \("public.regress_s4"\)/,
|
qr/WARNING: ( [A-Z0-9]+:)? missing sequence on publisher \("public.regress_s4"\)/,
|
||||||
$log_offset);
|
$log_offset);
|
||||||
|
|
||||||
|
# Recreate regress_s4 so later tests that reuse the subscription do not keep
|
||||||
|
# reporting the intentionally-missing sequence from the previous test.
|
||||||
|
$node_publisher->safe_psql(
|
||||||
|
'postgres', qq(
|
||||||
|
CREATE SEQUENCE regress_s4 START 10 INCREMENT 2;
|
||||||
|
));
|
||||||
|
|
||||||
|
##########
|
||||||
|
# Ensure that insufficient privileges on the publisher for a sequence do not
|
||||||
|
# disrupt the subscriber. The subscriber should log a warning and continue
|
||||||
|
# retrying.
|
||||||
|
##########
|
||||||
|
|
||||||
|
$node_publisher->safe_psql(
|
||||||
|
'postgres', qq(
|
||||||
|
CREATE ROLE regress_seq_repl LOGIN REPLICATION;
|
||||||
|
GRANT USAGE ON SCHEMA public TO regress_seq_repl;
|
||||||
|
GRANT SELECT ON ALL SEQUENCES IN SCHEMA public TO regress_seq_repl;
|
||||||
|
REVOKE ALL ON SEQUENCE regress_s2 FROM regress_seq_repl;
|
||||||
|
));
|
||||||
|
|
||||||
|
my $publisher_limited_connstr =
|
||||||
|
$node_publisher->connstr . ' dbname=postgres user=regress_seq_repl';
|
||||||
|
$log_offset = -s $node_subscriber->logfile;
|
||||||
|
|
||||||
|
$node_subscriber->safe_psql(
|
||||||
|
'postgres',
|
||||||
|
"ALTER SUBSCRIPTION regress_seq_sub CONNECTION '$publisher_limited_connstr'"
|
||||||
|
);
|
||||||
|
|
||||||
|
$node_subscriber->safe_psql(
|
||||||
|
'postgres',
|
||||||
|
"ALTER SUBSCRIPTION regress_seq_sub REFRESH SEQUENCES"
|
||||||
|
);
|
||||||
|
|
||||||
|
$node_subscriber->wait_for_log(
|
||||||
|
qr/WARNING: ( [A-Z0-9]+:)? missing sequence on publisher \("public.regress_s2"\)/,
|
||||||
|
$log_offset);
|
||||||
|
|
||||||
done_testing();
|
done_testing();
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue