74.3 Recovery Scan
Purpose
Opening a partition begins from its most recent valid checkpoint. The checkpoint identifies the recoverable SUT, SpaceDirectory and log position. The recovery scan follows the partition's LFUs from that position and reconstructs every committed change made after the checkpoint.
Each LFU is validated before its records are interpreted. Its checksum, checkpoint identity, PartitionId, sequence information, payload size and next-segment link must be consistent with the partition being recovered. The records within a valid LFU are then parsed according to the formats defined in the Log Records chapter.
Transaction boundaries
Records belonging to a mutative transaction are provisional until the recovery scan reaches that transaction's Snapshot record. At that point the records are applied as one committed transaction and the recovered partition state advances to the Snapshot's transaction sequence number and time.
A final partial transaction with no complete valid Snapshot record is not processed. Its records are ignored rather than treated as committed changes. Consequently, an invalid operation in that uncommitted tail does not by itself make the LSS corrupt; the operation has no effect on the recovered state.
Replaying packet records
An ordinary data-packet type describes a logical insertion or replacement and is replayed according
to that type. A RelocatedHeadDataPacket or
RelocatedOverflowDataPacket,
including either one's WithNext form, describes only physical
relocation of the already-live data packet having that record's identity. A
SpaceRpmNode,
SpaceDirectoryRpmNode or
Space encountered in the post-checkpoint recovery log likewise
represents relocation: their checkpoint-written forms are not part of that recovery-log sequence.
Recovery must not interpret a relocation record as a second insertion, recreate a serial element,
advance allocation state or expose a logical change.
Relocation records written by the cleaner are retained with the other provisional records until their
Snapshot is reached. They are then processed in log order. For each record, recovery obtains the old
LogRecordPosition from the mapping selected by its stable identity,
changes that mapping to the relocation record's own position, adds the encoded record size to the
destination segment's utilisation, and subtracts the same size from the source segment's
utilisation. The mapping is changed before the source utilisation is reduced. A later record in the
same or a later committed transaction sees the relocated position.
| Relocation record | Mapping used to find and replace its old position |
|---|---|
| Relocated head or overflow data packet | The identified Space RPM leaf entry |
SpaceRpmNode | Its parent entry, or the owning Space's current root state |
Space | The SpaceDirectory RPM leaf entry |
SpaceDirectoryRpmNode | Its parent entry, or the partition's current directory-root state |
Updating an RPM-node or Space-packet position marks its ancestor path dirty but does not cause those ancestors to be written during recovery. The normal checkpoint procedure later writes dirty RPM nodes bottom-up, writes dirty Space packets, and finally publishes the new SpaceDirectory root.
If the scan ends before a complete Snapshot, all relocation records in that final transaction are ignored. The checkpoint mappings therefore continue to name the old copies. Segments placed in the delta-FSS since the checkpoint have not yet entered the reusable FSS, so those old copies have not been overwritten. Conversely, after a cleaning transaction's Snapshot, replay of all its cleaning records must once again reduce every completely cleaned source segment to zero utilisation.
Under the trusted-writer model, optimized builds need not perform redundant structural validation at each update. Checksums, record bounds and memory-safety preconditions are always checked. Heavyweight validation may additionally confirm that every cleaning identity is live and maps to the expected source segment. If an implemented check discovers an impossible committed transition, it is not silently skipped or reinterpreted: recovery fails and the LSS enters the zombie state.
Recovering Seid allocation
For each ordinary head or overflow data-packet record, recovery advances the identified Space's
nextSeid to at least one greater than the packet's Seid. This
recovers allocation in the usual case where Seids are allocated and written in the same transaction.
Relocated data-packet records do not advance nextSeid because they
do not represent new allocation.
An AdvanceNextSeid record advances the identified Space directly
to the stored value. It preserves the unwritten suffix of a preallocated Seid range which packet
records cannot reveal. Like every other record, its effect is applied only when recovery reaches the
Snapshot which commits it.
Recovering DeleteSerialElement
When a committed DeleteSerialElement record is processed, its
PartitionSeid must identify the head packet of a live serial
element in the recovered state immediately preceding that record.
The requirement fails if any of the following is true:
- the Space does not exist;
- the head Seid has no live RPM mapping;
- the mapped packet is an overflow packet rather than a head packet;
- the serial element has already been deleted; or
- the packet chain cannot be traversed and validated as one complete live serial element.
Any such failure means the committed log is inconsistent with the checkpoint and preceding committed records. Recovery fails, the LSS is interpreted as corrupt, and it cannot be opened. Recovery must not treat the record as idempotent, ignore it, delete only a suffix of the chain or continue scanning in an attempt to produce a partially recovered store.
For a valid record, recovery follows the chain from the head, removes the RPM mapping for every packet
in the serial element and decreases SUT utilization for every removed packet. The one
DeleteSerialElement record therefore has the same whole-chain
effect during recovery as it has during normal execution.
Failure of recovery
Recovery also fails when a committed record is malformed, refers to the wrong partition, violates a record-specific invariant or would make the recovered RPM, SpaceDirectory, SUT or packet chains inconsistent. Failure leaves no usable open partition. Diagnostic reporting should identify the record position and violated invariant, but diagnostics must not change the fail-closed result.