← All workEvidence & sources ↓

L–Store / Database engineering · Team coursework

Where does a record go when it changes?

We built a database engine around versioned columnar storage. Follow a record through an update, then explore what happens when transactions compete for it.

My contributionBuilt the HTAP engine with a five-person team, covering versioned storage, buffering, merge, and concurrent transactions.

Record-level locks · No independent throughput benchmark

Conceptual artwork: ivory architectural layers with orange inserts and steel fins.
Conceptual artwork

Explore the project

Conceptual walkthrough · database systems course project

Where does a record go when it changes?

Keep a history of updates. Resolve the version you need. Coordinate access to the record.

Base storage
Original value
Tail versions
—

Original value

A base record anchors the logical row.

Illustrative record lifecycle. No throughput or latency benchmark is implied.

A reader and a writer still conflict.

Try an exclusive acquisition while another transaction holds a shared lock. A conflict returns immediately; the caller decides whether to retry.

Transaction A · shared lockShared lock held
Transaction B · exclusive requestNot requested

A holds a shared lock. B has not requested access.

The lock table at the cited commit uses one mutex. Append-only versions do not remove record-level reader/writer conflicts. The repository is private; source links require access.

Lock granularity
one record

shared and exclusive locks are keyed by record id, not by page or table

Conflict behavior
no-wait

a conflicting acquisition returns immediately for the transaction to abort and retry, rather than blocking

Follow the evidence

Private team repository

The source is recorded for provenance but is not publicly accessible. This page explains the implementation without publishing the team’s code.

Source revision · fed4d8c6cadf64b2dc3dbdfc98a6af67a71944d7

Scope & limitations

  • Readers and writers do conflict. Append-only versioning means a read resolves a record version without waiting on page mutation, but record-level shared and exclusive locks still exclude each other.
  • Conflicts are resolved by refusal rather than by waiting, so behavior under contention depends on the caller's retry policy.
  • At the linked commit the whole lock table is guarded by one mutex, so lock acquisition itself serializes across records.
  • Validated by course autograders across three milestones. No independent throughput or latency benchmark exists, and none is claimed.
  • The repository is private, so these links resolve only for accounts with access.

The engineering decision

Separate read-optimized base pages from appended updates. Resolve versions through indirection and enforce shared/exclusive ownership at the record level.

What the evidence means

These storage, memory, and concurrency fundamentals support my broader infrastructure work. This course database did not power an LLM pipeline; its team repository remains private.

Implementation notes

A hybrid transactional/analytical engine built from scratch by a 5-person team and validated across 3 autograded milestones: immutable base pages, append-only tail pages, and an indirection column resolving each record to its latest version at read time. Writes append rather than mutate, so a read never waits on page mutation — but transactions still take record-level shared and exclusive locks that exclude each other, and a conflict is refused immediately for the transaction to retry rather than made to wait.