BOOK DEEP READ · Database Internals · Chapter 6

B-Tree Variants

Database Internals · Ch 6 · Alex Petrov · 2019

中文 →

What is this chapter about?

The previous chapters built the database's index: layers of signposts that get you to the right page in a few hops. This one asks a different question — that scheme was invented forty years ago for spinning disks and single-core machines. Does it still fit?

A strange thing first

You probably assume the expensive part is finding. It isn't. The expensive part is changing. Edit an eighty-character record and the disk has to rewrite a whole page — thousands of characters. And so nobody reads a half-rewritten sheet, that page also gets a "work in progress" sign hung on it: everyone who passes has to wait. Finding a record costs three or four page turns. Changing one costs a full re-copy plus a queue of bystanders.

Why the old world is hard

One: change one character, rewrite a whole page. The page is the disk's unit; changing one byte costs about what changing the whole page costs.

Two: the higher the "work in progress" sign hangs, the worse the jam. Everyone passes through the topmost sheet of the index. Put a sign on it and all the machine's cores queue behind it.

Three: overwriting in place is itself risky. Lose power halfway through overwriting a page and you are left with a half-old, half-new mess — most of the ledger from the previous chapter exists to clean up after exactly this.

The core idea: four ways to stop editing the original

1. Re-copy instead of scribbling. To change a page, leave the original alone: copy it onto a fresh sheet and edit the copy, re-copying the signposts along the route from the cover down to it, then point the first line of the index at the new version — flipping that pointer is instantaneous, either old or new, never in between. Anyone reading the old version is entirely unaffected; readers never queue.

2. Stick notes on it, re-copy later. Instead of re-copying a page on every edit, stick a run of notes in the margin saying "this line now reads…", and let readers combine sheet and notes. Once the notes pile up, re-copy the whole thing once into a clean page.

3. File it in tiers. New changes go into the thin folder on top; when it fills, the whole folder is merged into a thicker one below, tier by tier. A finished folder is never edited again, so writing is always one continuous pass — exactly what flash likes, and the opposite of scattered little writes, which it hates.

4. Everyone cites door numbers, not addresses. Every signpost names a door number, and one registry maps "door number → current address". To change a page, write a small "change slip", pin it to the page, and repoint that one registry line at the slip — rewriting one registry line is a single indivisible instant, so nobody hangs a sign and nobody queues.

What it buys, and what it costs

Each trick cures one ailment: re-copying cures power loss and reader queues, margin notes cure "rewrite a page per character", tiered filing cures flash's dislike of scattered writes, door numbers cure queueing. The costs rhyme too: once a new version exists, someone has to sweep up the old one — the writes you save turn into space you occupy and background tidying you now owe.

One line to remember

The classic index tree is expensive to change, not to search. All four variants in this chapter attack the same assumption — does it really have to be edited in place? Stop editing in place and you get re-copying, note-sticking, tiered merging, or a pinned change slip plus a repointed door number. What you buy is power-loss safety, readers who never queue, and a shape flash likes. What you pay is space, and a tidying job that never ends.

Want the mechanisms, the notation and the diagrams? → Switch to the deep read