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.
This commit is contained in:
parent
8a504a3639
commit
038f3a0509
|
@ -39,6 +39,7 @@ get_control_data(ClusterInfo *cluster, bool live_check)
|
||||||
char *p;
|
char *p;
|
||||||
bool got_xid = false;
|
bool got_xid = false;
|
||||||
bool got_oid = false;
|
bool got_oid = false;
|
||||||
|
bool got_nextxlogfile = false;
|
||||||
bool got_log_id = false;
|
bool got_log_id = false;
|
||||||
bool got_log_seg = false;
|
bool got_log_seg = false;
|
||||||
bool got_tli = false;
|
bool got_tli = false;
|
||||||
|
@ -61,6 +62,10 @@ get_control_data(ClusterInfo *cluster, bool live_check)
|
||||||
char *language = NULL;
|
char *language = NULL;
|
||||||
char *lc_all = NULL;
|
char *lc_all = NULL;
|
||||||
char *lc_messages = NULL;
|
char *lc_messages = NULL;
|
||||||
|
uint32 logid = 0;
|
||||||
|
uint32 segno = 0;
|
||||||
|
uint32 tli = 0;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Because we test the pg_resetxlog output as strings, it has to be in
|
* 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)
|
||||||
p++; /* removing ':' char */
|
p++; /* removing ':' char */
|
||||||
cluster->controldata.cat_ver = str2uint(p);
|
cluster->controldata.cat_ver = str2uint(p);
|
||||||
}
|
}
|
||||||
|
else if ((p = strstr(bufin, "First log segment after reset:")) != NULL)
|
||||||
|
{
|
||||||
|
/* Skip the colon and any whitespace after it */
|
||||||
|
p = strchr(p, ':');
|
||||||
|
if (p == NULL || strlen(p) <= 1)
|
||||||
|
pg_log(PG_FATAL, "%d: controldata retrieval problem\n", __LINE__);
|
||||||
|
p = strpbrk(p, "01234567890ABCDEF");
|
||||||
|
if (p == NULL || strlen(p) <= 1)
|
||||||
|
pg_log(PG_FATAL, "%d: controldata retrieval problem\n", __LINE__);
|
||||||
|
|
||||||
|
/* Make sure it looks like a valid WAL file name */
|
||||||
|
if (strspn(p, "0123456789ABCDEF") != 24)
|
||||||
|
pg_log(PG_FATAL, "%d: controldata retrieval problem\n", __LINE__);
|
||||||
|
|
||||||
|
strlcpy(cluster->controldata.nextxlogfile, p, 25);
|
||||||
|
got_nextxlogfile = true;
|
||||||
|
}
|
||||||
else if ((p = strstr(bufin, "First log file ID after reset:")) != NULL)
|
else if ((p = strstr(bufin, "First log file ID after reset:")) != NULL)
|
||||||
{
|
{
|
||||||
p = strchr(p, ':');
|
p = strchr(p, ':');
|
||||||
|
@ -174,7 +196,7 @@ get_control_data(ClusterInfo *cluster, bool live_check)
|
||||||
pg_log(PG_FATAL, "%d: controldata retrieval problem\n", __LINE__);
|
pg_log(PG_FATAL, "%d: controldata retrieval problem\n", __LINE__);
|
||||||
|
|
||||||
p++; /* removing ':' char */
|
p++; /* removing ':' char */
|
||||||
cluster->controldata.logid = str2uint(p);
|
logid = str2uint(p);
|
||||||
got_log_id = true;
|
got_log_id = true;
|
||||||
}
|
}
|
||||||
else if ((p = strstr(bufin, "First log file segment after reset:")) != NULL)
|
else if ((p = strstr(bufin, "First log file segment after reset:")) != NULL)
|
||||||
|
@ -185,7 +207,7 @@ get_control_data(ClusterInfo *cluster, bool live_check)
|
||||||
pg_log(PG_FATAL, "%d: controldata retrieval problem\n", __LINE__);
|
pg_log(PG_FATAL, "%d: controldata retrieval problem\n", __LINE__);
|
||||||
|
|
||||||
p++; /* removing ':' char */
|
p++; /* removing ':' char */
|
||||||
cluster->controldata.nxtlogseg = str2uint(p);
|
segno = str2uint(p);
|
||||||
got_log_seg = true;
|
got_log_seg = true;
|
||||||
}
|
}
|
||||||
else if ((p = strstr(bufin, "Latest checkpoint's TimeLineID:")) != NULL)
|
else if ((p = strstr(bufin, "Latest checkpoint's TimeLineID:")) != NULL)
|
||||||
|
@ -393,10 +415,25 @@ get_control_data(ClusterInfo *cluster, bool live_check)
|
||||||
pg_free(lc_all);
|
pg_free(lc_all);
|
||||||
pg_free(lc_messages);
|
pg_free(lc_messages);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Before 9.3, pg_resetxlog reported the xlogid and segno of the first
|
||||||
|
* log file after reset as separate lines. Starting with 9.3, it reports
|
||||||
|
* the WAL file name. If the old cluster is older than 9.3, we construct
|
||||||
|
* the WAL file name from the xlogid and segno.
|
||||||
|
*/
|
||||||
|
if (GET_MAJOR_VERSION(cluster->major_version) <= 902)
|
||||||
|
{
|
||||||
|
if (got_log_id && got_log_seg)
|
||||||
|
{
|
||||||
|
snprintf(cluster->controldata.nextxlogfile, 24, "%08X%08X%08X",
|
||||||
|
tli, logid, segno);
|
||||||
|
got_nextxlogfile = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* verify that we got all the mandatory pg_control data */
|
/* verify that we got all the mandatory pg_control data */
|
||||||
if (!got_xid || !got_oid ||
|
if (!got_xid || !got_oid ||
|
||||||
(!live_check && !got_log_id) ||
|
(!live_check && !got_nextxlogfile) ||
|
||||||
(!live_check && !got_log_seg) ||
|
|
||||||
!got_tli ||
|
!got_tli ||
|
||||||
!got_align || !got_blocksz || !got_largesz || !got_walsz ||
|
!got_align || !got_blocksz || !got_largesz || !got_walsz ||
|
||||||
!got_walseg || !got_ident || !got_index || !got_toast ||
|
!got_walseg || !got_ident || !got_index || !got_toast ||
|
||||||
|
@ -411,11 +448,8 @@ get_control_data(ClusterInfo *cluster, bool live_check)
|
||||||
if (!got_oid)
|
if (!got_oid)
|
||||||
pg_log(PG_REPORT, " latest checkpoint next OID\n");
|
pg_log(PG_REPORT, " latest checkpoint next OID\n");
|
||||||
|
|
||||||
if (!live_check && !got_log_id)
|
if (!live_check && !got_nextxlogfile)
|
||||||
pg_log(PG_REPORT, " first log file ID after reset\n");
|
pg_log(PG_REPORT, " first WAL segment after reset\n");
|
||||||
|
|
||||||
if (!live_check && !got_log_seg)
|
|
||||||
pg_log(PG_REPORT, " first log file segment after reset\n");
|
|
||||||
|
|
||||||
if (!got_tli)
|
if (!got_tli)
|
||||||
pg_log(PG_REPORT, " latest checkpoint timeline ID\n");
|
pg_log(PG_REPORT, " latest checkpoint timeline ID\n");
|
||||||
|
|
|
@ -354,11 +354,9 @@ copy_clog_xlog_xid(void)
|
||||||
prep_status("Resetting WAL archives");
|
prep_status("Resetting WAL archives");
|
||||||
exec_prog(true, true, UTILITY_LOG_FILE,
|
exec_prog(true, true, UTILITY_LOG_FILE,
|
||||||
SYSTEMQUOTE
|
SYSTEMQUOTE
|
||||||
"\"%s/pg_resetxlog\" -l %u,%u,%u \"%s\" >> \"%s\" 2>&1"
|
"\"%s/pg_resetxlog\" -l %s \"%s\" >> \"%s\" 2>&1"
|
||||||
SYSTEMQUOTE, new_cluster.bindir,
|
SYSTEMQUOTE, new_cluster.bindir,
|
||||||
old_cluster.controldata.chkpnt_tli,
|
old_cluster.controldata.nextxlogfile,
|
||||||
old_cluster.controldata.logid,
|
|
||||||
old_cluster.controldata.nxtlogseg,
|
|
||||||
new_cluster.pgdata, UTILITY_LOG_FILE);
|
new_cluster.pgdata, UTILITY_LOG_FILE);
|
||||||
check_ok();
|
check_ok();
|
||||||
}
|
}
|
||||||
|
|
|
@ -168,8 +168,7 @@ typedef struct
|
||||||
{
|
{
|
||||||
uint32 ctrl_ver;
|
uint32 ctrl_ver;
|
||||||
uint32 cat_ver;
|
uint32 cat_ver;
|
||||||
uint32 logid;
|
char nextxlogfile[25];
|
||||||
uint32 nxtlogseg;
|
|
||||||
uint32 chkpnt_tli;
|
uint32 chkpnt_tli;
|
||||||
uint32 chkpnt_nxtxid;
|
uint32 chkpnt_nxtxid;
|
||||||
uint32 chkpnt_nxtoid;
|
uint32 chkpnt_nxtoid;
|
||||||
|
|
|
@ -131,13 +131,8 @@ PostgreSQL documentation
|
||||||
the directory <filename>pg_xlog</> under the data directory.
|
the directory <filename>pg_xlog</> under the data directory.
|
||||||
These names are also in hexadecimal and have three parts. The first
|
These names are also in hexadecimal and have three parts. The first
|
||||||
part is the <quote>timeline ID</> and should usually be kept the same.
|
part is the <quote>timeline ID</> and should usually be kept the same.
|
||||||
Do not choose a value larger than 255 (<literal>0xFF</>) for the third
|
|
||||||
part; instead increment the second part and reset the third part to 0.
|
|
||||||
For example, if <filename>00000001000000320000004A</> is the
|
For example, if <filename>00000001000000320000004A</> is the
|
||||||
largest entry in <filename>pg_xlog</>, <literal>-l 0x1,0x32,0x4B</> will
|
largest entry in <filename>pg_xlog</>, use <literal>-l 00000001000000320000004B</> or higher.
|
||||||
work; but if the largest entry is
|
|
||||||
<filename>000000010000003A000000FF</>, choose <literal>-l 0x1,0x3B,0x0</>
|
|
||||||
or more.
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<note>
|
<note>
|
||||||
|
|
|
@ -86,13 +86,9 @@ main(int argc, char *argv[])
|
||||||
Oid set_oid = 0;
|
Oid set_oid = 0;
|
||||||
MultiXactId set_mxid = 0;
|
MultiXactId set_mxid = 0;
|
||||||
MultiXactOffset set_mxoff = (MultiXactOffset) -1;
|
MultiXactOffset set_mxoff = (MultiXactOffset) -1;
|
||||||
uint32 minXlogTli = 0,
|
uint32 minXlogTli = 0;
|
||||||
minXlogId = 0,
|
|
||||||
minXlogSeg = 0;
|
|
||||||
XLogSegNo minXlogSegNo = 0;
|
XLogSegNo minXlogSegNo = 0;
|
||||||
char *endptr;
|
char *endptr;
|
||||||
char *endptr2;
|
|
||||||
char *endptr3;
|
|
||||||
char *DataDir;
|
char *DataDir;
|
||||||
int fd;
|
int fd;
|
||||||
char path[MAXPGPATH];
|
char path[MAXPGPATH];
|
||||||
|
@ -204,28 +200,13 @@ main(int argc, char *argv[])
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'l':
|
case 'l':
|
||||||
minXlogTli = strtoul(optarg, &endptr, 0);
|
if (strspn(optarg, "01234567890ABCDEFabcdef") != 24)
|
||||||
if (endptr == optarg || *endptr != ',')
|
|
||||||
{
|
{
|
||||||
fprintf(stderr, _("%s: invalid argument for option -l\n"), progname);
|
fprintf(stderr, _("%s: invalid argument for option -l\n"), progname);
|
||||||
fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
|
fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
minXlogId = strtoul(endptr + 1, &endptr2, 0);
|
XLogFromFileName(optarg, &minXlogTli, &minXlogSegNo);
|
||||||
if (endptr2 == endptr + 1 || *endptr2 != ',')
|
|
||||||
{
|
|
||||||
fprintf(stderr, _("%s: invalid argument for option -l\n"), progname);
|
|
||||||
fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
minXlogSeg = strtoul(endptr2 + 1, &endptr3, 0);
|
|
||||||
if (endptr3 == endptr2 + 1 || *endptr3 != '\0')
|
|
||||||
{
|
|
||||||
fprintf(stderr, _("%s: invalid argument for option -l\n"), progname);
|
|
||||||
fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
minXlogSegNo = (uint64) minXlogId * XLogSegmentsPerXLogId + minXlogSeg;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -1013,7 +994,7 @@ usage(void)
|
||||||
printf(_("Options:\n"));
|
printf(_("Options:\n"));
|
||||||
printf(_(" -e XIDEPOCH set next transaction ID epoch\n"));
|
printf(_(" -e XIDEPOCH set next transaction ID epoch\n"));
|
||||||
printf(_(" -f force update to be done\n"));
|
printf(_(" -f force update to be done\n"));
|
||||||
printf(_(" -l TLI,FILE,SEG force minimum WAL starting location for new transaction log\n"));
|
printf(_(" -l xlogfile force minimum WAL starting location for new transaction log\n"));
|
||||||
printf(_(" -m XID set next multitransaction ID\n"));
|
printf(_(" -m XID set next multitransaction ID\n"));
|
||||||
printf(_(" -n no update, just show extracted control values (for testing)\n"));
|
printf(_(" -n no update, just show extracted control values (for testing)\n"));
|
||||||
printf(_(" -o OID set next OID\n"));
|
printf(_(" -o OID set next OID\n"));
|
||||||
|
|
Loading…
Reference in New Issue