When start_segno matched current segno we pretend to start from start_lsn.
But due to copy-paste mistake we started from segment start.
This was catch by introduced special (almost redundant) check.
This check were introduced to match behaviour previously provided by
XLogBeginRead + WalRecordRead. It doesn't provide much value, but lets
keep it.
It was long believed `stop_lsn` should point on start of last record.
But in fact it points to end of last record (because XLogInsert(BACKUP_END)
returns pointer to end of record, and that is what pg_backup_stop/
pg_stop_backup returns).
So we don't need to lookup `stop_lsn` record in WAL log, but rather check
existence of record which ends on `stop_lsn` (which is what
`get_prior_record_lsn` does).
And there is no need to raise error on `stop_lsn` which points on block end
- it is very valid when xlog record ends at block end.
So:
- we simplify wait_wal_lsn to just wait for `get_prior_record_lsn` returns
"ok" (ie find such previous record). But now we don't overwrite stop_lsn
with lsn of this record.
- we use `wait_wal_lsn` only in "ARCHIVE" mode/directory.
So get rid of `in_stream_dir` argument.
- and `wait_wal_lsn` now waits only for previous record even for
`is_start_lsn`, since there is no much gain in waiting for it.
Even for PAGE mode we need only records before `start_lsn`, since
`start_lsn` record is considered as part of backup.
- "STREAM" mode now waits for lsn by hooking streamer. We don't need to
calculate stop_backup_lsn since we may use stop_backup_result.lsn
directly to stop streamer.
After streamer stopped, we just check wal with `get_prior_record_lsn`. We
don't need to, but just for sanity.
- therefore `wait_wal_and_calculate_stop_lsn` become obsolete. Lets get rid
of it.
Without it, there is no need in get_first_record_lsn and
get_next_record_lsn. Lets delete them too.
- Instead of using XRecOffIsValid and XRecOffIsNull use added
XRecPtrLooksGood and XRecEndLooksGood.
XRecPtrLooksGood validates record start more rigidly than XRecOffIsValid,
and XRecEndLooksGood validates record end, which could be on block end.
- In fact, some of `XRecOffIsValid(x)` had to be `!XLogRecPtrIsInvalid(x)`
- Since stop_lsn is not inclusive now, RunXLogThreads doesn't need
`inclusive_endpoint` parameter.
(And because Page mode needs just till start_lsn)
- PAGE_LSN_FROM_FUTURE must be considered as error, btw.
(And by the way there's no need to XLogBeginRead before XLogFindNextRecord.
Cleanup such calls)
since it uses XLogFindNextRecord, it could use stop_lsn with no valid
offset. In fact, it uses truncated stop_lsn with invalid offset always.
Also fix getting timestamp from possible record in a future.
We could not to not enter the loop since we need record->xl_prev to
correctly walk backward. So we need to add condition before
getRecordTimestamp.
We have streamer in our hand, so we may ask it directly, what are it
streaming now.
But in case we looks into previous segment, we fallback to log reading
since it is already flushed.
Well, we couldn't easily step back be 1MB, since it could be in
uninitialized tail of previous segment.
We need to use valid pointer in record->xl_prev.
xlogFile did contain pgFile in its start. Therefore pgFileFree were used
to free it.
Not xlogFile doesn't contain pgFile, so its free procedure should be fixed.
We want to sort files be offset in page header map file.
But it breaks searching with binary search by filename.
Therefore make and use hashtable instead of binary search.