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

Commite50cda7

Browse files
committed
Use pg_rewind when target timeline was switched
Allow pg_rewind to work when target timeline was switched. Nowuser can return promoted standby to old master.Target timeline history becomes a global variable. Indexin target timeline history is used in function interfaces instead ofspecifying TLI directly. Thus, SimpleXLogPageRead() can easily startreading XLOGs from next timeline when current timeline ends.Author: Alexander KorotkovReview: Michael Paquier
1 parent0e0776b commite50cda7

File tree

5 files changed

+181
-77
lines changed

5 files changed

+181
-77
lines changed

‎doc/src/sgml/ref/pg_rewind.sgml

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,17 @@ PostgreSQL documentation
6161
<application>pg_rewind</> examines the timeline histories of the source
6262
and target clusters to determine the point where they diverged, and
6363
expects to find WAL in the target cluster's <filename>pg_xlog</> directory
64-
reaching all the way back to the point of divergence. In the typical
65-
failover scenario where the target cluster was shut down soon after the
66-
divergence, that is not a problem, but if the target cluster had run for a
67-
long time after the divergence, the old WAL files might not be present
68-
anymore. In that case, they can be manually copied from the WAL archive to
69-
the <filename>pg_xlog</> directory. Fetching missing files from a WAL
70-
archive automatically is currently not supported.
64+
reaching all the way back to the point of divergence. The point of divergence
65+
could be found either on target timeline, source timeline or their common
66+
ancestor. In the typical failover scenario where the target cluster was
67+
shut down soon after the divergence, that is not a problem, but if the
68+
target cluster had run for a long time after the divergence, the old WAL
69+
files might not be present anymore. In that case, they can be manually
70+
copied from the WAL archive to the <filename>pg_xlog</> directory. Fetching
71+
missing files from a WAL archive automatically is currently not supported.
72+
Besides, <application>pg_rewind</> use cases are not limited by failover.
73+
For instance, standby server could be promoted, run some writes and
74+
then be returned back as stanby.
7175
</para>
7276

7377
<para>

‎src/bin/pg_rewind/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
#
99
#-------------------------------------------------------------------------
1010

11-
PGFILEDESC = "pg_rewind -repurpose an old master server as standby"
11+
PGFILEDESC = "pg_rewind -synchronize a data directory with another one forked from"
1212
PGAPPICON = win32
1313

1414
subdir = src/bin/pg_rewind

‎src/bin/pg_rewind/parsexlog.c

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ static char xlogfpath[MAXPGPATH];
4545
typedefstructXLogPageReadPrivate
4646
{
4747
constchar*datadir;
48-
TimeLineIDtli;
48+
inttliIndex;
4949
}XLogPageReadPrivate;
5050

