Skip to content

Commit ef20e82

Browse files
committed
[Issue #136] fix incorrect XlogSegNo calculation in catalog_get_timelines()
1 parent 6cbea99 commit ef20e82

File tree

4 files changed

+70
-48
lines changed

4 files changed

+70
-48
lines changed

src/catalog.c

+21-16
Original file line numberDiff line numberDiff line change
@@ -695,6 +695,10 @@ catalog_get_timelines(InstanceConfig *instance)
695695
timelineInfo *tlinfo;
696696
char arclog_path[MAXPGPATH];
697697

698+
/* for fancy reporting */
699+
char begin_segno_str[20];
700+
char end_segno_str[20];
701+
698702
/* read all xlog files that belong to this archive */
699703
sprintf(arclog_path, "%s/%s/%s", backup_path, "wal", instance->name);
700704
dir_list_file(xlog_files_list, arclog_path, false, false, false, 0, FIO_BACKUP_HOST);
@@ -716,19 +720,21 @@ catalog_get_timelines(InstanceConfig *instance)
716720
{
717721
int result = 0;
718722
uint32 log, seg;
719-
XLogSegNo segno;
720-
char suffix[MAXPGPATH];
723+
XLogSegNo segno = 0;
724+
char suffix[MAXFNAMELEN];
721725

722726
result = sscanf(file->name, "%08X%08X%08X.%s",
723727
&tli, &log, &seg, (char *) &suffix);
724728

729+
/* sanity */
725730
if (result < 3)
726731
{
727732
elog(WARNING, "unexpected WAL file name \"%s\"", file->name);
728733
continue;
729734
}
730735

731-
segno = log * instance->xlog_seg_size + seg;
736+
/* get segno from log */
737+
GetXLogSegNoFromScrath(segno, log, seg, instance->xlog_seg_size);
732738

733739
/* regular WAL file with suffix */
734740
if (result == 4)
@@ -1112,15 +1118,15 @@ catalog_get_timelines(InstanceConfig *instance)
11121118
* covered by other larger interval.
11131119
*/
11141120

1121+
GetXLogSegName(begin_segno_str, interval->begin_segno, instance->xlog_seg_size);
1122+
GetXLogSegName(end_segno_str, interval->end_segno, instance->xlog_seg_size);
1123+
11151124
elog(LOG, "Timeline %i to stay reachable from timeline %i "
11161125
"protect from purge WAL interval between "
1117-
"%08X%08X and %08X%08X on timeline %i",
1118-
tli, closest_backup->tli,
1119-
(uint32) interval->begin_segno / instance->xlog_seg_size,
1120-
(uint32) interval->begin_segno % instance->xlog_seg_size,
1121-
(uint32) interval->end_segno / instance->xlog_seg_size,
1122-
(uint32) interval->end_segno % instance->xlog_seg_size,
1123-
tlinfo->tli);
1126+
"%s and %s on timeline %i",
1127+
tli, closest_backup->tli, begin_segno_str,
1128+
end_segno_str, tlinfo->tli);
1129+
11241130
parray_append(tlinfo->keep_segments, interval);
11251131
continue;
11261132
}
@@ -1167,15 +1173,14 @@ catalog_get_timelines(InstanceConfig *instance)
11671173
else
11681174
interval->end_segno = segno;
11691175

1176+
GetXLogSegName(begin_segno_str, interval->begin_segno, instance->xlog_seg_size);
1177+
GetXLogSegName(end_segno_str, interval->end_segno, instance->xlog_seg_size);
1178+
11701179
elog(LOG, "Archive backup %s to stay consistent "
11711180
"protect from purge WAL interval "
1172-
"between %08X%08X and %08X%08X on timeline %i",
1181+
"between %s and %s on timeline %i",
11731182
base36enc(backup->start_time),
1174-
(uint32) interval->begin_segno / instance->xlog_seg_size,
1175-
(uint32) interval->begin_segno % instance->xlog_seg_size,
1176-
(uint32) interval->end_segno / instance->xlog_seg_size,
1177-
(uint32) interval->end_segno % instance->xlog_seg_size,
1178-
backup->tli);
1183+
begin_segno_str, end_segno_str, backup->tli);
11791184

11801185
if (tlinfo->keep_segments == NULL)
11811186
tlinfo->keep_segments = parray_new();

src/delete.c

