Exercise 3: MVCC Across a Simulated Restart — Possible Solution ==================================================================== THE TEST ------------------------------ mvcc = MVCCStore() t = mvcc.begin() mvcc.write(t, 10, {'id': 10, 'name': 'Widget', 'stock': 100}) mvcc.commit(t) # simulate a restart: a BRAND NEW MVCCStore object -- nothing shared with the old one mvcc_after_restart = MVCCStore() found = mvcc_after_restart.versions.get(10) print(found) RESULT ------------------------------ MVCC 'products' row after a real Python-level restart (fresh object, same variable name): None The committed row is completely gone. mvcc_after_restart.versions is a fresh, empty dict -- there is nothing anywhere for it to find. WHY THIS IS THE EXPECTED, INEVITABLE OUTCOME ------------------------------ MVCCStore, exactly as built and verified in Chapter 6, stores every Version object as a plain Python object living in a plain Python dict (self.versions) -- there is no file, no WAL, no HeapFile anywhere in its own implementation. Creating a new MVCCStore() object doesn't "reload" anything from disk, because nothing was ever written to disk in the first place. This isn't a bug in MVCCStore's own commit() logic -- commit() genuinely does everything Chapter 6 promised (the row is real, correctly versioned, and correctly committed in memory) -- it's a completely different, much larger gap: the whole class was never given ANY persistence layer at all. WHY THIS IS A GENUINELY DIFFERENT KIND OF GAP THAN EITHER BUG FOUND IN THIS CAPSTONE ------------------------------ Both of this chapter's own found bugs (the rollback/recovery conflict, and the shared-WAL corruption) were REAL bugs in code that was ATTEMPTING to be durable -- genuine mistakes in an integration that was trying to do the right thing and got a detail wrong. MVCC's own lack of persistence isn't a mistake in that sense at all -- it's an honest reflection of what Chapter 6 was actually scoped to build: a correct concurrency-control STRATEGY, verified entirely in memory, with real disk-backed storage explicitly left as later, unattempted work. There's no small fix analogous to "log the rollback too" or "use one WAL per table" that would close this gap -- it would require building an entirely new storage layer for MVCC's own version chains, comparable in scope to Chapters 1-4 combined, applied to a genuinely different (row-versioned, not page-based) data model. WHY THIS WORKS AS AN ANSWER ------------------------------ Actually performing the restart -- creating a real second object, not just reasoning about what "should" happen -- makes the contrast against Steps 6-7's own genuine recovery concrete and undeniable: the disk-backed catalog gets its data BACK after a simulated crash; MVCC gets nothing back at all, because there was never anything durable to get back from. That distinction is the entire point of this chapter's own closing finding.