Skip to content

Commit 88c1312

Browse files
committed
Merge branch 'master' into issue_324
2 parents 8a3dfd5 + 731d190 commit 88c1312

26 files changed

+850
-122
lines changed

doc/pgprobackup.xml

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ doc/src/sgml/pgprobackup.sgml
155155
recovery of <productname>PostgreSQL</productname> database clusters.
156156
It is designed to perform periodic backups of the <productname>PostgreSQL</productname>
157157
instance that enable you to restore the server in case of a failure.
158-
<application>pg_probackup</application> supports <productname>PostgreSQL</productname> 9.5 or higher.
158+
<application>pg_probackup</application> supports PostgreSQL 9.5 or higher.
159159
</para>
160160

161161
<itemizedlist spacing="compact">
@@ -389,7 +389,7 @@ doc/src/sgml/pgprobackup.sgml
389389
<itemizedlist spacing="compact">
390390
<listitem>
391391
<para>
392-
<application>pg_probackup</application> only supports <productname>PostgreSQL</productname> 9.5 and higher.
392+
<application>pg_probackup</application> only supports PostgreSQL 9.5 and higher.
393393
</para>
394394
</listitem>
395395
<listitem>
@@ -410,7 +410,7 @@ doc/src/sgml/pgprobackup.sgml
410410
</listitem>
411411
<listitem>
412412
<para>
413-
For PostgreSQL 9.5, functions
413+
For <productname>PostgreSQL</productname> 9.5, functions
414414
<function>pg_create_restore_point(text)</function> and
415415
<function>pg_switch_xlog()</function> can be executed only if
416416
the backup role is a superuser, so backup of a
@@ -599,7 +599,7 @@ pg_probackup add-instance -B <replaceable>backup_dir</replaceable> -D <replaceab
599599
connection</emphasis> to the <productname>PostgreSQL</productname> server:
600600
</para>
601601
<para>
602-
For PostgreSQL 9.5:
602+
For <productname>PostgreSQL</productname> 9.5:
603603
</para>
604604
<programlisting>
605605
BEGIN;
@@ -1202,8 +1202,9 @@ CREATE EXTENSION ptrack;
12021202
together, which leads to false-positive results when tracking changed
12031203
blocks and increases the incremental backup size as unchanged blocks
12041204
can also be copied into the incremental backup.
1205-
Setting <varname>ptrack.map_size</varname> to a higher value
1206-
does not affect PTRACK operation. The maximum allowed value is 1024.
1205+
Setting <varname>ptrack.map_size</varname> to a higher value does not
1206+
affect PTRACK operation, but it is not recommended to set this parameter
1207+
to a value higher than 1024.
12071208
</para>
12081209
</listitem>
12091210
</orderedlist>
@@ -1711,7 +1712,7 @@ pg_probackup restore -B <replaceable>backup_dir</replaceable> --instance <replac
17111712
<para>
17121713
The speed of restore from backup can be significantly improved
17131714
by replacing only invalid and changed pages in already
1714-
existing PostgreSQL data directory using
1715+
existing <productname>PostgreSQL</productname> data directory using
17151716
<link linkend="pbk-incremental-restore-options">incremental
17161717
restore options</link> with the <xref linkend="pbk-restore"/>
17171718
command.
@@ -1874,11 +1875,11 @@ pg_probackup restore -B <replaceable>backup_dir</replaceable> --instance <replac
18741875
</note>
18751876
<note>
18761877
<para>
1877-
Due to recovery specifics of PostgreSQL versions earlier than 12,
1878+
Due to recovery specifics of <productname>PostgreSQL</productname> versions earlier than 12,
18781879
it is advisable that you set the
18791880
<ulink url="https://postgrespro.com/docs/postgresql/current/runtime-config-replication.html#GUC-HOT-STANDBY">hot_standby</ulink>
18801881
parameter to <literal>off</literal> when running partial
1881-
restore of a PostgreSQL cluster of version earlier than 12.
1882+
restore of a <productname>PostgreSQL</productname> cluster of version earlier than 12.
18821883
Otherwise the recovery may fail.
18831884
</para>
18841885
</note>

