Skip to content

Commit 038f3a0

Browse files
committed
Fix pg_upgrade, broken by the xlogid/segno -> 64-bit int refactoring.
The xlogid + segno representation of a particular WAL segment doesn't make much sense in pg_resetxlog anymore, now that we don't use that anywhere else. Use the WAL filename instead, since that's a convenient way to name a particular WAL segment. I did this partially for pg_resetxlog in the original xlogid/segno -> uint64 patch, but I neglected pg_upgrade and the docs. This should now be more complete.
1 parent 8a504a3 commit 038f3a0

File tree

5 files changed

+51
-44
lines changed

5 files changed

+51
-44
lines changed

contrib/pg_upgrade/controldata.c

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ get_control_data(ClusterInfo *cluster, bool live_check)
3939
char *p;
4040
bool got_xid = false;
4141
bool got_oid = false;
42+
bool got_nextxlogfile = false;
4243
bool got_log_id = false;
4344
bool got_log_seg = false;
4445
bool got_tli = false;
@@ -61,6 +62,10 @@ get_control_data(ClusterInfo *cluster, bool live_check)
6162
char *language = NULL;
6263
char *lc_all = NULL;
6364
char *lc_messages = NULL;
65+
uint32 logid = 0;
66+
uint32 segno = 0;
67+
uint32 tli = 0;
68+
6469

6570
/*
6671
* Because we test the pg_resetxlog output as strings, it has to be in
@@ -166,6 +171,23 @@ get_control_data(ClusterInfo *cluster, bool live_check)
166171
p++; /* removing ':' char */
167172
cluster->controldata.cat_ver = str2uint(p);
168173
}
174+
else if ((p = strstr(bufin, "First log segment after reset:")) != NULL)
175+
{
176+
/* Skip the colon and any whitespace after it */
177+
p = strchr(p, ':');
178+
if (p == NULL || strlen(p) <= 1)
179+
pg_log(PG_FATAL, "%d: controldata retrieval problem\n", __LINE__);
180+
p = strpbrk(p, "01234567890ABCDEF");
181+
if (p == NULL || strlen(p) <= 1)
182+
pg_log(PG_FATAL, "%d: controldata retrieval problem\n", __LINE__);
183+
184+
/* Make sure it looks like a valid WAL file name */
185+
if (strspn(p, "0123456789ABCDEF") != 24)
186+
pg_log(PG_FATAL, "%d: controldata retrieval problem\n", __LINE__);
187+
188+
strlcpy(cluster->controldata.nextxlogfile, p, 25);
189+
got_nextxlogfile = true;
190+
}
169191
else if ((p = strstr(bufin, "First log file ID after reset:")) != NULL)
170192
{
171193
p = strchr(p, ':');
@@ -174,7 +196,7 @@ get_control_data(ClusterInfo *cluster, bool live_check)
174196
pg_log(PG_FATAL, "%d: controldata retrieval problem\n", __LINE__);
175197

176198
p++; /* removing ':' char */
177-
cluster->controldata.logid = str2uint(p);
199+
logid = str2uint(p);
178200
got_log_id = true;
179201
}
180202
else if ((p = strstr(bufin, "First log file segment after reset:")) != NULL)
@@ -185,7 +207,7 @@ get_control_data(ClusterInfo *cluster, bool live_check)
185207
pg_log(PG_FATAL, "%d: controldata retrieval problem\n", __LINE__);
186208

187209
p++; /* removing ':' char */
188-
cluster->controldata.nxtlogseg = str2uint(p);
210+
segno = str2uint(p);
189211
got_log_seg = true;
190212
}
191213
else if ((p = strstr(bufin, "Latest checkpoint's TimeLineID:")) != NULL)
@@ -393,10 +415,25 @@ get_control_data(ClusterInfo *cluster, bool live_check)
393415
pg_free(lc_all);
394416
pg_free(lc_messages);
395417

418+
/*
419+
* Before 9.3, pg_resetxlog reported the xlogid and segno of the first
420+
* log file after reset as separate lines. Starting with 9.3, it reports
421+
* the WAL file name. If the old cluster is older than 9.3, we construct
422+
* the WAL file name from the xlogid and segno.
423+
*/
424+
if (GET_MAJOR_VERSION(cluster->major_version) <= 902)
425+
{
426+
if (got_log_id && got_log_seg)
427+
{
428+
snprintf(cluster->controldata.nextxlogfile, 24, "%08X%08X%08X",
429+
tli, logid, segno);
430+
got_nextxlogfile = true;
431+
}
432+
}
433+
396434
/* verify that we got all the mandatory pg_control data */
397435
if (!got_xid || !got_oid ||
398-
(!live_check && !got_log_id) ||
399-
(!live_check && !got_log_seg) ||
436+
(!live_check && !got_nextxlogfile) ||
400437
!got_tli ||
401438
!got_align || !got_blocksz || !got_largesz || !got_walsz ||
402439
!got_walseg || !got_ident || !got_index || !got_toast ||
@@ -411,11 +448,8 @@ get_control_data(ClusterInfo *cluster, bool live_check)
411448
if (!got_oid)
412449
pg_log(PG_REPORT, " latest checkpoint next OID\n");
413450

414-
if (!live_check && !got_log_id)
415-
pg_log(PG_REPORT, " first log file ID after reset\n");
416-
417-
if (!live_check && !got_log_seg)
418-
pg_log(PG_REPORT, " first log file segment after reset\n");
451+
if (!live_check && !got_nextxlogfile)
452+
pg_log(PG_REPORT, " first WAL segment after reset\n");
419453

420454
if (!got_tli)
421455
pg_log(PG_REPORT, " latest checkpoint timeline ID\n");

contrib/pg_upgrade/pg_upgrade.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -354,11 +354,9 @@ copy_clog_xlog_xid(void)
354354
prep_status("Resetting WAL archives");
355355
exec_prog(true, true, UTILITY_LOG_FILE,
356356
SYSTEMQUOTE
357-
"\"%s/pg_resetxlog\" -l %u,%u,%u \"%s\" >> \"%s\" 2>&1"
357+
"\"%s/pg_resetxlog\" -l %s \"%s\" >> \"%s\" 2>&1"
358358
SYSTEMQUOTE, new_cluster.bindir,
359-
old_cluster.controldata.chkpnt_tli,
360-
old_cluster.controldata.logid,
361-
old_cluster.controldata.nxtlogseg,
359+
old_cluster.controldata.nextxlogfile,
362360
new_cluster.pgdata, UTILITY_LOG_FILE);
363361
check_ok();
364362
}

