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

Commit10ffe0f

Browse files
committed
Fix crash in WAL sender when starting physical replication
Since database connections can be used with WAL senders in 9.4, it ispossible to use physical replication. This commit fixes a crash whenstarting physical replication with a WAL sender using a databaseconnection, caused by the refactoring done in850196b.There have been discussions about forbidding the use of physicalreplication in a database connection, but this is left for later,taking care only of the crash new to 13.While on it, add a test to check for a failure when attempting logicalreplication if the WAL sender does not have a database connection. Thispart is extracted from a larger patch by Kyotaro Horiguchi.Reported-by: Vladimir SitnikovAuthor: Michael Paquier, Kyotaro HoriguchiReviewed-by: Kyotaro Horiguchi, Álvaro HerreraDiscussion:https://postgr.es/m/CAB=Je-GOWMj1PTPkeUhjqQp-4W3=nW-pXe2Hjax6rJFffB5_Aw@mail.gmail.comBackpatch-through: 13
1 parent9b5f85f commit10ffe0f

File tree

4 files changed

+31
-26
lines changed

4 files changed

+31
-26
lines changed

‎src/backend/access/transam/xlogreader.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ static bool ValidXLogRecordHeader(XLogReaderState *state, XLogRecPtr RecPtr,
4444
staticboolValidXLogRecord(XLogReaderState*state,XLogRecord*record,
4545
XLogRecPtrrecptr);
4646
staticvoidResetDecoder(XLogReaderState*state);
47+
staticvoidWALOpenSegmentInit(WALOpenSegment*seg,WALSegmentContext*segcxt,
48+
intsegsize,constchar*waldir);
4749

4850
/* size of the buffer allocated for error message. */
4951
#defineMAX_ERRORMSG_LEN 1000
@@ -210,7 +212,7 @@ allocate_recordbuf(XLogReaderState *state, uint32 reclength)
210212
/*
211213
* Initialize the passed segment structs.
212214
*/
213-
void
215+
staticvoid
214216
WALOpenSegmentInit(WALOpenSegment*seg,WALSegmentContext*segcxt,
215217
intsegsize,constchar*waldir)
216218
{

‎src/backend/replication/walsender.c

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -130,13 +130,11 @@ boollog_replication_commands = false;
130130
boolwake_wal_senders= false;
131131

132132
/*
133-
* Physical walsender does not use xlogreader to read WAL, but it does use a
134-
* fake one to keep state. Logical walsender uses a proper xlogreader. Both
135-
* keep the 'xlogreader' pointer to the right one, for the sake of common
136-
* routines.
133+
* xlogreader used for replication. Note that a WAL sender doing physical
134+
* replication does not need xlogreader to read WAL, but it needs one to
135+
* keep a state of its work.
137136
*/
138-
staticXLogReaderStatefake_xlogreader;
139-
staticXLogReaderState*xlogreader;
137+
staticXLogReaderState*xlogreader=NULL;
140138

141139
/*
142140
* These variables keep track of the state of the timeline we're currently
@@ -285,20 +283,6 @@ InitWalSender(void)
285283

286284
/* Initialize empty timestamp buffer for lag tracking. */
287285
lag_tracker=MemoryContextAllocZero(TopMemoryContext,sizeof(LagTracker));
288-
289-
/*
290-
* Prepare physical walsender's fake xlogreader struct. Logical walsender
291-
* does this later.
292-
*/
293-
if (!am_db_walsender)
294-
{
295-
xlogreader=&fake_xlogreader;
296-
xlogreader->routine=
297-
*XL_ROUTINE(.segment_open=WalSndSegmentOpen,
298-
.segment_close=wal_segment_close);
299-
WALOpenSegmentInit(&xlogreader->seg,&xlogreader->segcxt,
300-
wal_segment_size,NULL);
301-
}
302286
}
303287

304288
/*
@@ -594,6 +578,18 @@ StartReplication(StartReplicationCmd *cmd)
594578
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
595579
errmsg("IDENTIFY_SYSTEM has not been run before START_REPLICATION")));
596580

581+
/* create xlogreader for physical replication */
582+
xlogreader=
583+
XLogReaderAllocate(wal_segment_size,NULL,
584+
XL_ROUTINE(.segment_open=WalSndSegmentOpen,
585+
.segment_close=wal_segment_close),
586+
NULL);
587+
588+
if (!xlogreader)
589+
ereport(ERROR,
590+
(errcode(ERRCODE_OUT_OF_MEMORY),
591+
errmsg("out of memory")));
592+
597593
/*
598594
* We assume here that we're logging enough information in the WAL for
599595
* log-shipping, since this is checked in PostmasterMain().
@@ -1643,6 +1639,8 @@ exec_replication_command(const char *cmd_string)
16431639
StartReplication(cmd);
16441640
else
16451641
StartLogicalReplication(cmd);
1642+
1643+
Assert(xlogreader!=NULL);
16461644
break;
16471645
}
16481646

‎src/include/access/xlogreader.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -262,10 +262,6 @@ extern XLogReaderRoutine *LocalXLogReaderRoutine(void);
262262
/* Free an XLogReader */
263263
externvoidXLogReaderFree(XLogReaderState*state);
264264

265-
/* Initialize supporting structures */
266-
externvoidWALOpenSegmentInit(WALOpenSegment*seg,WALSegmentContext*segcxt,
267-
intsegsize,constchar*waldir);
268-
269265
/* Position the XLogReader to given record */
270266
externvoidXLogBeginRead(XLogReaderState*state,XLogRecPtrRecPtr);
271267
#ifdefFRONTEND

‎src/test/recovery/t/006_logical_decoding.pl

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
use warnings;
88
use PostgresNode;
99
use TestLib;
10-
use Test::Moretests=>13;
10+
use Test::Moretests=>14;
1111
use Config;
1212

1313
# Initialize master node
@@ -36,6 +36,15 @@
3636
m/replication slot "test_slot" was not created in this database/,
3737
"Logical decoding correctly fails to start");
3838

39+
# Check case of walsender not using a database connection. Logical
40+
# decoding should not be allowed.
41+
($result,$stdout,$stderr) =$node_master->psql(
42+
'template1',
43+
qq[START_REPLICATION SLOT s1 LOGICAL 0/1],
44+
replication=>'true');
45+
ok($stderr =~/ERROR: logical decoding requires a database connection/,
46+
"Logical decoding fails on non-database connection");
47+
3948
$node_master->safe_psql('postgres',
4049
qq[INSERT INTO decoding_test(x,y) SELECT s, s::text FROM generate_series(1,10) s;]
4150
);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp