1
0
mirror of https://github.com/postgrespro/pg_probackup.git synced 2025-01-09 14:45:47 +02:00

[Issue #136] fix incorrect XlogSegNo calculation in catalog_get_timelines()

This commit is contained in:
Grigory Smolkin 2019-10-22 21:16:49 +03:00
parent 6cbea998cc
commit ef20e82a6f
4 changed files with 70 additions and 48 deletions

View File

@ -695,6 +695,10 @@ catalog_get_timelines(InstanceConfig *instance)
timelineInfo *tlinfo;
char arclog_path[MAXPGPATH];
/* for fancy reporting */
char begin_segno_str[20];
char end_segno_str[20];
/* read all xlog files that belong to this archive */
sprintf(arclog_path, "%s/%s/%s", backup_path, "wal", instance->name);
dir_list_file(xlog_files_list, arclog_path, false, false, false, 0, FIO_BACKUP_HOST);
@ -716,19 +720,21 @@ catalog_get_timelines(InstanceConfig *instance)
{
int result = 0;
uint32 log, seg;
XLogSegNo segno;
char suffix[MAXPGPATH];
XLogSegNo segno = 0;
char suffix[MAXFNAMELEN];
result = sscanf(file->name, "%08X%08X%08X.%s",
&tli, &log, &seg, (char *) &suffix);
/* sanity */
if (result < 3)
{
elog(WARNING, "unexpected WAL file name \"%s\"", file->name);
continue;
}
segno = log * instance->xlog_seg_size + seg;
/* get segno from log */
GetXLogSegNoFromScrath(segno, log, seg, instance->xlog_seg_size);
/* regular WAL file with suffix */
if (result == 4)
@ -1112,15 +1118,15 @@ catalog_get_timelines(InstanceConfig *instance)
* covered by other larger interval.
*/
GetXLogSegName(begin_segno_str, interval->begin_segno, instance->xlog_seg_size);
GetXLogSegName(end_segno_str, interval->end_segno, instance->xlog_seg_size);
elog(LOG, "Timeline %i to stay reachable from timeline %i "
"protect from purge WAL interval between "
"%08X%08X and %08X%08X on timeline %i",
tli, closest_backup->tli,
(uint32) interval->begin_segno / instance->xlog_seg_size,
(uint32) interval->begin_segno % instance->xlog_seg_size,
(uint32) interval->end_segno / instance->xlog_seg_size,
(uint32) interval->end_segno % instance->xlog_seg_size,
tlinfo->tli);
"%s and %s on timeline %i",
tli, closest_backup->tli, begin_segno_str,
end_segno_str, tlinfo->tli);
parray_append(tlinfo->keep_segments, interval);
continue;
}
@ -1167,15 +1173,14 @@ catalog_get_timelines(InstanceConfig *instance)
else
interval->end_segno = segno;
GetXLogSegName(begin_segno_str, interval->begin_segno, instance->xlog_seg_size);
GetXLogSegName(end_segno_str, interval->end_segno, instance->xlog_seg_size);
elog(LOG, "Archive backup %s to stay consistent "
"protect from purge WAL interval "
"between %08X%08X and %08X%08X on timeline %i",
"between %s and %s on timeline %i",
base36enc(backup->start_time),
(uint32) interval->begin_segno / instance->xlog_seg_size,
(uint32) interval->begin_segno % instance->xlog_seg_size,
(uint32) interval->end_segno / instance->xlog_seg_size,
(uint32) interval->end_segno % instance->xlog_seg_size,
backup->tli);
begin_segno_str, end_segno_str, backup->tli);
if (tlinfo->keep_segments == NULL)
tlinfo->keep_segments = parray_new();

View File