+19-14
Original file line numberDiff line numberDiff line change
@@ -810,6 +810,8 @@ delete_walfiles_in_tli(XLogRecPtr keep_lsn, timelineInfo *tlinfo,
810810
{
811811
XLogSegNo FirstToDeleteSegNo;
812812
XLogSegNo OldestToKeepSegNo = 0;
813+
char first_to_del_str[20];
814+
char oldest_to_keep_str[20];
813815
int rc;
814816
int i;
815817
int wal_size_logical = 0;
@@ -842,13 +844,15 @@ delete_walfiles_in_tli(XLogRecPtr keep_lsn, timelineInfo *tlinfo,
842844
}
843845

844846
if (OldestToKeepSegNo > 0 && OldestToKeepSegNo > FirstToDeleteSegNo)
845-
elog(INFO, "On timeline %i WAL segments between %08X%08X and %08X%08X %s be removed",
846-
tlinfo->tli,
847-
(uint32) FirstToDeleteSegNo / xlog_seg_size,
848-
(uint32) FirstToDeleteSegNo % xlog_seg_size,
849-
(uint32) (OldestToKeepSegNo - 1) / xlog_seg_size,
850-
(uint32) (OldestToKeepSegNo - 1) % xlog_seg_size,
851-
dry_run?"can":"will");
847+
{
848+
/* translate segno number into human readable format */
849+
GetXLogSegName(first_to_del_str, FirstToDeleteSegNo, xlog_seg_size);
850+
GetXLogSegName(oldest_to_keep_str, OldestToKeepSegNo, xlog_seg_size);
851+
852+
elog(INFO, "On timeline %i WAL segments between %s and %s %s be removed",
853+
tlinfo->tli, first_to_del_str,
854+
oldest_to_keep_str, dry_run?"can":"will");
855+
}
852856

853857
/* sanity */
854858
if (OldestToKeepSegNo > FirstToDeleteSegNo)
@@ -866,15 +870,16 @@ delete_walfiles_in_tli(XLogRecPtr keep_lsn, timelineInfo *tlinfo,
866870
* 1. WAL archive corruption.
867871
* 2. There is no actual WAL archive to speak of and
868872
* 'keep_lsn' is coming from STREAM backup.
869-
*
870-
* Assume the worst.
871873
*/
874+
872875
if (FirstToDeleteSegNo > 0 && OldestToKeepSegNo > 0)
873-
elog(LOG, "On timeline %i first segment %08X%08X is greater than "
874-
"oldest segment to keep %08X%08X",
875-
tlinfo->tli,
876-
(uint32) FirstToDeleteSegNo / xlog_seg_size, (uint32) FirstToDeleteSegNo % xlog_seg_size,
877-
(uint32) OldestToKeepSegNo / xlog_seg_size, (uint32) OldestToKeepSegNo % xlog_seg_size);
876+
{
877+
GetXLogSegName(first_to_del_str, FirstToDeleteSegNo, xlog_seg_size);
878+
GetXLogSegName(oldest_to_keep_str, OldestToKeepSegNo, xlog_seg_size);
879+
880+
elog(LOG, "On timeline %i first segment %s is greater than oldest segment to keep %s",
881+
tlinfo->tli, first_to_del_str, oldest_to_keep_str);
882+
}
878883
}
879884
else if (OldestToKeepSegNo == FirstToDeleteSegNo && !purge_all)
880885
{

src/pg_probackup.h

+14
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,13 @@ typedef struct BackupPageHeader
526526
XLogFileName(fname, tli, logSegNo, wal_segsz_bytes)
527527
#define IsInXLogSeg(xlrp, logSegNo, wal_segsz_bytes) \
528528
XLByteInSeg(xlrp, logSegNo, wal_segsz_bytes)
529+
#define GetXLogSegName(fname, logSegNo, wal_segsz_bytes) \
530+
snprintf(fname, MAXFNAMELEN, "%08X%08X", \
531+
(uint32) ((logSegNo) / XLogSegmentsPerXLogId(wal_segsz_bytes)), \
532+
(uint32) ((logSegNo) % XLogSegmentsPerXLogId(wal_segsz_bytes)))
533+
534+
#define GetXLogSegNoFromScrath(logSegNo, log, seg, wal_segsz_bytes) \
535+
logSegNo = (uint64) log * XLogSegmentsPerXLogId(wal_segsz_bytes) + seg
529536
#else
530537
#define GetXLogSegNo(xlrp, logSegNo, wal_segsz_bytes) \
531538
XLByteToSeg(xlrp, logSegNo)
@@ -535,6 +542,13 @@ typedef struct BackupPageHeader
535542
XLogFileName(fname, tli, logSegNo)
536543
#define IsInXLogSeg(xlrp, logSegNo, wal_segsz_bytes) \
537544
XLByteInSeg(xlrp, logSegNo)
545+
#define GetXLogSegName(fname, logSegNo, wal_segsz_bytes) \
546+
snprintf(fname, MAXFNAMELEN, "%08X%08X",\
547+
(uint32) ((logSegNo) / XLogSegmentsPerXLogId), \
548+
(uint32) ((logSegNo) % XLogSegmentsPerXLogId))
549+
550+
#define GetXLogSegNoFromScrath(logSegNo, log, seg, wal_segsz_bytes) \
551+
logSegNo = (uint64) log * XLogSegmentsPerXLogId + seg
538552
#endif
539553

540554
#define IsSshProtocol() (instance_config.remote.host && strcmp(instance_config.remote.proto, "ssh") == 0)

src/show.c

+16-18
Original file line numberDiff line numberDiff line change
@@ -749,6 +749,7 @@ static void
749749
show_archive_plain(const char *instance_name, uint32 xlog_seg_size,
750750
parray *tli_list, bool show_name)
751751
{
752+
char segno_tmp[20];
752753
parray *actual_tli_list = parray_new();
753754
#define SHOW_ARCHIVE_FIELDS_COUNT 10
754755
int i;
@@ -807,16 +808,16 @@ show_archive_plain(const char *instance_name, uint32 xlog_seg_size,
807808
cur++;
808809

809810
/* Min Segno */
810-
snprintf(row->min_segno, lengthof(row->min_segno), "%08X%08X",
811-
(uint32) tlinfo->begin_segno / xlog_seg_size,
812-
(uint32) tlinfo->begin_segno % xlog_seg_size);
811+
GetXLogSegName(segno_tmp, tlinfo->begin_segno, xlog_seg_size);
812+
snprintf(row->min_segno, lengthof(row->min_segno), "%s",segno_tmp);
813+
813814
widths[cur] = Max(widths[cur], strlen(row->min_segno));
814815
cur++;
815816

816817
/* Max Segno */
817-
snprintf(row->max_segno, lengthof(row->max_segno), "%08X%08X",
818-
(uint32) tlinfo->end_segno / xlog_seg_size,
819-
(uint32) tlinfo->end_segno % xlog_seg_size);
818+
GetXLogSegName(segno_tmp, tlinfo->end_segno, xlog_seg_size);
819+
snprintf(row->max_segno, lengthof(row->max_segno), "%s", segno_tmp);
820+
820821
widths[cur] = Max(widths[cur], strlen(row->max_segno));
821822
cur++;
822823

@@ -939,6 +940,7 @@ show_archive_json(const char *instance_name, uint32 xlog_seg_size,
939940
int i,j;
940941
PQExpBuffer buf = &show_buf;
941942
parray *actual_tli_list = parray_new();
943+
char segno_tmp[20];
942944

943945
if (!first_instance)
944946
appendPQExpBufferChar(buf, ',');
@@ -985,14 +987,12 @@ show_archive_json(const char *instance_name, uint32 xlog_seg_size,
985987
(uint32) (tlinfo->switchpoint >> 32), (uint32) tlinfo->switchpoint);
986988
json_add_value(buf, "switchpoint", tmp_buf, json_level, true);
987989

988-
snprintf(tmp_buf, lengthof(tmp_buf), "%08X%08X",
989-
(uint32) tlinfo->begin_segno / xlog_seg_size,
990-
(uint32) tlinfo->begin_segno % xlog_seg_size);
990+
GetXLogSegName(segno_tmp, tlinfo->begin_segno, xlog_seg_size);
991+
snprintf(tmp_buf, lengthof(tmp_buf), "%s", segno_tmp);
991992
json_add_value(buf, "min-segno", tmp_buf, json_level, true);
992993

993-
snprintf(tmp_buf, lengthof(tmp_buf), "%08X%08X",
994-
(uint32) tlinfo->end_segno / xlog_seg_size,
995-
(uint32) tlinfo->end_segno % xlog_seg_size);
994+
GetXLogSegName(segno_tmp, tlinfo->end_segno, xlog_seg_size);
995+
snprintf(tmp_buf, lengthof(tmp_buf), "%s", segno_tmp);
996996
json_add_value(buf, "max-segno", tmp_buf, json_level, true);
997997

998998
json_add_key(buf, "n-segments", json_level);
@@ -1034,14 +1034,12 @@ show_archive_json(const char *instance_name, uint32 xlog_seg_size,
10341034

10351035
json_add(buf, JT_BEGIN_OBJECT, &json_level);
10361036

1037-
snprintf(tmp_buf, lengthof(tmp_buf), "%08X%08X",
1038-
(uint32) lost_segments->begin_segno / xlog_seg_size,
1039-
(uint32) lost_segments->begin_segno % xlog_seg_size);
1037+
GetXLogSegName(segno_tmp, lost_segments->begin_segno, xlog_seg_size);
1038+
snprintf(tmp_buf, lengthof(tmp_buf), "%s", segno_tmp);
10401039
json_add_value(buf, "begin-segno", tmp_buf, json_level, true);
10411040

1042-
snprintf(tmp_buf, lengthof(tmp_buf), "%08X%08X",
1043-
(uint32) lost_segments->end_segno / xlog_seg_size,
1044-
(uint32) lost_segments->end_segno % xlog_seg_size);
1041+
GetXLogSegName(segno_tmp, lost_segments->end_segno, xlog_seg_size);
1042+
snprintf(tmp_buf, lengthof(tmp_buf), "%s", segno_tmp);
10451043
json_add_value(buf, "end-segno", tmp_buf, json_level, true);
10461044
json_add(buf, JT_END_OBJECT, &json_level);
10471045
}

0 commit comments

Comments
 (0)