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:
parent
6cbea998cc
commit
ef20e82a6f
@ -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();
|
||||
|
33
src/delete.c
33
src/delete.c
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
|
34
src/show.c
34
src/show.c
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user