skip to content

Engine Architecture & Storage Internals

How a relational engine is actually built: connections come in, pages and the buffer pool sit in the middle, and write-ahead logging plus recovery guarantee durability underneath. Interviewers probe these internals to see whether you understand what the database does with your SQL beyond the syntax — why commits are durable, where memory goes, and what happens after a crash.

part ofRelational database conceptsoverview, primer and where to startread it →
on this pageshow

questions

page 2 of 2

Columnar storage usually compresses far better than row storage. Explain why, describe run-length encoding and dictionary encoding, and say how compression affects query execution beyond saving disk space.

level: middleimportance: should knowfreq 50%

basics

~20 s

A column block holds one data type with similar, often repeating values, so it compresses far better than a row block that interleaves types. Run-length encoding stores value plus repeat count; dictionary encoding replaces values with small codes into a value table. Beyond disk savings, scans read fewer bytes and engines can filter and aggregate on encoded data without decompressing.

open as a page

Explain how a database sorts a result set far larger than the memory budget given to the sort operation, and describe the I/O cost of that algorithm.

level: middleimportance: should knowfreq 45%

basics

~20 s

It uses an external merge sort: fill memory, sort that chunk, write it out as a sorted run, repeat until input is exhausted, then merge the runs by repeatedly taking the smallest head value across them. Each pass reads and writes the whole dataset, and more memory means fewer, larger runs and usually a single merge pass.

open as a page

The SQL-standard INFORMATION_SCHEMA views and an engine's native catalog (for example a pg_catalog-style set of system tables, or sys.* / DBA_* dictionary views) both describe the same database. How do they differ, and when would you choose each?

level: middleimportance: should knowfreq 45%

basics

~20 s

INFORMATION_SCHEMA is a standard, portable, read-only view layer with the same column names across engines, but only standard concepts. The native catalog is the real underlying dictionary: engine-specific, far richer, usually faster. Use the standard for portable tooling, native for depth and performance.

open as a page

How would you use a database's catalog metadata to answer operational questions such as which indexes are never used, how much space a table and its indexes occupy, and whether the optimizer's statistics are stale?

level: middleimportance: should knowfreq 40%

basics

~20 s

Join the engine's native catalog: object tables for names and ownership, size functions or storage columns for bytes, index-usage counters for scans since reset, and statistics catalogs for row estimates, distinct values and the last analyze time. The standard views cannot answer any of these.

open as a page

What do a database's automatic statistics and vacuum/purge maintenance daemons do for you, and what symptoms appear when they cannot keep up with the write rate?

level: seniorimportance: should knowfreq 31%

basics

~20 s

They refresh optimizer statistics and reclaim space from dead row versions, on thresholds and under a throttle. Falling behind shows up as table and index bloat, growing history/undo, degrading scans, sudden bad plans from stale statistics, and maintenance that never finishes on the hottest tables.

open as a page

Your monitoring shows the database's buffer cache hit ratio steady at 99.5%, yet query latency has doubled. Explain how a high hit ratio can coexist with a serious performance problem, and what you would measure instead.

level: seniorimportance: should knowfreq 45%

basics

~20 s

Hit ratio is a ratio of page accesses, not of work. A query doing a hundred times more page accesses than needed can keep the ratio high while burning CPU and time. Measure absolute logical reads per query, physical reads, and latency - not the ratio.

open as a page

A nightly reporting job scans a table far larger than the server's memory, and for a while afterwards the normal transactional workload runs much slower. Explain the effect this has on the engine's page cache and what mechanisms engines use to prevent it.

level: seniorimportance: should knowfreq 42%

basics

~20 s

The scan reads pages used once and lets them displace the hot working set - cache pollution. The OLTP workload then misses on pages it used to hit until the pool refills. Engines defend with midpoint insertion, small ring buffers for bulk reads, and marking scan pages for immediate reuse.

open as a page

Every few minutes a production database shows a burst of write I/O with latency spikes across unrelated queries, and the bursts line up with its checkpoints. Explain the mechanism and how you would smooth it out.

level: seniorimportance: should knowfreq 45%

basics

~20 s

