Skip to content

Commit 2c36de4

Browse files
petereCommitfest Bot
authored andcommitted
pg_upgrade: Support for upgrading to checksums enabled
When upgrading between instances with different checksum settings, the --copy (default) mode automatically sets (or unsets) the checksum on the fly. TODO: What to do about the Windows code path?
1 parent 8a3e401 commit 2c36de4

File tree

5 files changed

+49
-15
lines changed

5 files changed

+49
-15
lines changed

src/bin/pg_upgrade/controldata.c

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -735,18 +735,12 @@ check_control_data(ControlData *oldctrl,
735735
* check_for_isn_and_int8_passing_mismatch().
736736
*/
737737

738-
/*
739-
* We might eventually allow upgrades from checksum to no-checksum
740-
* clusters.
741-
*/
742-
if (oldctrl->data_checksum_version == 0 &&
743-
newctrl->data_checksum_version != 0)
744-
pg_fatal("old cluster does not use data checksums but the new one does");
745-
else if (oldctrl->data_checksum_version != 0 &&
746-
newctrl->data_checksum_version == 0)
747-
pg_fatal("old cluster uses data checksums but the new one does not");
748-
else if (oldctrl->data_checksum_version != newctrl->data_checksum_version)
749-
pg_fatal("old and new cluster pg_controldata checksum versions do not match");
738+
/* FIXME: what about upgrade from checksum to non-checksum? */
739+
if (oldctrl->data_checksum_version != newctrl->data_checksum_version)
740+
{
741+
if (!user_opts.update_checksums)
742+
pg_fatal("when upgrading between clusters with different data checksum settings, option %s must be used", "--update-checksums");
743+
}
750744
}
751745

752746

src/bin/pg_upgrade/file.c

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,14 @@ cloneFile(const char *src, const char *dst,
8080
*/
8181
void
8282
copyFile(const char *src, const char *dst,
83-
const char *schemaName, const char *relName)
83+
const char *schemaName, const char *relName,
84+
int segno)
8485
{
8586
#ifndef WIN32
8687
int src_fd;
8788
int dest_fd;
8889
char *buffer;
90+
BlockNumber blocknum;
8991

9092
if ((src_fd = open(src, O_RDONLY | PG_BINARY, 0)) < 0)
9193
pg_fatal("error while copying relation \"%s.%s\": could not open file \"%s\": %m",
@@ -101,6 +103,8 @@ copyFile(const char *src, const char *dst,
101103

102104
buffer = (char *) pg_malloc(COPY_BUF_SIZE);
103105

106+
blocknum = segno * old_cluster.controldata.largesz;
107+
104108
/* perform data copying i.e read src source, write to destination */
105109
while (true)
106110
{
@@ -113,6 +117,31 @@ copyFile(const char *src, const char *dst,
113117
if (nbytes == 0)
114118
break;
115119

120+
/*
121+
* Update checksums if requested
122+
*/
123+
if (user_opts.update_checksums)
124+
{
125+
/* must deal in whole blocks */
126+
nbytes = nbytes / BLCKSZ * BLCKSZ;
127+
128+
for (int i = 0; i * BLCKSZ < nbytes; i++)
129+
{
130+
PageData *page = buffer + i * BLCKSZ;
131+
PageHeader header = (PageHeader) page;
132+
133+
if (PageIsNew(page))
134+
continue;
135+
136+
if (new_cluster.controldata.data_checksum_version == 1)
137+
header->pd_checksum = pg_checksum_page(page, blocknum);
138+
else
139+
header->pd_checksum = 0;
140+
141+
blocknum++;
142+
}
143+
}
144+
116145
errno = 0;
117146
if (write(dest_fd, buffer, nbytes) != nbytes)
118147
{

src/bin/pg_upgrade/option.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ parseCommandLine(int argc, char *argv[])
6262
{"sync-method", required_argument, NULL, 4},
6363
{"no-statistics", no_argument, NULL, 5},
6464
{"set-char-signedness", required_argument, NULL, 6},
65+
{"update-checksums", no_argument, NULL, 7},
6566

6667
{NULL, 0, NULL, 0}
6768
};
@@ -228,6 +229,11 @@ parseCommandLine(int argc, char *argv[])
228229
else
229230
pg_fatal("invalid argument for option %s", "--set-char-signedness");
230231
break;
232+
233+
case 7:
234+
user_opts.update_checksums = true;
235+
break;
236+
231237
default:
232238
fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
233239
os_info.progname);
@@ -241,6 +247,9 @@ parseCommandLine(int argc, char *argv[])
241247
if (!user_opts.sync_method)
242248
user_opts.sync_method = pg_strdup("fsync");
243249

250+
if (user_opts.update_checksums && user_opts.transfer_mode != TRANSFER_MODE_COPY)
251+
pg_fatal("option %s requires transfer mode %s", "--update-checksums", "--copy");
252+
244253
if (log_opts.verbose)
245254
pg_log(PG_REPORT, "Running in verbose mode");
246255

src/bin/pg_upgrade/pg_upgrade.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,7 @@ typedef struct
337337
int char_signedness; /* default char signedness: -1 for initial
338338
* value, 1 for "signed" and 0 for
339339
* "unsigned" */
340+
bool update_checksums;
340341
} UserOpts;
341342

342343
typedef struct
@@ -414,7 +415,8 @@ bool pid_lock_file_exists(const char *datadir);
414415
void cloneFile(const char *src, const char *dst,
415416
const char *schemaName, const char *relName);
416417
void copyFile(const char *src, const char *dst,
417-
const char *schemaName, const char *relName);
418+
const char *schemaName, const char *relName,
419+
int segno);
418420
void copyFileByRange(const char *src, const char *dst,
419421
const char *schemaName, const char *relName);
420422
void linkFile(const char *src, const char *dst,

src/bin/pg_upgrade/relfilenumber.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ transfer_relfile(FileNameMap *map, const char *type_suffix, bool vm_must_add_fro
248248
case TRANSFER_MODE_COPY:
249249
pg_log(PG_VERBOSE, "copying \"%s\" to \"%s\"",
250250
old_file, new_file);
251-
copyFile(old_file, new_file, map->nspname, map->relname);
251+
copyFile(old_file, new_file, map->nspname, map->relname, segno);
252252
break;
253253
case TRANSFER_MODE_COPY_FILE_RANGE:
254254
pg_log(PG_VERBOSE, "copying \"%s\" to \"%s\" with copy_file_range",

0 commit comments

Comments
 (0)