contrib/pg_upgrade/pg_upgrade.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,8 +168,7 @@ typedef struct
168168
{
169169
uint32 ctrl_ver;
170170
uint32 cat_ver;
171-
uint32 logid;
172-
uint32 nxtlogseg;
171+
char nextxlogfile[25];
173172
uint32 chkpnt_tli;
174173
uint32 chkpnt_nxtxid;
175174
uint32 chkpnt_nxtoid;

doc/src/sgml/ref/pg_resetxlog.sgml

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -131,13 +131,8 @@ PostgreSQL documentation
131131
the directory <filename>pg_xlog</> under the data directory.
132132
These names are also in hexadecimal and have three parts. The first
133133
part is the <quote>timeline ID</> and should usually be kept the same.
134-
Do not choose a value larger than 255 (<literal>0xFF</>) for the third
135-
part; instead increment the second part and reset the third part to 0.
136134
For example, if <filename>00000001000000320000004A</> is the
137-
largest entry in <filename>pg_xlog</>, <literal>-l 0x1,0x32,0x4B</> will
138-
work; but if the largest entry is
139-
<filename>000000010000003A000000FF</>, choose <literal>-l 0x1,0x3B,0x0</>
140-
or more.
135+
largest entry in <filename>pg_xlog</>, use <literal>-l 00000001000000320000004B</> or higher.
141136
</para>
142137

143138
<note>

src/bin/pg_resetxlog/pg_resetxlog.c

Lines changed: 4 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -86,13 +86,9 @@ main(int argc, char *argv[])
8686
Oid set_oid = 0;
8787
MultiXactId set_mxid = 0;
8888
MultiXactOffset set_mxoff = (MultiXactOffset) -1;
89-
uint32 minXlogTli = 0,
90-
minXlogId = 0,
91-
minXlogSeg = 0;
89+
uint32 minXlogTli = 0;
9290
XLogSegNo minXlogSegNo = 0;
9391
char *endptr;
94-
char *endptr2;
95-
char *endptr3;
9692
char *DataDir;
9793
int fd;
9894
char path[MAXPGPATH];
@@ -204,28 +200,13 @@ main(int argc, char *argv[])
204200
break;
205201

206202
case 'l':
207-
minXlogTli = strtoul(optarg, &endptr, 0);
208-
if (endptr == optarg || *endptr != ',')
203+
if (strspn(optarg, "01234567890ABCDEFabcdef") != 24)
209204
{
210205
fprintf(stderr, _("%s: invalid argument for option -l\n"), progname);
211206
fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
212207
exit(1);
213208
}
214-
minXlogId = strtoul(endptr + 1, &endptr2, 0);
215-
if (endptr2 == endptr + 1 || *endptr2 != ',')
216-
{
217-
fprintf(stderr, _("%s: invalid argument for option -l\n"), progname);
218-
fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
219-
exit(1);
220-
}
221-
minXlogSeg = strtoul(endptr2 + 1, &endptr3, 0);
222-
if (endptr3 == endptr2 + 1 || *endptr3 != '\0')
223-
{
224-
fprintf(stderr, _("%s: invalid argument for option -l\n"), progname);
225-
fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
226-
exit(1);
227-
}
228-
minXlogSegNo = (uint64) minXlogId * XLogSegmentsPerXLogId + minXlogSeg;
209+
XLogFromFileName(optarg, &minXlogTli, &minXlogSegNo);
229210
break;
230211

231212
default:
@@ -1013,7 +994,7 @@ usage(void)
1013994
printf(_("Options:\n"));
1014995
printf(_(" -e XIDEPOCH set next transaction ID epoch\n"));
1015996
printf(_(" -f force update to be done\n"));
1016-
printf(_(" -l TLI,FILE,SEG force minimum WAL starting location for new transaction log\n"));
997+
printf(_(" -l xlogfile force minimum WAL starting location for new transaction log\n"));
1017998
printf(_(" -m XID set next multitransaction ID\n"));
1018999
printf(_(" -n no update, just show extracted control values (for testing)\n"));
10191000
printf(_(" -o OID set next OID\n"));

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy