Exercise 2: Three Records for the Same Page, Replayed in LSN Order — Possible Solution ==================================================================== THE TEST ------------------------------ heap = HeapFile(heap_path) wal = WAL(wal_path) pn = heap.allocate_page() pA = Page(); pA.add_record(b'VERSION-1') pB = Page(); pB.add_record(b'VERSION-2-LONGER') pC = Page(); pC.add_record(b'VERSION-3-FINAL') wal.append(pn, bytes(pA.data)) wal.append(pn, bytes(pB.data)) wal.append(pn, bytes(pC.data)) # none of the three applied yet -- crash before any of them reached the data file n = recover(heap, wal_path) final = heap.read_page(pn) RESULT ------------------------------ records applied: 3 final page matches VERSION-3 (the last one logged): True All three records replay, and the page ends up holding VERSION-3's own content -- not VERSION-1, not VERSION-2. WHY THE LAST-LOGGED VERSION CORRECTLY WINS ------------------------------ recover()'s own sort step, records.sort(key=lambda r: r['lsn']), guarantees the three records are replayed in the exact order they were originally logged -- 1, then 2, then 3. Since each record stores a COMPLETE new page image (Chapter 2's own design decision, not a delta), applying record 2 doesn't build on record 1's own result -- it simply overwrites the page outright with VERSION-2's own full content, discarding VERSION-1 entirely. Applying record 3 does the exact same thing again, discarding VERSION-2. The final state after all three replay is therefore identical to what the page would have looked like if the original three writes had actually completed, uninterrupted, back to back -- VERSION-3, and only VERSION-3. WHY LSN ORDER SPECIFICALLY MATTERS HERE ------------------------------ If recover() replayed these three records in the WRONG order (out of LSN sequence -- for instance, if a future change accidentally grouped records by page_num using an unordered data structure), the page could easily end up holding VERSION-1 or VERSION-2 instead of the correct VERSION-3, with no error or crash to reveal the mistake -- just a page silently holding older data than it should. The explicit sort by lsn is what guarantees "replay in LSN order" isn't an accident of file layout (though it happens to already match, since WAL.append() only ever appends sequentially) but an explicit, enforced property of the routine itself. WHY THIS WORKS AS AN ANSWER ------------------------------ Testing multiple records against the SAME page -- rather than each chapter finding's own one-record-per-page examples -- confirms recover() correctly reduces a whole sequence of updates down to the single, correct final state, and pins down explicitly why LSN ordering (not just "replay everything") is the specific property that makes that reduction correct.