Dirty pages accumulate between checkpoints and are then flushed in a burst of random writes that saturates the device, so every query queues behind it. Smooth it by spreading the flush over most of the interval, letting a background writer trickle pages out continuously, and reducing dirty-page accumulation.

open as a page

A connection pooler can hand a server connection to a client for the duration of a whole session or only for the duration of a transaction. Compare these two pooling modes and explain what stops working in the transaction-scoped one.

level: seniorimportance: should knowfreq 44%

basics

~20 s

Session pooling binds a server connection to a client for its whole session - safe, but the multiplexing ratio is poor. Transaction pooling returns the server connection after each commit or rollback, allowing far more clients per server connection, but anything session-scoped breaks: session settings, temporary tables, session-level prepared statements, advisory locks, and cursors held across transactions.

open as a page

When a relational engine rolls back a transaction, the undo work itself is written to the transaction log as compensation log records. What problem do those records solve, and what happens if the server crashes again while a rollback is still in progress?

level: seniorimportance: should knowfreq 30%

basics

~20 s

A compensation log record (CLR) logs each reversal as it is performed and carries a pointer to the next record still to be undone. That makes rollback restartable and never repeated: after a second crash, recovery reads the CLRs, sees which reversals are done, and resumes from the pointer. CLRs are redo-only and are never themselves undone.

open as a page

In ARIES-style recovery, the redo pass reapplies changes made by transactions that were still uncommitted at crash time, only for the undo pass to roll them back immediately afterwards. Why is that apparently wasteful design chosen over skipping the uncommitted transactions during redo?

level: seniorimportance: should knowfreq 35%

basics

~20 s

Redo repeats history so that after it, the pages match the exact state at the moment of the crash. Undo then operates on a state it understands, using the same rollback path used at runtime. Selective redo would create a state that never existed, where logged before-images and page-internal structures no longer line up.

open as a page

When a stored row is rewritten at a larger size and no longer fits on its current page, what options does the storage engine have, and how does it find a page with enough free space for a new row in the first place?

level: seniorimportance: should knowfreq 35%

basics

~30 s

For a new row the engine consults a free-space map, a compact per-page summary of remaining space, to pick a page without scanning the file. If a rewritten row no longer fits, the engine first compacts the page; if that is still not enough it places the row on another page, either updating index entries or leaving a forwarding pointer behind, which costs an extra read on later lookups.

open as a page

Compare storing table rows in an unordered heap file, with secondary structures pointing into it, against storing the rows inside the primary-key structure itself (an index-organized or clustered table). What are the tradeoffs?

level: seniorimportance: should knowfreq 45%

basics

~20 s

A heap appends rows wherever there is space, so inserts are cheap and every lookup costs an index probe plus a fetch into the heap. An index-organized table keeps rows sorted inside the primary-key structure, so primary-key lookups and ranges need no extra fetch, but secondary lookups go through the primary key and inserts in random key order cause page splits and reordering.

open as a page

A hash join's build-side hash table does not fit in the memory budget for that operator. Explain what the engine does instead, and what goes wrong when the join key is heavily skewed.

level: seniorimportance: should knowfreq 42%

basics

~20 s

It partitions both inputs by a hash of the join key into batches written to temporary files, then joins one pair of matching partitions at a time in memory. If one key value dominates, its partition stays too big to fit, so partitioning recurses without helping and that batch degrades badly.

open as a page

When a session executes DDL such as adding a column to a busy table, what happens to the engine's catalog rows and to the in-memory catalog caches that other sessions hold? Why can concurrent sessions block, and why might a session briefly act on stale metadata?

level: seniorimportance: should knowfreq 35%

basics

~20 s

DDL updates catalog rows under a lock on the object. Because every backend caches catalog entries and compiled plans, the change must be broadcast as an invalidation; other sessions block on the lock or on reaching a safe point, then rebuild their cached definitions and replan. Long-running readers delay the whole thing.

open as a page

What is table and index bloat in an MVCC database, what symptoms does it produce, and what actually returns the space — to the object for reuse versus to the operating system?

level: seniorimportance: should knowfreq 42%

basics

