PostgreSQL Base Infrastructure — Section Overview
Contents:
What this section covers
Section titled “What this section covers”This is the base-infra subcategory: the process-local substrate that
every other PostgreSQL subsystem assumes already exists. Unlike the other
subcategories, base-infra has no single “feature” — it is the set of
cross-cutting facilities that the storage engine, the query pipeline, the
catalog, and the transaction machinery all call into. If you open almost any
.c file in the backend, the first things it touches are here: it pallocs
into a memory context, it ereports on error, it looks a function up through
fmgr, it reads a GUC, it stores cleanup on a resource owner.
Concretely, the subcategory owns seven facilities, rooted under
src/backend/utils/:
- Memory contexts (
utils/mmgr/) — the hierarchical allocator tree.palloc/pfreeagainst aCurrentMemoryContext, with four allocator implementations behind oneMemoryContextMethodsvirtual table:AllocSet(the general-purpose default,aset.c),Slab(fixed-size chunks,slab.c),Generation(FIFO-ish lifespans,generation.c), andBump(dense, no individual free — the REL_18-era addition,bump.c). - Error handling (
utils/error/) — theelog/ereportfamily, error severity levels, and thesetjmp/longjmpnon-local unwinding (PG_TRY/PG_CATCH/PG_RE_THROW,PG_exception_stack) that makes “throw an error from anywhere, clean up reliably” work without C++ exceptions. - The function manager (
utils/fmgr/) —fmgr, which turns apg_proccatalog row into a callableFmgrInfo, the V1 calling convention (PG_FUNCTION_ARGS/FunctionCallInfo), andfuncapifor set-returning and composite-returning functions. - The datatype library (
utils/adt/) — ~118 files implementing the in/out/send/recv functions and operators for every built-in type: numeric, varlena text, date/time,jsonb, arrays, ranges/multiranges, network types, and the selectivity estimators planners read. - GUC parameters (
utils/misc/) — the Grand Unified Configuration system: variable definitions (guc_tables.c), the priority-ordered source stack (postgresql.conf, command line,ALTER SYSTEM, per-role/per-database), and check/assign/show hooks. - Resource owners (
utils/resowner/) — theResourceOwnertree (modeled on the memory-context tree) that tracks buffer pins, lock references, tuple descriptors, and similar resources so they are released at transaction/query end even on error. - dynahash (
utils/hash/) —dynahash.c, the chaining hash table used both for process-local tables and, in a partitioned shared-memory mode, for the buffer lookup table and the heavyweight lock table.
Sharp boundaries — what is not here:
- Tuple sorting and spill (
utils/sort/:tuplesort.c,tuplestore.c,logtape.c) is structurally adjacent in the tree but belongs to query-processing (postgres-tuplesort.md) — it is a query-execution facility, not a universal substrate. - Encoding conversion and locale/collation (
utils/mb/,utils/adt/pg_locale*) belong to i18n-text — base-infra hands the text datatypes off there for charset and collation behavior. - Dynamic shared memory and the shared allocator (
utils/mmgr/dsa.c,freepage.c) belong to server-architecture (postgres-shared-memory-ipc.md): base-infra owns the process-local context tree; DSA is the shared-segment analog and is documented with the IPC substrate. - Portal memory (
utils/mmgr/portalmem.c) belongs to query-processing (postgres-portals-prepared.md), even though it lives undermmgr/. - Catalog caches built on dynahash (relcache, catcache) belong to system-catalog; base-infra owns only the generic hash-table engine, not the catalog-specific caches that instantiate it.
The substrate
Section titled “The substrate”The seven facilities are not peers — they layer. Memory contexts and error
handling are the true bottom: every other facility allocates in a context and
throws through ereport. The resource-owner tree and dynahash sit just above
them. fmgr, the adt library, and GUC are the application-facing facilities
that the rest of the engine calls into. The diagram shows the dependency
direction (an arrow means “is built on / calls into”), with node labels
naming the module doc that owns each box.
flowchart TB
subgraph CALLERS["the rest of the backend"]
REST["storage / executor / planner / catalog / txn<br/>(every other subcategory)"]
end
subgraph APP["application-facing substrate"]
FMGR["function manager<br/>postgres-fmgr.md<br/>(pg_proc row -> callable)"]
ADT["datatype library<br/>postgres-datatypes-adt.md<br/>(type I/O + operators)"]
GUC["GUC parameters<br/>postgres-guc-parameters.md<br/>(config variable system)"]
end
subgraph MID["tracking + lookup"]
RESOWN["resource owners<br/>postgres-resource-owners.md<br/>(pins/locks released on error)"]
HASH["dynahash<br/>postgres-dynahash.md<br/>(process-local + partitioned shared)"]
end
subgraph BOTTOM["the true bottom"]
MCXT["memory contexts<br/>postgres-memory-contexts.md<br/>(AllocSet / slab / generation / bump)"]
ELOG["error handling<br/>postgres-error-handling.md<br/>(elog/ereport, setjmp/longjmp unwind)"]
end
REST --> FMGR
REST --> ADT
REST --> GUC
REST --> RESOWN
REST --> HASH
FMGR --> ADT
ADT --> MCXT
GUC --> MCXT
RESOWN --> MCXT
HASH --> MCXT
FMGR --> MCXT
FMGR --> ELOG
MCXT -. "longjmp unwind frees the<br/>error/abort context" .-> ELOG
RESOWN -. "release ordering paired with<br/>context reset on abort" .-> MCXT
Three load-bearing relationships a reader should carry forward:
- Allocation and error handling are co-designed. A
pallocfailure is itself anereport(ERROR, ...), and thelongjmpthat unwinds an error hands control to a handler that resets/deletes the per-query context tree — so “allocate freely, throw on error, and the whole subtree is reclaimed at once” is the core idiom. This is why PostgreSQL C code rarelyfrees individually. - Resource owners mirror the memory-context tree by deliberate design (the resowner README says so explicitly): both are parent/child forests released top-down, and abort processing walks them in a fixed order so pins and locks drop alongside the memory they protected.
- fmgr is the bridge to the adt library. Every built-in operator and
type I/O routine in
utils/adt/is reached through anFmgrInfo/FunctionCallInfo; fmgr is the indirection, adt is the population of functions behind it.
Reading order
Section titled “Reading order”Cross-referenced-first — read the two bottom facilities before anything that sits on them:
postgres-memory-contexts.md— the allocator tree. Nothing else makes sense until you understandpalloc/MemoryContextSwitchToand the context lifespan model.postgres-error-handling.md—elog/ereportand thePG_TRY/longjmpunwind. Read alongside (1): the two are co-designed.postgres-resource-owners.md— the pin/lock cleanup tree; it reads as a direct analog of (1), so read it right after.postgres-dynahash.md— the generic hash engine; short, and referenced by the catalog caches and the shared lock/buffer tables.postgres-fmgr.md— how a catalog function becomes a C call; the gate to the datatype library.postgres-datatypes-adt.md— the type library reached through fmgr.postgres-guc-parameters.md— the configuration system; mostly independent, can be read last (or first if you arrived chasing a parameter).
Detail-doc summaries
Section titled “Detail-doc summaries”Forward references — these module docs are planned; summaries are predictive.
| Module doc | One-line scope |
|---|---|
postgres-memory-contexts.md | The hierarchical MemoryContext allocator: palloc/pfree, MemoryContextSwitchTo, context reset/delete lifecycles, and the four implementations behind one virtual table — AllocSet (default), Slab, Generation, and Bump. |
postgres-error-handling.md | The elog/ereport family, severity levels (DEBUG…PANIC), the errmsg/errcode/errdetail builder, and the setjmp/longjmp unwinding via PG_TRY/PG_CATCH/PG_RE_THROW and PG_exception_stack. |
postgres-fmgr.md | The function manager: turning a pg_proc row into an FmgrInfo, the V1 calling convention (PG_FUNCTION_ARGS, FunctionCallInfo, PG_GETARG_*/PG_RETURN_*), and funcapi for set- and composite-returning functions. |
postgres-datatypes-adt.md | The built-in datatype library in utils/adt/: the in/out/send/recv + operator functions for numeric, varlena text, date/time, jsonb, arrays, and ranges, plus the type-specific selectivity estimators the planner consumes. |
postgres-guc-parameters.md | The GUC system: variable definitions in guc_tables.c, the priority-ordered source stack (postgresql.conf → command line → ALTER SYSTEM → role/db), check/assign/show hooks, and the RESET/transactional-rollback semantics of SET. |
postgres-resource-owners.md | The ResourceOwner tree that tracks buffer pins, lock references, tuple descriptors, and plancache references, releasing them in a fixed order at query/transaction end or on error — modeled on the memory-context tree. |
postgres-dynahash.md | dynahash.c: the chaining hash-table engine used both process-local (e.g. backing syscache) and in partitioned shared-memory mode (the buffer lookup table and the heavyweight lock table), including its element/entry layout and partition locking. |
Adjacent sections
Section titled “Adjacent sections”base-infra is the floor, so it borders nearly everything; these are the sections it most directly hands off to or is consumed by.
- server-architecture (
postgres-overview-server-architecture.md) — the closest neighbor. dynahash in partitioned mode backs the heavyweight lock table; the DSA/dynamic-shared-memory allocator there is the shared-segment counterpart to base-infra’s process-local context tree (dsa.clives undermmgr/but is documented with the IPC substrate). Resource owners release the buffer pins and locks that subsystem manages. - query-processing (
postgres-overview-query-processing.md) — consumes fmgr for every expression call, the adt library for type behavior, and owns the spill facilities (postgres-tuplesort.md) and portal memory that live structurally near base-infra but belong to query execution. - system-catalog (
postgres-overview-system-catalog.md) — the relcache and catcache are built on dynahash and live in per-backend memory contexts; base-infra owns the generic engines, system-catalog owns the catalog-specific caches and their invalidation. - i18n-text (
postgres-overview-i18n-text.md) — receives the text datatypes from base-infra and adds encoding conversion (utils/mb/) and collation/locale providers (utils/adt/pg_locale*), which base-infra deliberately does not cover. - txn-recovery (
postgres-overview-txn-recovery.md) — abort processing there drives the resource-owner release and per-query context reset that base-infra defines; the two unwind paths run in lockstep on error.