5151
staticintSimpleXLogPageRead(XLogReaderState*xlogreader,
@@ -55,11 +55,11 @@ static int SimpleXLogPageRead(XLogReaderState *xlogreader,
5555

5656
/*
5757
* Read WAL from the datadir/pg_xlog, starting from 'startpoint' on timeline
58-
*'tli', until 'endpoint'. Make note of the data blocks touched by the WAL
59-
* records, and return them in a page map.
58+
*index 'tliIndex' in target timeline history, until 'endpoint'. Make note of
59+
*the data blocks touched by the WALrecords, and return them in a page map.
6060
*/
6161
void
62-
extractPageMap(constchar*datadir,XLogRecPtrstartpoint,TimeLineIDtli,
62+
extractPageMap(constchar*datadir,XLogRecPtrstartpoint,inttliIndex,
6363
XLogRecPtrendpoint)
6464
{
6565
XLogRecord*record;
@@ -68,7 +68,7 @@ extractPageMap(const char *datadir, XLogRecPtr startpoint, TimeLineID tli,
6868
XLogPageReadPrivateprivate;
6969

7070
private.datadir=datadir;
71-
private.tli=tli;
71+
private.tliIndex=tliIndex;
7272
xlogreader=XLogReaderAllocate(&SimpleXLogPageRead,&private);
7373
if (xlogreader==NULL)
7474
pg_fatal("out of memory\n");
@@ -112,7 +112,7 @@ extractPageMap(const char *datadir, XLogRecPtr startpoint, TimeLineID tli,
112112
* doing anything with the record itself.
113113
*/
114114
XLogRecPtr
115-
readOneRecord(constchar*datadir,XLogRecPtrptr,TimeLineIDtli)
115+
readOneRecord(constchar*datadir,XLogRecPtrptr,inttliIndex)
116116
{
117117
XLogRecord*record;
118118
XLogReaderState*xlogreader;
@@ -121,7 +121,7 @@ readOneRecord(const char *datadir, XLogRecPtr ptr, TimeLineID tli)
121121
XLogRecPtrendptr;
122122

123123
private.datadir=datadir;
124-
private.tli=tli;
124+
private.tliIndex=tliIndex;
125125
xlogreader=XLogReaderAllocate(&SimpleXLogPageRead,&private);
126126
if (xlogreader==NULL)
127127
pg_fatal("out of memory\n");
@@ -152,7 +152,7 @@ readOneRecord(const char *datadir, XLogRecPtr ptr, TimeLineID tli)
152152
* Find the previous checkpoint preceding given WAL position.
153153
*/
154154
void
155-
findLastCheckpoint(constchar*datadir,XLogRecPtrforkptr,TimeLineIDtli,
155+
findLastCheckpoint(constchar*datadir,XLogRecPtrforkptr,inttliIndex,
156156
XLogRecPtr*lastchkptrec,TimeLineID*lastchkpttli,
157157
XLogRecPtr*lastchkptredo)
158158
{
@@ -173,7 +173,7 @@ findLastCheckpoint(const char *datadir, XLogRecPtr forkptr, TimeLineID tli,
173173
forkptr+= (forkptr %XLogSegSize==0) ?SizeOfXLogLongPHD :SizeOfXLogShortPHD;
174174

175175
private.datadir=datadir;
176-
private.tli=tli;
176+
private.tliIndex=tliIndex;
177177
xlogreader=XLogReaderAllocate(&SimpleXLogPageRead,&private);
178178
if (xlogreader==NULL)
179179
pg_fatal("out of memory\n");
@@ -236,9 +236,11 @@ SimpleXLogPageRead(XLogReaderState *xlogreader, XLogRecPtr targetPagePtr,
236236
{
237237
XLogPageReadPrivate*private= (XLogPageReadPrivate*)xlogreader->private_data;
238238
uint32targetPageOff;
239-
XLogSegNotargetSegNoPG_USED_FOR_ASSERTS_ONLY;
239+
XLogRecPtrtargetSegEnd;
240+
XLogSegNotargetSegNo;
240241

241242
XLByteToSeg(targetPagePtr,targetSegNo);
243+
XLogSegNoOffsetToRecPtr(targetSegNo+1,0,targetSegEnd);
242244
targetPageOff=targetPagePtr %XLogSegSize;
243245

244246
/*
@@ -257,7 +259,20 @@ SimpleXLogPageRead(XLogReaderState *xlogreader, XLogRecPtr targetPagePtr,
257259
{
258260
charxlogfname[MAXFNAMELEN];
259261

260-
XLogFileName(xlogfname,private->tli,xlogreadsegno);
262+
/*
263+
* Since incomplete segments are copied into next timelines, switch to
264+
* the timeline holding the required segment. Assuming this scan can be
265+
* done both forward and backward, consider also switching timeline
266+
* accordingly.
267+
*/
268+
while (private->tliIndex<targetNentries-1&&
269+
targetHistory[private->tliIndex].end<targetSegEnd)
270+
private->tliIndex++;
271+
while (private->tliIndex>0&&
272+
targetHistory[private->tliIndex].begin >=targetSegEnd)
273+
private->tliIndex--;
274+
275+
XLogFileName(xlogfname,targetHistory[private->tliIndex].tli,xlogreadsegno);
261276

262277
snprintf(xlogfpath,MAXPGPATH,"%s/"XLOGDIR"/%s",private->datadir,xlogfname);
263278

@@ -293,7 +308,7 @@ SimpleXLogPageRead(XLogReaderState *xlogreader, XLogRecPtr targetPagePtr,
293308

294309
Assert(targetSegNo==xlogreadsegno);
295310

296-
*pageTLI=private->tli;
311+
*pageTLI=targetHistory[private->tliIndex].tli;
297312
returnXLOG_BLCKSZ;
298313
}
299314

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp