The file is a strip of pages — 4 KB page reads and OS block alignment

The DB file is a strip of identical fixed-size pages — every read/write is one whole page because the disk and OS work in pages.

Previously

We need an ordered structure. Before we can build it, we have to know what the storage substrate looks like — and it's not a sea of bytes.

Scene 02

The file is a strip of pages

  1. Watch
  2. Try it
  3. Predict
  4. Capture
FILEusers.dbpage_size = 4 KBread-headHDRp11p22p33p44p55p66p77p88p99p1010p1111p1212p1313p1414p1515p1616OS BLOCKS · 4 KB each · ALIGNED · 1 page = 1 OS block4 KB4 KB4 KB4 KB4 KB4 KB4 KB4 KB4 KB4 KB4 KB4 KB4 KB4 KB4 KB4 KBI/O EVENTclick a page to fire one I/OIO COUNT0FILE SIZE (this layout)64 KBBANDWIDTH PER ROW LOOKUP1× (4 KB)an empty strip of identical 4 KB pages — every read or write moves one whole page
What to watch for

The file isn't a soup of bytes — it's a strip of identical pages. Watch the read-head sweep across them; each landing is one disk I/O. Then an INSERT picks exactly ONE page as rowid 42's home.

Continue unlocks when the animation finishes.
Implementation

Highlighted lines are the ones running in the diagram right now.

Pager.read_one_row
fetch the WHOLE page; slice the row out in RAM
def read_one_row(file, page_size, page_no, row_offset):
# disk addresses are page numbers, not byte offsets
offset = (page_no - 1) * page_size
page_buf = read(file, offset, page_size) # one I/O = one page
# row extraction happens entirely in RAM
row = extract_row_from_page_buffer(page_buf, row_offset)
return row
Kernel.effective_io
bytes the kernel actually moves for one page read
def effective_io(row_size, page_size, os_block=4096):
if page_size < os_block:
# sub-block page: kernel still drags a whole 4 KB block,
# SQLite throws the rest away
sub = os_block // page_size
return os_block # waste = (sub - 1) * page_size per read
if page_size == os_block:
# aligned: one page = one block = one disk transfer
return os_block
# supra-block page: one logical read spans many blocks
blocks = page_size // os_block
return blocks * os_block # bandwidth = blocks * 4 KB per row

Where this sits in Build a B-tree storage engine (SQLite-style)

Scene 02 of 11, in the Anatomy act — Pages, the tree of pages, and how a search descends.. The DB file is a strip of identical fixed-size pages — every read/write is one whole page because the disk and OS work in pages.

Up next. We have a strip of fixed-size pages, but no order yet. The next scene links pages into a tree so we can find any row in a few page reads instead of N.

All 11 scenes in Build a B-tree storage engine (SQLite-style) · Every curriculum

Built with Arqly
Every scene in Build a B-tree storage engine (SQLite-style) builds on the one before it.All 11 Build a B-tree storage engine (SQLite-style) scenes