@ -810,6 +810,8 @@ delete_walfiles_in_tli(XLogRecPtr keep_lsn, timelineInfo *tlinfo,
{
XLogSegNo FirstToDeleteSegNo;
XLogSegNo OldestToKeepSegNo = 0;
char first_to_del_str[20];
char oldest_to_keep_str[20];
int rc;
int i;
int wal_size_logical = 0;
@ -842,13 +844,15 @@ delete_walfiles_in_tli(XLogRecPtr keep_lsn, timelineInfo *tlinfo,
}
if (OldestToKeepSegNo > 0 && OldestToKeepSegNo > FirstToDeleteSegNo)
elog(INFO, "On timeline %i WAL segments between %08X%08X and %08X%08X %s be removed",
tlinfo->tli,
(uint32) FirstToDeleteSegNo / xlog_seg_size,
(uint32) FirstToDeleteSegNo % xlog_seg_size,
(uint32) (OldestToKeepSegNo - 1) / xlog_seg_size,
(uint32) (OldestToKeepSegNo - 1) % xlog_seg_size,
dry_run?"can":"will");
{
/* translate segno number into human readable format */
GetXLogSegName(first_to_del_str, FirstToDeleteSegNo, xlog_seg_size);
GetXLogSegName(oldest_to_keep_str, OldestToKeepSegNo, xlog_seg_size);
elog(INFO, "On timeline %i WAL segments between %s and %s %s be removed",
tlinfo->tli, first_to_del_str,
oldest_to_keep_str, dry_run?"can":"will");
}
/* sanity */
if (OldestToKeepSegNo > FirstToDeleteSegNo)
@ -866,15 +870,16 @@ delete_walfiles_in_tli(XLogRecPtr keep_lsn, timelineInfo *tlinfo,
* 1. WAL archive corruption.
* 2. There is no actual WAL archive to speak of and
* 'keep_lsn' is coming from STREAM backup.
*
* Assume the worst.
*/
if (FirstToDeleteSegNo > 0 && OldestToKeepSegNo > 0)
elog(LOG, "On timeline %i first segment %08X%08X is greater than "
"oldest segment to keep %08X%08X",
tlinfo->tli,
(uint32) FirstToDeleteSegNo / xlog_seg_size, (uint32) FirstToDeleteSegNo % xlog_seg_size,
(uint32) OldestToKeepSegNo / xlog_seg_size, (uint32) OldestToKeepSegNo % xlog_seg_size);
{
GetXLogSegName(first_to_del_str, FirstToDeleteSegNo, xlog_seg_size);
GetXLogSegName(oldest_to_keep_str, OldestToKeepSegNo, xlog_seg_size);
elog(LOG, "On timeline %i first segment %s is greater than oldest segment to keep %s",
tlinfo->tli, first_to_del_str, oldest_to_keep_str);
}
}
else if (OldestToKeepSegNo == FirstToDeleteSegNo && !purge_all)
{

View File

@ -526,6 +526,13 @@ typedef struct BackupPageHeader
XLogFileName(fname, tli, logSegNo, wal_segsz_bytes)
#define IsInXLogSeg(xlrp, logSegNo, wal_segsz_bytes) \
XLByteInSeg(xlrp, logSegNo, wal_segsz_bytes)
#define GetXLogSegName(fname, logSegNo, wal_segsz_bytes) \
snprintf(fname, MAXFNAMELEN, "%08X%08X", \
(uint32) ((logSegNo) / XLogSegmentsPerXLogId(wal_segsz_bytes)), \
(uint32) ((logSegNo) % XLogSegmentsPerXLogId(wal_segsz_bytes)))
#define GetXLogSegNoFromScrath(logSegNo, log, seg, wal_segsz_bytes) \
logSegNo = (uint64) log * XLogSegmentsPerXLogId(wal_segsz_bytes) + seg
#else
#define GetXLogSegNo(xlrp, logSegNo, wal_segsz_bytes) \
XLByteToSeg(xlrp, logSegNo)
@ -535,6 +542,13 @@ typedef struct BackupPageHeader
XLogFileName(fname, tli, logSegNo)
#define IsInXLogSeg(xlrp, logSegNo, wal_segsz_bytes) \
XLByteInSeg(xlrp, logSegNo)
#define GetXLogSegName(fname, logSegNo, wal_segsz_bytes) \
snprintf(fname, MAXFNAMELEN, "%08X%08X",\
(uint32) ((logSegNo) / XLogSegmentsPerXLogId), \
(uint32) ((logSegNo) % XLogSegmentsPerXLogId))
#define GetXLogSegNoFromScrath(logSegNo, log, seg, wal_segsz_bytes) \
logSegNo = (uint64) log * XLogSegmentsPerXLogId + seg
#endif
#define IsSshProtocol() (instance_config.remote.host && strcmp(instance_config.remote.proto, "ssh") == 0)

View File

@ -749,6 +749,7 @@ static void
show_archive_plain(const char *instance_name, uint32 xlog_seg_size,
parray *tli_list, bool show_name)
{
char segno_tmp[20];
parray *actual_tli_list = parray_new();
#define SHOW_ARCHIVE_FIELDS_COUNT 10
int i;
@ -807,16 +808,16 @@ show_archive_plain(const char *instance_name, uint32 xlog_seg_size,
cur++;
/* Min Segno */
snprintf(row->min_segno, lengthof(row->min_segno), "%08X%08X",
(uint32) tlinfo->begin_segno / xlog_seg_size,
(uint32) tlinfo->begin_segno % xlog_seg_size);
GetXLogSegName(segno_tmp, tlinfo->begin_segno, xlog_seg_size);
snprintf(row->min_segno, lengthof(row->min_segno), "%s",segno_tmp);
widths[cur] = Max(widths[cur], strlen(row->min_segno));
cur++;
/* Max Segno */
snprintf(row->max_segno, lengthof(row->max_segno), "%08X%08X",
(uint32) tlinfo->end_segno / xlog_seg_size,
(uint32) tlinfo->end_segno % xlog_seg_size);
GetXLogSegName(segno_tmp, tlinfo->end_segno, xlog_seg_size);
snprintf(row->max_segno, lengthof(row->max_segno), "%s", segno_tmp);
widths[cur] = Max(widths[cur], strlen(row->max_segno));
cur++;
@ -939,6 +940,7 @@ show_archive_json(const char *instance_name, uint32 xlog_seg_size,
int i,j;
PQExpBuffer buf = &show_buf;
parray *actual_tli_list = parray_new();
char segno_tmp[20];
if (!first_instance)
appendPQExpBufferChar(buf, ',');
@ -985,14 +987,12 @@ show_archive_json(const char *instance_name, uint32 xlog_seg_size,
(uint32) (tlinfo->switchpoint >> 32), (uint32) tlinfo->switchpoint);
json_add_value(buf, "switchpoint", tmp_buf, json_level, true);
snprintf(tmp_buf, lengthof(tmp_buf), "%08X%08X",
(uint32) tlinfo->begin_segno / xlog_seg_size,
(uint32) tlinfo->begin_segno % xlog_seg_size);
GetXLogSegName(segno_tmp, tlinfo->begin_segno, xlog_seg_size);
snprintf(tmp_buf, lengthof(tmp_buf), "%s", segno_tmp);
json_add_value(buf, "min-segno", tmp_buf, json_level, true);
snprintf(tmp_buf, lengthof(tmp_buf), "%08X%08X",
(uint32) tlinfo->end_segno / xlog_seg_size,
(uint32) tlinfo->end_segno % xlog_seg_size);
GetXLogSegName(segno_tmp, tlinfo->end_segno, xlog_seg_size);
snprintf(tmp_buf, lengthof(tmp_buf), "%s", segno_tmp);
json_add_value(buf, "max-segno", tmp_buf, json_level, true);
json_add_key(buf, "n-segments", json_level);
@ -1034,14 +1034,12 @@ show_archive_json(const char *instance_name, uint32 xlog_seg_size,
json_add(buf, JT_BEGIN_OBJECT, &json_level);
snprintf(tmp_buf, lengthof(tmp_buf), "%08X%08X",
(uint32) lost_segments->begin_segno / xlog_seg_size,
(uint32) lost_segments->begin_segno % xlog_seg_size);
GetXLogSegName(segno_tmp, lost_segments->begin_segno, xlog_seg_size);
snprintf(tmp_buf, lengthof(tmp_buf), "%s", segno_tmp);
json_add_value(buf, "begin-segno", tmp_buf, json_level, true);
snprintf(tmp_buf, lengthof(tmp_buf), "%08X%08X",
(uint32) lost_segments->end_segno / xlog_seg_size,
(uint32) lost_segments->end_segno % xlog_seg_size);
GetXLogSegName(segno_tmp, lost_segments->end_segno, xlog_seg_size);
snprintf(tmp_buf, lengthof(tmp_buf), "%s", segno_tmp);
json_add_value(buf, "end-segno", tmp_buf, json_level, true);
json_add(buf, JT_END_OBJECT, &json_level);
}