~20 s

Bloat is space allocated to dead versions and half-empty pages rather than live data. Symptoms: files far larger than live data, scans reading mostly garbage, cache polluted, plans degrading. Ordinary cleanup frees space for reuse inside the object; only a rewrite or dropping a partition returns it to the operating system.

open as a page

Committing a transaction usually requires flushing the write-ahead log to stable storage with an fsync-style call. How does that shape commit latency and throughput, and what does group commit do about it?

level: seniorimportance: should knowfreq 48%

basics

~20 s

Commit latency is floored by the storage device's flush latency, since the commit record must be durable before acknowledgement. Group commit batches many concurrent commits into one flush, so throughput scales with concurrency even though single-commit latency does not improve.

open as a page

Log records in a write-ahead log are stamped with a monotonically increasing log sequence number, and data pages carry one too. What is an LSN used for?

level: seniorimportance: should knowfreq 38%

basics

~20 s

An LSN is a monotonically increasing position in the log. Each page stores the LSN of the last change applied to it, so the engine can enforce log-before-data, skip redo of changes a page already has, and address a point in the log stream.

open as a page

The directory holding a database's write-ahead log segments keeps growing until the disk is nearly full, even though the database's data size is stable. What causes log segments to accumulate, and how do you reason about it?

level: seniorimportance: should knowfreq 44%

basics

~20 s

Log segments are recycled only once nothing still needs them. Something is holding a required position: an unfinished checkpoint, a long-running transaction, a lagging or disconnected replica, a failing archive process, or a stalled backup. Find the oldest required log position and its owner.

open as a page

How would you decide how much memory to give a database's buffer pool on a dedicated 128 GB server, and what is 'double buffering' between the engine's page cache and the operating system's page cache?

level: principalimportance: should knowfreq 40%

basics

~20 s

Size it from the working set, not a fixed percentage, and leave room for per-connection memory, sort/hash workspace and the OS. Double buffering is the same page being cached twice - once by the engine, once by the kernel - wasting RAM; direct I/O or a much larger pool avoids it.

open as a page

How would you choose a checkpoint interval or recovery-time target for a production database, and what are you trading off in each direction?

level: principalimportance: should knowfreq 38%

basics

~20 s

Start from the recovery-time objective, since the interval bounds how much log replay a crash costs, then check the steady-state price: shorter intervals mean more repeated page writes and more full-page-image log volume. Choose the longest interval that still meets the recovery target.

open as a page

A transactional database is being slowed by long analytical scans from a BI tool. Discuss the architectural options for serving both transactional and analytical workloads, including hybrid designs that maintain row and column copies of the same data, and the tradeoffs you would weigh.

level: principalimportance: should knowfreq 40%

basics

~20 s

Options: keep one row store and accept the scan cost; offload analytics to a replica; copy data into a columnar analytical system; or use a hybrid engine that keeps a columnar representation alongside the row data, updated from the transaction stream. Trade freshness, storage and operational cost against isolation of the two workloads.

open as a page

You own a queue-like table in an MVCC database where rows are inserted and then updated to a completed state thousands of times per second, and background cleanup can never keep up. How would you redesign around dead-version accumulation?

level: principalimportance: should knowfreq 30%

basics

~20 s

Reduce versions produced and make removal a metadata operation. Narrow the churned row, cut updates per item, partition by time or state so completed work is dropped as a partition rather than deleted, tune cleanup to be far more aggressive on that table, and keep transactions short so the horizon never stalls.

open as a page

You are designing a multi-tenant product where each tenant could get its own schema, potentially tens of thousands of schemas and millions of catalog rows. What are the catalog-level consequences, and how would you decide between schema-per-tenant and one shared schema with a tenant identifier column?

level: principalimportance: nice to knowfreq 28%

basics

~20 s

Every schema multiplies catalog rows for tables, columns, indexes and constraints. At tens of thousands of tenants the dictionary itself becomes a hot, large, contended structure: slower planning, slower introspection, heavier backup and migrations that must run N times. Shared-schema scales the catalog; schema-per-tenant buys isolation.

open as a page

showing 31–54 of 54