src/backup.c

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ static void pg_stop_backup(pgBackup *backup, PGconn *pg_startbackup_conn, PGNode
5656

5757
static XLogRecPtr wait_wal_lsn(XLogRecPtr lsn, bool is_start_lsn, TimeLineID tli,
5858
bool in_prev_segment, bool segment_only,
59-
int timeout_elevel, bool in_stream_dir);
59+
int timeout_elevel, bool in_stream_dir, pgBackup *backup);
6060

6161
static void check_external_for_tablespaces(parray *external_list,
6262
PGconn *backup_conn);
@@ -165,8 +165,10 @@ do_backup_instance(PGconn *backup_conn, PGNodeInfo *nodeInfo, bool no_sync, bool
165165
"trying to look up on previous timelines",
166166
current.tli);
167167

168-
/* TODO: use read_timeline_history */
169-
tli_list = catalog_get_timelines(&instance_config);
168+
tli_list = get_history_streaming(&instance_config.conn_opt, current.tli, backup_list);
169+
if (!tli_list)
170+
/* fallback to using archive */
171+
tli_list = catalog_get_timelines(&instance_config);
170172

171173
if (parray_num(tli_list) == 0)
172174
elog(WARNING, "Cannot find valid backup on previous timelines, "
@@ -268,7 +270,7 @@ do_backup_instance(PGconn *backup_conn, PGNodeInfo *nodeInfo, bool no_sync, bool
268270
* Because WAL streaming will start after pg_start_backup() in stream
269271
* mode.
270272
*/
271-
wait_wal_lsn(current.start_lsn, true, current.tli, false, true, ERROR, false);
273+
wait_wal_lsn(current.start_lsn, true, current.tli, false, true, ERROR, false, &current);
272274
}
273275

274276
/* start stream replication */
@@ -279,6 +281,12 @@ do_backup_instance(PGconn *backup_conn, PGNodeInfo *nodeInfo, bool no_sync, bool
279281

280282
start_WAL_streaming(backup_conn, dst_backup_path, &instance_config.conn_opt,
281283
current.start_lsn, current.tli);
284+
285+
/* Make sure that WAL streaming is working
286+
* PAGE backup in stream mode is waited twice, first for
287+
* segment in WAL archive and then for streamed segment
288+
*/
289+
wait_wal_lsn(current.start_lsn, true, current.tli, false, true, ERROR, true, &current);
282290
}
283291

284292
/* initialize backup's file list */
@@ -1262,7 +1270,7 @@ pg_is_superuser(PGconn *conn)
12621270
static XLogRecPtr
12631271
wait_wal_lsn(XLogRecPtr target_lsn, bool is_start_lsn, TimeLineID tli,
12641272
bool in_prev_segment, bool segment_only,
1265-
int timeout_elevel, bool in_stream_dir)
1273+
int timeout_elevel, bool in_stream_dir, pgBackup *backup)
12661274
{
12671275
XLogSegNo targetSegNo;
12681276
char pg_wal_dir[MAXPGPATH];
@@ -1294,15 +1302,14 @@ wait_wal_lsn(XLogRecPtr target_lsn, bool is_start_lsn, TimeLineID tli,
12941302
*/
12951303
if (in_stream_dir)
12961304
{
1297-
pgBackupGetPath2(&current, pg_wal_dir, lengthof(pg_wal_dir),
1298-
DATABASE_DIR, PG_XLOG_DIR);
1305+
join_path_components(pg_wal_dir, backup->database_dir, PG_XLOG_DIR);
12991306
join_path_components(wal_segment_path, pg_wal_dir, wal_segment);
13001307
wal_segment_dir = pg_wal_dir;
13011308
}
13021309
else
13031310
{
13041311
join_path_components(wal_segment_path, arclog_path, wal_segment);
1305-
wal_segment_dir = arclog_path;
1312+
wal_segment_dir = arclog_path; /* global var */
13061313
}
13071314

13081315
/* TODO: remove this in 3.0 (it is a cludge against some old bug with archive_timeout) */
@@ -1394,7 +1401,7 @@ wait_wal_lsn(XLogRecPtr target_lsn, bool is_start_lsn, TimeLineID tli,
13941401

13951402
sleep(1);
13961403
if (interrupted)
1397-
elog(ERROR, "Interrupted during waiting for WAL archiving");
1404+
elog(ERROR, "Interrupted during waiting for WAL %s", in_stream_dir ? "streaming" : "archiving");
13981405
try_count++;
13991406

14001407
/* Inform user if WAL segment is absent in first attempt */
@@ -1418,9 +1425,10 @@ wait_wal_lsn(XLogRecPtr target_lsn, bool is_start_lsn, TimeLineID tli,
14181425
{
14191426
if (file_exists)
14201427
elog(timeout_elevel, "WAL segment %s was %s, "
1421-
"but target LSN %X/%X could not be archived in %d seconds",
1428+
"but target LSN %X/%X could not be %s in %d seconds",
14221429
wal_segment, wal_delivery_str,
1423-
(uint32) (target_lsn >> 32), (uint32) target_lsn, timeout);
1430+
(uint32) (target_lsn >> 32), (uint32) target_lsn,
1431+
wal_delivery_str, timeout);
14241432
/* If WAL segment doesn't exist or we wait for previous segment */
14251433
else
14261434
elog(timeout_elevel,
@@ -1572,8 +1580,13 @@ pg_stop_backup(pgBackup *backup, PGconn *pg_startbackup_conn,
15721580
*/
15731581
if (pg_stop_backup_is_sent && !in_cleanup)
15741582
{
1583+
int timeout = ARCHIVE_TIMEOUT_DEFAULT;
15751584
res = NULL;
15761585

1586+
/* kludge against some old bug in archive_timeout. TODO: remove in 3.0.0 */
1587+
if (instance_config.archive_timeout > 0)
1588+
timeout = instance_config.archive_timeout;
1589+
15771590
while (1)
15781591
{
15791592
if (!PQconsumeInput(conn))
@@ -1598,11 +1611,10 @@ pg_stop_backup(pgBackup *backup, PGconn *pg_startbackup_conn,
15981611
* If postgres haven't answered in archive_timeout seconds,
15991612
* send an interrupt.
16001613
*/
1601-
if (pg_stop_backup_timeout > instance_config.archive_timeout)
1614+
if (pg_stop_backup_timeout > timeout)
16021615
{
16031616
pgut_cancel(conn);
1604-
elog(ERROR, "pg_stop_backup doesn't answer in %d seconds, cancel it",
1605-
instance_config.archive_timeout);
1617+
elog(ERROR, "pg_stop_backup doesn't answer in %d seconds, cancel it", timeout);
16061618
}
16071619
}
16081620
else
@@ -1701,7 +1713,7 @@ pg_stop_backup(pgBackup *backup, PGconn *pg_startbackup_conn,
17011713
{
17021714
/* Wait for segment with current stop_lsn, it is ok for it to never arrive */
17031715
wait_wal_lsn(stop_backup_lsn_tmp, false, backup->tli,
1704-
false, true, WARNING, stream_wal);
1716+
false, true, WARNING, stream_wal, backup);
17051717

17061718
/* Get the first record in segment with current stop_lsn */
17071719
lsn_tmp = get_first_record_lsn(xlog_path, segno, backup->tli,
@@ -1729,7 +1741,7 @@ pg_stop_backup(pgBackup *backup, PGconn *pg_startbackup_conn,
17291741
* because previous record can be the contrecord.
17301742
*/
17311743
lsn_tmp = wait_wal_lsn(stop_backup_lsn_tmp, false, backup->tli,
1732-
true, false, ERROR, stream_wal);
1744+
true, false, ERROR, stream_wal, backup);
17331745

17341746
/* sanity */
17351747
if (!XRecOffIsValid(lsn_tmp) || XLogRecPtrIsInvalid(lsn_tmp))
@@ -1743,7 +1755,7 @@ pg_stop_backup(pgBackup *backup, PGconn *pg_startbackup_conn,
17431755
{
17441756
/* Wait for segment with current stop_lsn */
17451757
wait_wal_lsn(stop_backup_lsn_tmp, false, backup->tli,
1746-
false, true, ERROR, stream_wal);
1758+
false, true, ERROR, stream_wal, backup);
17471759

17481760
/* Get the next closest record in segment with current stop_lsn */
17491761
lsn_tmp = get_next_record_lsn(xlog_path, segno, backup->tli,
@@ -1872,7 +1884,7 @@ pg_stop_backup(pgBackup *backup, PGconn *pg_startbackup_conn,
18721884
*/
18731885
if (!stop_lsn_exists)
18741886
stop_backup_lsn = wait_wal_lsn(stop_backup_lsn_tmp, false, backup->tli,
1875-
false, false, ERROR, stream_wal);
1887+
false, false, ERROR, stream_wal, backup);
18761888

18771889
if (stream_wal)
18781890
{

src/catalog.c

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ typedef struct LockInfo
4848
bool exclusive;
4949
} LockInfo;
5050

51-
static timelineInfo *
51+
timelineInfo *
5252
timelineInfoNew(TimeLineID tli)
5353
{
5454
timelineInfo *tlinfo = (timelineInfo *) pgut_malloc(sizeof(timelineInfo));
@@ -74,7 +74,8 @@ timelineInfoFree(void *tliInfo)
7474

7575
if (tli->backups)
7676
{
77-
parray_walk(tli->backups, pgBackupFree);
77+
/* backups themselves should freed separately */
78+
// parray_walk(tli->backups, pgBackupFree);
7879
parray_free(tli->backups);
7980
}
8081

@@ -972,17 +973,11 @@ catalog_get_backup_list(const char *instance_name, time_t requested_backup_id)
972973
continue;
973974
}
974975
parray_append(backups, backup);
975-
976-
if (errno && errno != ENOENT)
977-
{
978-
elog(WARNING, "cannot read data directory \"%s\": %s",
979-
data_ent->d_name, strerror(errno));
980-
goto err_proc;
981-
}
982976
}
977+
983978
if (errno)
984979
{
985-
elog(WARNING, "cannot read backup root directory \"%s\": %s",
980+
elog(WARNING, "Cannot read backup root directory \"%s\": %s",
986981
backup_instance_path, strerror(errno));
987982
goto err_proc;
988983
}
@@ -2462,7 +2457,7 @@ write_backup_filelist(pgBackup *backup, parray *files, const char *root,
24622457
{
24632458
len += sprintf(line+len, ",\"n_headers\":\"%i\"", file->n_headers);
24642459
len += sprintf(line+len, ",\"hdr_crc\":\"%u\"", file->hdr_crc);
2465-
len += sprintf(line+len, ",\"hdr_off\":\"%li\"", file->hdr_off);
2460+
len += sprintf(line+len, ",\"hdr_off\":\"%llu\"", file->hdr_off);
24662461
len += sprintf(line+len, ",\"hdr_size\":\"%i\"", file->hdr_size);
24672462
}
24682463

src/configure.c

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,7 @@ do_set_config(bool missing_ok)
299299

300300
for (i = 0; instance_options[i].type; i++)
301301
{
302+
int rc = 0;
302303
ConfigOption *opt = &instance_options[i];
303304
char *value;
304305

@@ -319,13 +320,25 @@ do_set_config(bool missing_ok)
319320
}
320321

321322
if (strchr(value, ' '))
322-
fprintf(fp, "%s = '%s'\n", opt->lname, value);
323+
rc = fprintf(fp, "%s = '%s'\n", opt->lname, value);
323324
else
324-
fprintf(fp, "%s = %s\n", opt->lname, value);
325+
rc = fprintf(fp, "%s = %s\n", opt->lname, value);
326+
327+
if (rc < 0)
328+
elog(ERROR, "Cannot write to configuration file: \"%s\"", path_temp);
329+
325330
pfree(value);
326331
}
327332

328-
fclose(fp);
333+
if (ferror(fp) || fflush(fp))
334+
elog(ERROR, "Cannot write to configuration file: \"%s\"", path_temp);
335+
336+
if (fclose(fp))
337+
elog(ERROR, "Cannot close configuration file: \"%s\"", path_temp);
338+
339+
if (fio_sync(path_temp, FIO_LOCAL_HOST) != 0)
340+
elog(ERROR, "Failed to sync temp configuration file \"%s\": %s",
341+
path_temp, strerror(errno));
329342

330343
if (rename(path_temp, path) < 0)
331344
{

src/data.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2160,7 +2160,7 @@ get_data_file_headers(HeaderMap *hdr_map, pgFile *file, uint32 backup_version, b
21602160

21612161
if (fseek(in, file->hdr_off, SEEK_SET))
21622162
{
2163-
elog(strict ? ERROR : WARNING, "Cannot seek to position %lu in page header map \"%s\": %s",
2163+
elog(strict ? ERROR : WARNING, "Cannot seek to position %llu in page header map \"%s\": %s",
21642164
file->hdr_off, hdr_map->path, strerror(errno));
21652165
goto cleanup;
21662166
}
@@ -2177,7 +2177,7 @@ get_data_file_headers(HeaderMap *hdr_map, pgFile *file, uint32 backup_version, b
21772177

21782178
if (fread(zheaders, 1, file->hdr_size, in) != file->hdr_size)
21792179
{
2180-
elog(strict ? ERROR : WARNING, "Cannot read header file at offset: %li len: %i \"%s\": %s",
2180+
elog(strict ? ERROR : WARNING, "Cannot read header file at offset: %llu len: %i \"%s\": %s",
21812181
file->hdr_off, file->hdr_size, hdr_map->path, strerror(errno));
21822182
goto cleanup;
21832183
}
@@ -2208,7 +2208,7 @@ get_data_file_headers(HeaderMap *hdr_map, pgFile *file, uint32 backup_version, b
22082208
if (hdr_crc != file->hdr_crc)
22092209
{
22102210
elog(strict ? ERROR : WARNING, "Header map for file \"%s\" crc mismatch \"%s\" "
2211-
"offset: %lu, len: %lu, current: %u, expected: %u",
2211+
"offset: %llu, len: %lu, current: %u, expected: %u",
22122212
file->rel_path, hdr_map->path, file->hdr_off, read_len, hdr_crc, file->hdr_crc);
22132213
goto cleanup;
22142214
}
@@ -2268,7 +2268,7 @@ write_page_headers(BackupPageHeader2 *headers, pgFile *file, HeaderMap *hdr_map,
22682268
{
22692269
elog(LOG, "Creating page header map \"%s\"", map_path);
22702270

2271-
hdr_map->fp = fopen(map_path, PG_BINARY_W);
2271+
hdr_map->fp = fopen(map_path, "a");
22722272
if (hdr_map->fp == NULL)
22732273
elog(ERROR, "Cannot open header file \"%s\": %s",
22742274
map_path, strerror(errno));
@@ -2297,7 +2297,7 @@ write_page_headers(BackupPageHeader2 *headers, pgFile *file, HeaderMap *hdr_map,
22972297
file->rel_path, z_len);
22982298
}
22992299

2300-
elog(VERBOSE, "Writing headers for file \"%s\" offset: %li, len: %i, crc: %u",
2300+
elog(VERBOSE, "Writing headers for file \"%s\" offset: %llu, len: %i, crc: %u",
23012301
file->rel_path, file->hdr_off, z_len, file->hdr_crc);
23022302

23032303
if (fwrite(zheaders, 1, z_len, hdr_map->fp) != z_len)

0 commit comments

Comments
 (0)