PostgreSQL Source Code git master
Loading...
Searching...
No Matches
controldata.c
Go to the documentation of this file.
1/*
2 * controldata.c
3 *
4 * controldata functions
5 *
6 * Copyright (c) 2010-2026, PostgreSQL Global Development Group
7 * src/bin/pg_upgrade/controldata.c
8 */
9
10#include "postgres_fe.h"
11
12#include <ctype.h>
13#include <limits.h> /* for CHAR_MIN */
14
16#include "common/string.h"
17#include "pg_upgrade.h"
18#include "storage/checksum.h"
19
20
21/*
22 * get_control_data()
23 *
24 * gets pg_control information in "ctrl". Assumes that bindir and
25 * datadir are valid absolute paths to postgresql bin and pgdata
26 * directories respectively *and* pg_resetwal is version compatible
27 * with datadir. The main purpose of this function is to get pg_control
28 * data in a version independent manner.
29 *
30 * The approach taken here is to invoke pg_resetwal with -n option
31 * and then pipe its output. With little string parsing we get the
32 * pg_control data. pg_resetwal cannot be run while the server is running
33 * so we use pg_controldata; pg_controldata doesn't provide all the fields
34 * we need to actually perform the upgrade, but it provides enough for
35 * check mode. We do not implement pg_resetwal -n because it is hard to
36 * return valid xid data for a running server.
37 */
38void
40{
41 char cmd[MAXPGPATH];
42 char bufin[MAX_STRING];
43 FILE *output;
44 char *p;
45 bool got_xid = false;
46 bool got_oid = false;
47 bool got_multi = false;
48 bool got_oldestmulti = false;
49 bool got_oldestxid = false;
50 bool got_mxoff = false;
51 bool got_nextxlogfile = false;
52 bool got_float8_pass_by_value = false;
53 bool got_align = false;
54 bool got_blocksz = false;
55 bool got_largesz = false;
56 bool got_walsz = false;
57 bool got_walseg = false;
58 bool got_ident = false;
59 bool got_index = false;
60 bool got_toast = false;
61 bool got_large_object = false;
62 bool got_date_is_int = false;
63 bool got_data_checksum_version = false;
64 bool got_cluster_state = false;
65 bool got_default_char_signedness = false;
66 char *lc_collate = NULL;
67 char *lc_ctype = NULL;
68 char *lc_monetary = NULL;
69 char *lc_numeric = NULL;
70 char *lc_time = NULL;
71 char *lang = NULL;
72 char *language = NULL;
73 char *lc_all = NULL;
74 char *lc_messages = NULL;
75 int rc;
76 bool live_check = (cluster == &old_cluster && user_opts.live_check);
77
78 /*
79 * Because we test the pg_resetwal output as strings, it has to be in
80 * English. Copied from pg_regress.c.
81 */
82 if (getenv("LC_COLLATE"))
83 lc_collate = pg_strdup(getenv("LC_COLLATE"));
84 if (getenv("LC_CTYPE"))
85 lc_ctype = pg_strdup(getenv("LC_CTYPE"));
86 if (getenv("LC_MONETARY"))
87 lc_monetary = pg_strdup(getenv("LC_MONETARY"));
88 if (getenv("LC_NUMERIC"))
89 lc_numeric = pg_strdup(getenv("LC_NUMERIC"));
90 if (getenv("LC_TIME"))
91 lc_time = pg_strdup(getenv("LC_TIME"));
92 if (getenv("LANG"))
93 lang = pg_strdup(getenv("LANG"));
94 if (getenv("LANGUAGE"))
95 language = pg_strdup(getenv("LANGUAGE"));
96 if (getenv("LC_ALL"))
97 lc_all = pg_strdup(getenv("LC_ALL"));
98 if (getenv("LC_MESSAGES"))
99 lc_messages = pg_strdup(getenv("LC_MESSAGES"));
100
101 unsetenv("LC_COLLATE");
102 unsetenv("LC_CTYPE");
103 unsetenv("LC_MONETARY");
104 unsetenv("LC_NUMERIC");
105 unsetenv("LC_TIME");
106#ifndef WIN32
107 unsetenv("LANG");
108#else
109 /* On Windows the default locale may not be English, so force it */
110 setenv("LANG", "en", 1);
111#endif
112 unsetenv("LANGUAGE");
113 unsetenv("LC_ALL");
114 setenv("LC_MESSAGES", "C", 1);
115
116 /*
117 * Check for clean shutdown
118 */
119 if (!live_check || cluster == &new_cluster)
120 {
121 /* only pg_controldata outputs the cluster state */
122 snprintf(cmd, sizeof(cmd), "\"%s/pg_controldata\" \"%s\"",
123 cluster->bindir, cluster->pgdata);
124 fflush(NULL);
125
126 if ((output = popen(cmd, "r")) == NULL)
127 pg_fatal("could not get control data using %s: %m", cmd);
128
129 /* we have the result of cmd in "output". so parse it line by line now */
130 while (fgets(bufin, sizeof(bufin), output))
131 {
132 if ((p = strstr(bufin, "Database cluster state:")) != NULL)
133 {
134 p = strchr(p, ':');
135
136 if (p == NULL || strlen(p) <= 1)
137 pg_fatal("%d: database cluster state problem", __LINE__);
138
139 p++; /* remove ':' char */
140
141 /*
142 * We checked earlier for a postmaster lock file, and if we
143 * found one, we tried to start/stop the server to replay the
144 * WAL. However, pg_ctl -m immediate doesn't leave a lock
145 * file, but does require WAL replay, so we check here that
146 * the server was shut down cleanly, from the controldata
147 * perspective.
148 */
149 /* Remove trailing newline and leading spaces */
150 (void) pg_strip_crlf(p);
151 while (*p == ' ')
152 p++;
153 if (strcmp(p, "shut down in recovery") == 0)
154 {
155 if (cluster == &old_cluster)
156 pg_fatal("The source cluster was shut down while in recovery mode. To upgrade, use \"rsync\" as documented or shut it down as a primary.");
157 else
158 pg_fatal("The target cluster was shut down while in recovery mode. To upgrade, use \"rsync\" as documented or shut it down as a primary.");
159 }
160 else if (strcmp(p, "shut down") != 0)
161 {
162 if (cluster == &old_cluster)
163 pg_fatal("The source cluster was not shut down cleanly, state reported as: \"%s\"", p);
164 else
165 pg_fatal("The target cluster was not shut down cleanly, state reported as: \"%s\"", p);
166 }
167 got_cluster_state = true;
168 }
169 }
170
171 rc = pclose(output);
172 if (rc != 0)
173 pg_fatal("could not get control data using %s: %s",
174 cmd, wait_result_to_str(rc));
175
177 {
178 if (cluster == &old_cluster)
179 pg_fatal("The source cluster lacks cluster state information:");
180 else
181 pg_fatal("The target cluster lacks cluster state information:");
182 }
183 }
184
185 snprintf(cmd, sizeof(cmd), "\"%s/%s \"%s\"",
186 cluster->bindir,
187 live_check ? "pg_controldata\"" : "pg_resetwal\" -n",
188 cluster->pgdata);
189 fflush(NULL);
190
191 if ((output = popen(cmd, "r")) == NULL)
192 pg_fatal("could not get control data using %s: %m", cmd);
193
194 /* we have the result of cmd in "output". so parse it line by line now */
195 while (fgets(bufin, sizeof(bufin), output))
196 {
197 /* In verbose mode, log each line */
199 pg_log(PG_VERBOSE, "%s", bufin);
200
201 if ((p = strstr(bufin, "pg_control version number:")) != NULL)
202 {
203 p = strchr(p, ':');
204
205 if (p == NULL || strlen(p) <= 1)
206 pg_fatal("%d: pg_resetwal problem", __LINE__);
207
208 p++; /* remove ':' char */
209 cluster->controldata.ctrl_ver = str2uint(p);
210 }
211 else if ((p = strstr(bufin, "Catalog version number:")) != NULL)
212 {
213 p = strchr(p, ':');
214
215 if (p == NULL || strlen(p) <= 1)
216 pg_fatal("%d: controldata retrieval problem", __LINE__);
217
218 p++; /* remove ':' char */
219 cluster->controldata.cat_ver = str2uint(p);
220 }
221 else if ((p = strstr(bufin, "Latest checkpoint's NextXID:")) != NULL)
222 {
223 p = strchr(p, ':');
224
225 if (p == NULL || strlen(p) <= 1)
226 pg_fatal("%d: controldata retrieval problem", __LINE__);
227
228 p++; /* remove ':' char */
229 cluster->controldata.chkpnt_nxtepoch = str2uint(p);
230
231 p = strchr(p, ':');
232
233 if (p == NULL || strlen(p) <= 1)
234 pg_fatal("%d: controldata retrieval problem", __LINE__);
235
236 p++; /* remove ':' char */
237 cluster->controldata.chkpnt_nxtxid = str2uint(p);
238 got_xid = true;
239 }
240 else if ((p = strstr(bufin, "Latest checkpoint's NextOID:")) != NULL)
241 {
242 p = strchr(p, ':');
243
244 if (p == NULL || strlen(p) <= 1)
245 pg_fatal("%d: controldata retrieval problem", __LINE__);
246
247 p++; /* remove ':' char */
248 cluster->controldata.chkpnt_nxtoid = str2uint(p);
249 got_oid = true;
250 }
251 else if ((p = strstr(bufin, "Latest checkpoint's NextMultiXactId:")) != NULL)
252 {
253 p = strchr(p, ':');
254
255 if (p == NULL || strlen(p) <= 1)
256 pg_fatal("%d: controldata retrieval problem", __LINE__);
257
258 p++; /* remove ':' char */
259 cluster->controldata.chkpnt_nxtmulti = str2uint(p);
260 got_multi = true;
261 }
262 else if ((p = strstr(bufin, "Latest checkpoint's oldestXID:")) != NULL)
263 {
264 p = strchr(p, ':');
265
266 if (p == NULL || strlen(p) <= 1)
267 pg_fatal("%d: controldata retrieval problem", __LINE__);
268
269 p++; /* remove ':' char */
270 cluster->controldata.chkpnt_oldstxid = str2uint(p);
271 got_oldestxid = true;
272 }
273 else if ((p = strstr(bufin, "Latest checkpoint's oldestMultiXid:")) != NULL)
274 {
275 p = strchr(p, ':');
276
277 if (p == NULL || strlen(p) <= 1)
278 pg_fatal("%d: controldata retrieval problem", __LINE__);
279
280 p++; /* remove ':' char */
281 cluster->controldata.chkpnt_oldstMulti = str2uint(p);
282 got_oldestmulti = true;
283 }
284 else if ((p = strstr(bufin, "Latest checkpoint's NextMultiOffset:")) != NULL)
285 {
286 p = strchr(p, ':');
287
288 if (p == NULL || strlen(p) <= 1)
289 pg_fatal("%d: controldata retrieval problem", __LINE__);
290
291 p++; /* remove ':' char */
292 cluster->controldata.chkpnt_nxtmxoff = str2uint(p);
293 got_mxoff = true;
294 }
295 else if ((p = strstr(bufin, "First log segment after reset:")) != NULL)
296 {
297 /* Skip the colon and any whitespace after it */
298 p = strchr(p, ':');
299 if (p == NULL || strlen(p) <= 1)
300 pg_fatal("%d: controldata retrieval problem", __LINE__);
301 p = strpbrk(p, "0123456789ABCDEF");
302 if (p == NULL || strlen(p) <= 1)
303 pg_fatal("%d: controldata retrieval problem", __LINE__);
304
305 /* Make sure it looks like a valid WAL file name */
306 if (strspn(p, "0123456789ABCDEF") != 24)
307 pg_fatal("%d: controldata retrieval problem", __LINE__);
308
309 strlcpy(cluster->controldata.nextxlogfile, p, 25);
310 got_nextxlogfile = true;
311 }
312 else if ((p = strstr(bufin, "Float8 argument passing:")) != NULL)
313 {
314 p = strchr(p, ':');
315
316 if (p == NULL || strlen(p) <= 1)
317 pg_fatal("%d: controldata retrieval problem", __LINE__);
318
319 p++; /* remove ':' char */
320 /* used later for contrib check */
321 cluster->controldata.float8_pass_by_value = strstr(p, "by value") != NULL;
323 }
324 else if ((p = strstr(bufin, "Maximum data alignment:")) != NULL)
325 {
326 p = strchr(p, ':');
327
328 if (p == NULL || strlen(p) <= 1)
329 pg_fatal("%d: controldata retrieval problem", __LINE__);
330
331 p++; /* remove ':' char */
332 cluster->controldata.align = str2uint(p);
333 got_align = true;
334 }
335 else if ((p = strstr(bufin, "Database block size:")) != NULL)
336 {
337 p = strchr(p, ':');
338
339 if (p == NULL || strlen(p) <= 1)
340 pg_fatal("%d: controldata retrieval problem", __LINE__);
341
342 p++; /* remove ':' char */
343 cluster->controldata.blocksz = str2uint(p);
344 got_blocksz = true;
345 }
346 else if ((p = strstr(bufin, "Blocks per segment of large relation:")) != NULL)
347 {
348 p = strchr(p, ':');
349
350 if (p == NULL || strlen(p) <= 1)
351 pg_fatal("%d: controldata retrieval problem", __LINE__);
352
353 p++; /* remove ':' char */
354 cluster->controldata.largesz = str2uint(p);
355 got_largesz = true;
356 }
357 else if ((p = strstr(bufin, "WAL block size:")) != NULL)
358 {
359 p = strchr(p, ':');
360
361 if (p == NULL || strlen(p) <= 1)
362 pg_fatal("%d: controldata retrieval problem", __LINE__);
363
364 p++; /* remove ':' char */
365 cluster->controldata.walsz = str2uint(p);
366 got_walsz = true;
367 }
368 else if ((p = strstr(bufin, "Bytes per WAL segment:")) != NULL)
369 {
370 p = strchr(p, ':');
371
372 if (p == NULL || strlen(p) <= 1)
373 pg_fatal("%d: controldata retrieval problem", __LINE__);
374
375 p++; /* remove ':' char */
376 cluster->controldata.walseg = str2uint(p);
377 got_walseg = true;
378 }
379 else if ((p = strstr(bufin, "Maximum length of identifiers:")) != NULL)
380 {
381 p = strchr(p, ':');
382
383 if (p == NULL || strlen(p) <= 1)
384 pg_fatal("%d: controldata retrieval problem", __LINE__);
385
386 p++; /* remove ':' char */
387 cluster->controldata.ident = str2uint(p);
388 got_ident = true;
389 }
390 else if ((p = strstr(bufin, "Maximum columns in an index:")) != NULL)
391 {
392 p = strchr(p, ':');
393
394 if (p == NULL || strlen(p) <= 1)
395 pg_fatal("%d: controldata retrieval problem", __LINE__);
396
397 p++; /* remove ':' char */
398 cluster->controldata.index = str2uint(p);
399 got_index = true;
400 }
401 else if ((p = strstr(bufin, "Maximum size of a TOAST chunk:")) != NULL)
402 {
403 p = strchr(p, ':');
404
405 if (p == NULL || strlen(p) <= 1)
406 pg_fatal("%d: controldata retrieval problem", __LINE__);
407
408 p++; /* remove ':' char */
409 cluster->controldata.toast = str2uint(p);
410 got_toast = true;
411 }
412 else if ((p = strstr(bufin, "Size of a large-object chunk:")) != NULL)
413 {
414 p = strchr(p, ':');
415
416 if (p == NULL || strlen(p) <= 1)
417 pg_fatal("%d: controldata retrieval problem", __LINE__);
418
419 p++; /* remove ':' char */
420 cluster->controldata.large_object = str2uint(p);
421 got_large_object = true;
422 }
423 else if ((p = strstr(bufin, "Date/time type storage:")) != NULL)
424 {
425 p = strchr(p, ':');
426
427 if (p == NULL || strlen(p) <= 1)
428 pg_fatal("%d: controldata retrieval problem", __LINE__);
429
430 p++; /* remove ':' char */
431 cluster->controldata.date_is_int = strstr(p, "64-bit integers") != NULL;
432 got_date_is_int = true;
433 }
434 else if ((p = strstr(bufin, "checksum")) != NULL)
435 {
436 p = strchr(p, ':');
437
438 if (p == NULL || strlen(p) <= 1)
439 pg_fatal("%d: controldata retrieval problem", __LINE__);
440
441 p++; /* remove ':' char */
442 cluster->controldata.data_checksum_version = str2uint(p);
444 }
445 else if ((p = strstr(bufin, "Default char data signedness:")) != NULL)
446 {
447 p = strchr(p, ':');
448
449 if (p == NULL || strlen(p) <= 1)
450 pg_fatal("%d: controldata retrieval problem", __LINE__);
451
452 /* Skip the colon and any whitespace after it */
453 p++;
454 while (isspace((unsigned char) *p))
455 p++;
456
457 /* The value should be either 'signed' or 'unsigned' */
458 if (strcmp(p, "signed") != 0 && strcmp(p, "unsigned") != 0)
459 pg_fatal("%d: controldata retrieval problem", __LINE__);
460
461 cluster->controldata.default_char_signedness = strcmp(p, "signed") == 0;
463 }
464 }
465
466 rc = pclose(output);
467 if (rc != 0)
468 pg_fatal("could not get control data using %s: %s",
469 cmd, wait_result_to_str(rc));
470
471 /*
472 * Restore environment variables. Note all but LANG and LC_MESSAGES were
473 * unset above.
474 */
475 if (lc_collate)
476 setenv("LC_COLLATE", lc_collate, 1);
477 if (lc_ctype)
478 setenv("LC_CTYPE", lc_ctype, 1);
479 if (lc_monetary)
480 setenv("LC_MONETARY", lc_monetary, 1);
481 if (lc_numeric)
482 setenv("LC_NUMERIC", lc_numeric, 1);
483 if (lc_time)
484 setenv("LC_TIME", lc_time, 1);
485 if (lang)
486 setenv("LANG", lang, 1);
487 else
488 unsetenv("LANG");
489 if (language)
490 setenv("LANGUAGE", language, 1);
491 if (lc_all)
492 setenv("LC_ALL", lc_all, 1);
493 if (lc_messages)
494 setenv("LC_MESSAGES", lc_messages, 1);
495 else
496 unsetenv("LC_MESSAGES");
497
503 pg_free(lang);
507
508 /*
509 * Pre-v18 database clusters don't have the default char signedness
510 * information. We use the char signedness of the platform where
511 * pg_upgrade was built.
512 */
513 if (cluster->controldata.cat_ver < DEFAULT_CHAR_SIGNEDNESS_CAT_VER)
514 {
516#if CHAR_MIN != 0
517 cluster->controldata.default_char_signedness = true;
518#else
519 cluster->controldata.default_char_signedness = false;
520#endif
521 }
522
523 /* verify that we got all the mandatory pg_control data */
524 if (!got_xid || !got_oid ||
527 !got_mxoff || (!live_check && !got_nextxlogfile) ||
530 !got_index || !got_toast ||
534 cluster->controldata.cat_ver >= DEFAULT_CHAR_SIGNEDNESS_CAT_VER))
535 {
536 if (cluster == &old_cluster)
538 "The source cluster lacks some required control information:");
539 else
541 "The target cluster lacks some required control information:");
542
543 if (!got_xid)
544 pg_log(PG_REPORT, " checkpoint next XID");
545
546 if (!got_oid)
547 pg_log(PG_REPORT, " latest checkpoint next OID");
548
549 if (!got_multi)
550 pg_log(PG_REPORT, " latest checkpoint next MultiXactId");
551
552 if (!got_oldestmulti)
553 pg_log(PG_REPORT, " latest checkpoint oldest MultiXactId");
554
555 if (!got_oldestxid)
556 pg_log(PG_REPORT, " latest checkpoint oldestXID");
557
558 if (!got_mxoff)
559 pg_log(PG_REPORT, " latest checkpoint next MultiXactOffset");
560
561 if (!live_check && !got_nextxlogfile)
562 pg_log(PG_REPORT, " first WAL segment after reset");
563
565 pg_log(PG_REPORT, " float8 argument passing method");
566
567 if (!got_align)
568 pg_log(PG_REPORT, " maximum alignment");
569
570 if (!got_blocksz)
571 pg_log(PG_REPORT, " block size");
572
573 if (!got_largesz)
574 pg_log(PG_REPORT, " large relation segment size");
575
576 if (!got_walsz)
577 pg_log(PG_REPORT, " WAL block size");
578
579 if (!got_walseg)
580 pg_log(PG_REPORT, " WAL segment size");
581
582 if (!got_ident)
583 pg_log(PG_REPORT, " maximum identifier length");
584
585 if (!got_index)
586 pg_log(PG_REPORT, " maximum number of indexed columns");
587
588 if (!got_toast)
589 pg_log(PG_REPORT, " maximum TOAST chunk size");
590
591 if (!got_large_object)
592 pg_log(PG_REPORT, " large-object chunk size");
593
594 if (!got_date_is_int)
595 pg_log(PG_REPORT, " dates/times are integers?");
596
597 /* value added in Postgres 9.3 */
599 pg_log(PG_REPORT, " data checksum version");
600
601 /* value added in Postgres 18 */
603 pg_log(PG_REPORT, " default char signedness");
604
605 pg_fatal("Cannot continue without required control information, terminating");
606 }
607}
608
609
610/*
611 * check_control_data()
612 *
613 * check to make sure the control data settings are compatible
614 */
615void
618{
619 if (oldctrl->align == 0 || oldctrl->align != newctrl->align)
620 pg_fatal("old and new pg_controldata alignments are invalid or do not match.\n"
621 "Likely one cluster is a 32-bit install, the other 64-bit");
622
623 if (oldctrl->blocksz == 0 || oldctrl->blocksz != newctrl->blocksz)
624 pg_fatal("old and new pg_controldata block sizes are invalid or do not match");
625
626 if (oldctrl->largesz == 0 || oldctrl->largesz != newctrl->largesz)
627 pg_fatal("old and new pg_controldata maximum relation segment sizes are invalid or do not match");
628
629 if (oldctrl->walsz == 0 || oldctrl->walsz != newctrl->walsz)
630 pg_fatal("old and new pg_controldata WAL block sizes are invalid or do not match");
631
632 if (oldctrl->walseg == 0 || oldctrl->walseg != newctrl->walseg)
633 pg_fatal("old and new pg_controldata WAL segment sizes are invalid or do not match");
634
635 if (oldctrl->ident == 0 || oldctrl->ident != newctrl->ident)
636 pg_fatal("old and new pg_controldata maximum identifier lengths are invalid or do not match");
637
638 if (oldctrl->index == 0 || oldctrl->index != newctrl->index)
639 pg_fatal("old and new pg_controldata maximum indexed columns are invalid or do not match");
640
641 if (oldctrl->toast == 0 || oldctrl->toast != newctrl->toast)
642 pg_fatal("old and new pg_controldata maximum TOAST chunk sizes are invalid or do not match");
643
644 if (oldctrl->large_object == 0 ||
645 oldctrl->large_object != newctrl->large_object)
646 pg_fatal("old and new pg_controldata large-object chunk sizes are invalid or do not match");
647
648 if (oldctrl->date_is_int != newctrl->date_is_int)
649 pg_fatal("old and new pg_controldata date/time storage types do not match");
650
651 /*
652 * float8_pass_by_value does not need to match, but is used in
653 * check_for_isn_and_int8_passing_mismatch().
654 */
655
656 /*
657 * If data checksums are in any in-progress state then disallow the
658 * upgrade. The user should either let the process finish, or turn off
659 * data checksums, before retrying.
660 */
661 if (oldctrl->data_checksum_version > PG_DATA_CHECKSUM_VERSION)
662 pg_fatal("checksums are being enabled in the old cluster");
663
664 /*
665 * We might eventually allow upgrades from checksum to no-checksum
666 * clusters.
667 */
668 if (oldctrl->data_checksum_version == PG_DATA_CHECKSUM_OFF &&
669 newctrl->data_checksum_version != PG_DATA_CHECKSUM_OFF)
670 pg_fatal("old cluster does not use data checksums but the new one does");
671 else if (oldctrl->data_checksum_version != PG_DATA_CHECKSUM_OFF &&
672 newctrl->data_checksum_version == PG_DATA_CHECKSUM_OFF)
673 pg_fatal("old cluster uses data checksums but the new one does not");
674 else if (oldctrl->data_checksum_version != newctrl->data_checksum_version)
675 pg_fatal("old and new cluster pg_controldata checksum versions do not match");
676}
677
678
679void
681{
682 char old_path[MAXPGPATH],
684
685 /* rename pg_control so old server cannot be accidentally started */
686 /* translator: %s is the file path of the control file */
687 prep_status("Adding \".old\" suffix to old \"%s\"", XLOG_CONTROL_FILE);
688
691 if (pg_mv_file(old_path, new_path) != 0)
692 pg_fatal("could not rename file \"%s\" to \"%s\": %m",
694 check_ok();
695
696 if (transfer_mode == TRANSFER_MODE_LINK)
697 /* translator: %s/%s is the file path of the control file */
698 pg_log(PG_REPORT, "\n"
699 "If you want to start the old cluster, you will need to remove\n"
700 "the \".old\" suffix from \"%s/%s.old\".\n"
701 "Because \"link\" mode was used, the old cluster cannot be safely\n"
702 "started once the new cluster has been started.",
704 else if (transfer_mode == TRANSFER_MODE_SWAP)
705 pg_log(PG_REPORT, "\n"
706 "Because \"swap\" mode was used, the old cluster can no longer be\n"
707 "safely started.");
708 else
709 pg_fatal("unrecognized transfer mode");
710}
#define Assert(condition)
Definition c.h:1002
@ PG_DATA_CHECKSUM_VERSION
Definition checksum.h:29
@ PG_DATA_CHECKSUM_OFF
Definition checksum.h:28
void get_control_data(ClusterInfo *cluster)
Definition controldata.c:39
void check_control_data(ControlData *oldctrl, ControlData *newctrl)
void disable_old_cluster(transferMode transfer_mode)
char * pg_strdup(const char *in)
Definition fe_memutils.c:91
void pg_free(void *ptr)
FILE * output
static char * lc_collate
Definition initdb.c:141
static char * lc_time
Definition initdb.c:145
static char * lc_ctype
Definition initdb.c:142
static char * lc_messages
Definition initdb.c:146
static char * lc_numeric
Definition initdb.c:144
static void check_ok(void)
Definition initdb.c:2138
static char * lc_monetary
Definition initdb.c:143
#define pg_fatal(...)
#define MAXPGPATH
ClusterInfo new_cluster
Definition pg_upgrade.c:74
ClusterInfo old_cluster
Definition pg_upgrade.c:73
#define pg_mv_file
Definition pg_upgrade.h:81
void void unsigned int str2uint(const char *str)
Definition util.c:352
void void pg_log(eLogType type, const char *fmt,...) pg_attribute_printf(2
transferMode
Definition pg_upgrade.h:243
@ TRANSFER_MODE_LINK
Definition pg_upgrade.h:247
@ TRANSFER_MODE_SWAP
Definition pg_upgrade.h:248
@ PG_VERBOSE
Definition pg_upgrade.h:256
@ PG_REPORT
Definition pg_upgrade.h:259
#define MAX_STRING
Definition pg_upgrade.h:22
#define DEFAULT_CHAR_SIGNEDNESS_CAT_VER
Definition pg_upgrade.h:115
void prep_status(const char *fmt,...) pg_attribute_printf(1
#define snprintf
Definition port.h:261
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition strlcpy.c:45
static int fb(int x)
UserOpts user_opts
Definition option.c:30
int pg_strip_crlf(char *str)
Definition string.c:154
char * pgdata
Definition pg_upgrade.h:275
bool live_check
Definition pg_upgrade.h:318
char * wait_result_to_str(int exitstatus)
Definition wait_error.c:33
#define unsetenv(x)
Definition win32_port.h:560
#define setenv(x, y, z)
Definition win32_port.h:559
#define XLOG_CONTROL_FILE