Skip to content

Future: a background worker to schedule columnar vacuum and analyze, which autovacuum cannot reach #415

Description

@jdatcmd

Future work, deliberately not scheduled. Filing it so the gap is recorded where it
is visible rather than discovered by a user, per #395.

The gap

pgColumnar has maintenance operations that PostgreSQL's own autovacuum daemon will
never invoke, because they are extension functions rather than table-AM callbacks:

operation reached by autovacuum?
pgcolumnar_relation_vacuum (visibility map, retire fully-deleted groups) yes, it is the AM callback
pgcolumnar.vacuum() (the space-reclaiming rewrite) no
pgcolumnar.vacuum_sorted() / clustering decay no
a future pgcolumnar.analyze() (#414) no

So the cheap online part is automatic and the expensive part is manual. A user who
never runs the functions accumulates reclaimable space and, if #414 goes ahead,
increasingly stale statistics.

The asymmetry matters: a table that is never rewritten wastes disk, which is visible
and survivable. Statistics that are never refreshed produce bad plans, which is
invisible and is felt as "the database got slower" with no obvious cause. That is the
argument for solving scheduling before adding more manual maintenance functions, and
it is why #414 is gated on this.

What it would be

A background worker registered from _PG_init, in the shape of core's autovacuum
launcher: a launcher that wakes on an interval and starts per-database workers, each
deciding what needs attention and doing it.

The decisions that need answering first, none of which are code

  1. What triggers work. Autovacuum uses row-change counters from the statistics
    collector. Our triggers are different in kind: reclaimable fraction (dead rows over
    live), clustering decay (pgcolumnar.sort_status, which already measures it), and
    staleness for analyze. Each needs a threshold and a GUC, and thresholds invented
    without measurement are how a daemon becomes a support burden.
  2. Not fighting autovacuum. The AM callback already runs under autovacuum and does
    the online work. A worker that also rewrites the same table takes
    AccessExclusiveLock, and doing that on a schedule the user did not choose is a very
    different proposition from doing it when they type it. This is the part I would
    most want argued before any code
    : an extension that takes an exclusive lock on a
    user's table on its own initiative needs a strong default of not doing so.
  3. Cost control. Autovacuum has vacuum_cost_delay and friends precisely because
    unbounded background I/O is worse than no background maintenance. We would need an
    equivalent, and would need to respect the existing settings rather than invent
    parallel ones.
  4. Registration cost. A background worker means shared_preload_libraries becomes
    effectively required for the feature, which changes installation. It should be
    possible to run pgColumnar without it and lose only this.
  5. Failure behaviour. A worker that errors must not restart in a tight loop, and
    must report where it failed in a way an administrator can act on.

Why a worker rather than the alternatives

  • Documentation plus cron works today and is what we should keep recommending
    until this exists. It is honest and it is what docs/administration.md should say.
  • A pg_cron dependency pushes the problem onto another extension and is not
    available everywhere.
  • Doing more inside the AM callback is tempting, since autovacuum already calls it,
    but the callback runs under ShareUpdateExclusiveLock and the expensive operations
    need AccessExclusiveLock. Escalating a lock inside a callback autovacuum invoked is
    not something I would want to do.

That third option is worth re-examining anyway: some of what the functions do today may
be reachable under the weaker lock, which would shrink this issue rather than solve it.
Worth a look before committing to a daemon.

Scope

Nothing here is scheduled. The next step, whenever it is taken, is the measurement in
(1): what fraction of reclaimable space and clustering decay actually costs a query
enough to be worth an automatic rewrite. Until that number exists, any threshold is a
guess.

Related: #414 (custom analyze, gated on this), the lazy-versus-eager maintenance split
recorded in docs/limitations.md.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions