Skip to content

PostgreSQL Base Infrastructure — Section Overview

Contents:

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/pfree against a CurrentMemoryContext, with four allocator implementations behind one MemoryContextMethods virtual table: AllocSet (the general-purpose default, aset.c), Slab (fixed-size chunks, slab.c), Generation (FIFO-ish lifespans, generation.c), and Bump (dense, no individual free — the REL_18-era addition, bump.c).
  • Error handling (utils/error/) — the elog/ereport family, error severity levels, and the setjmp/longjmp non-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 a pg_proc catalog row into a callable FmgrInfo, the V1 calling convention (PG_FUNCTION_ARGS / FunctionCallInfo), and funcapi for 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/) — the ResourceOwner tree (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 under mmgr/.
  • 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 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 palloc failure is itself an ereport(ERROR, ...), and the longjmp that 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 rarely frees 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 an FmgrInfo / FunctionCallInfo; fmgr is the indirection, adt is the population of functions behind it.

Cross-referenced-first — read the two bottom facilities before anything that sits on them:

  1. postgres-memory-contexts.md — the allocator tree. Nothing else makes sense until you understand palloc/MemoryContextSwitchTo and the context lifespan model.
  2. postgres-error-handling.mdelog/ereport and the PG_TRY/longjmp unwind. Read alongside (1): the two are co-designed.
  3. postgres-resource-owners.md — the pin/lock cleanup tree; it reads as a direct analog of (1), so read it right after.
  4. postgres-dynahash.md — the generic hash engine; short, and referenced by the catalog caches and the shared lock/buffer tables.
  5. postgres-fmgr.md — how a catalog function becomes a C call; the gate to the datatype library.
  6. postgres-datatypes-adt.md — the type library reached through fmgr.
  7. postgres-guc-parameters.md — the configuration system; mostly independent, can be read last (or first if you arrived chasing a parameter).

Forward references — these module docs are planned; summaries are predictive.

Module docOne-line scope
postgres-memory-contexts.mdThe 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.mdThe elog/ereport family, severity levels (DEBUGPANIC), the errmsg/errcode/errdetail builder, and the setjmp/longjmp unwinding via PG_TRY/PG_CATCH/PG_RE_THROW and PG_exception_stack.
postgres-fmgr.mdThe 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.mdThe 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.mdThe 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.mdThe 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.mddynahash.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.

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.c lives under mmgr/ 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.