Line data Source code
1 : /*-------------------------------------------------------------------------
2 : *
3 : * xlogbackup.c
4 : * Internal routines for base backups.
5 : *
6 : * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
7 : * Portions Copyright (c) 1994, Regents of the University of California
8 : *
9 : * IDENTIFICATION
10 : * src/backend/access/transam/xlogbackup.c
11 : *-------------------------------------------------------------------------
12 : */
13 :
14 : #include "postgres.h"
15 :
16 : #include "access/xlog.h"
17 : #include "access/xlog_internal.h"
18 : #include "access/xlogbackup.h"
19 :
20 : /*
21 : * Build contents for backup_label or backup history file.
22 : *
23 : * When ishistoryfile is true, it creates the contents for a backup history
24 : * file, otherwise it creates contents for a backup_label file.
25 : *
26 : * Returns the result generated as a palloc'd string.
27 : */
28 : char *
29 632 : build_backup_content(BackupState *state, bool ishistoryfile)
30 : {
31 : char startstrbuf[128];
32 : char startxlogfile[MAXFNAMELEN]; /* backup start WAL file */
33 : XLogSegNo startsegno;
34 : StringInfoData result;
35 :
36 : Assert(state != NULL);
37 :
38 632 : initStringInfo(&result);
39 :
40 : /* Use the log timezone here, not the session timezone */
41 632 : pg_strftime(startstrbuf, sizeof(startstrbuf), "%Y-%m-%d %H:%M:%S %Z",
42 632 : pg_localtime(&state->starttime, log_timezone));
43 :
44 632 : XLByteToSeg(state->startpoint, startsegno, wal_segment_size);
45 632 : XLogFileName(startxlogfile, state->starttli, startsegno, wal_segment_size);
46 632 : appendStringInfo(&result, "START WAL LOCATION: %X/%08X (file %s)\n",
47 632 : LSN_FORMAT_ARGS(state->startpoint), startxlogfile);
48 :
49 632 : if (ishistoryfile)
50 : {
51 : char stopxlogfile[MAXFNAMELEN]; /* backup stop WAL file */
52 : XLogSegNo stopsegno;
53 :
54 304 : XLByteToSeg(state->stoppoint, stopsegno, wal_segment_size);
55 304 : XLogFileName(stopxlogfile, state->stoptli, stopsegno, wal_segment_size);
56 304 : appendStringInfo(&result, "STOP WAL LOCATION: %X/%08X (file %s)\n",
57 304 : LSN_FORMAT_ARGS(state->stoppoint), stopxlogfile);
58 : }
59 :
60 632 : appendStringInfo(&result, "CHECKPOINT LOCATION: %X/%08X\n",
61 632 : LSN_FORMAT_ARGS(state->checkpointloc));
62 632 : appendStringInfoString(&result, "BACKUP METHOD: streamed\n");
63 632 : appendStringInfo(&result, "BACKUP FROM: %s\n",
64 632 : state->started_in_recovery ? "standby" : "primary");
65 632 : appendStringInfo(&result, "START TIME: %s\n", startstrbuf);
66 632 : appendStringInfo(&result, "LABEL: %s\n", state->name);
67 632 : appendStringInfo(&result, "START TIMELINE: %u\n", state->starttli);
68 :
69 632 : if (ishistoryfile)
70 : {
71 : char stopstrfbuf[128];
72 :
73 : /* Use the log timezone here, not the session timezone */
74 304 : pg_strftime(stopstrfbuf, sizeof(stopstrfbuf), "%Y-%m-%d %H:%M:%S %Z",
75 304 : pg_localtime(&state->stoptime, log_timezone));
76 :
77 304 : appendStringInfo(&result, "STOP TIME: %s\n", stopstrfbuf);
78 304 : appendStringInfo(&result, "STOP TIMELINE: %u\n", state->stoptli);
79 : }
80 :
81 : /* either both istartpoint and istarttli should be set, or neither */
82 : Assert(XLogRecPtrIsValid(state->istartpoint) == (state->istarttli != 0));
83 632 : if (XLogRecPtrIsValid(state->istartpoint))
84 : {
85 40 : appendStringInfo(&result, "INCREMENTAL FROM LSN: %X/%08X\n",
86 40 : LSN_FORMAT_ARGS(state->istartpoint));
87 40 : appendStringInfo(&result, "INCREMENTAL FROM TLI: %u\n",
88 : state->istarttli);
89 : }
90 :
91 632 : return result.data;
92 : }
|