CHAPTER DEEPREAD · DATABASE INTERNALS · CH 3

File Formats

Database Internals · Ch 3 · Alex Petrov · 2019

中文 →

What is this chapter about?

The photos on your phone, your chat history, your company's order book — all of it ends up as a file on a disk. The previous chapter explained why databases use a tree of signposts to find things. This chapter goes one floor down: what does one node of that tree actually look like, as a pile of bytes on disk? It sounds like tedious clean-up work. In fact, whether any of those elegant algorithms can run on real hardware is decided right here.

An analogy first

Think of a disk as a ring binder. It won't let you "insert a sentence on line 37". You can only take out a whole page, rewrite it, and put it back. But the things a database has to store come in wildly different sizes — an order is 80 bytes, a product description is 3,000. How do you pack ragged content neatly into fixed-size pages, and still be able to add and remove things at any time?

Why the old world was hard

In memory, someone else does the dirty work for you: ask the system for space and you get some; hand it back when you're done; remember where a thing lives by keeping its house number. On disk all three conveniences vanish. The house number is worthless once the thing moves to another page, nobody fills in the hole a deletion leaves behind, and the page size is fixed. And if you take the easy route — one fixed-size cubbyhole per record — the cubbyhole has to be sized for the longest record, so short records waste most of their space.

The core mechanism: one page, with a table of contents at the front

The answer databases reached is about as clever as laying out a menu: write the body from the back of the page forward, keep the table of contents at the front, leave the gap in the middle.

Each page also carries a tally number: computed and stored when the page is written, recomputed when it is read back. If the two disagree, you know the page quietly rotted on disk. The front of the file holds a passphrase and a version number, so a future program can tell at a glance which set of rules to read it by.

What it buys you

Nearly every database file you can open looks like this: PostgreSQL uses 8 KB pages, MySQL 16 KB, SQLite 4 KB, and inside each one sits a directory at the front and content at the back. The cost is honest too: deleting does not hand your disk space back right away — the holes come back only at some later tidy-up, and that tidy-up rewrites the whole page.

Remember this one line

Disks only deal in whole pages, but records come in ragged sizes. The database's answer is a page with a directory at the front: content lies wherever it fell, the directory keeps the order; deletions go on a "vacant lots" list and get tidied in a batch; and every page carries a tally number so it can't rot in silence.

Want the real byte layouts, the slotted-page diagrams and what each engine actually chose? → Switch to the deep read