Back to “log LSN on DROP TABLE”
Fix correctness and coverage of recovery landmarks for destructive DDL.
Transcript summary and timecodes pending captions.
direct mapping
postgres@hacking:~$ ls people/kirk-wolak/sessions/
Postgres community hacker and recurring session participant. 32 sessions in the public archive.
Fix correctness and coverage of recovery landmarks for destructive DDL.
Transcript summary and timecodes pending captions.
Agent-assisted patch work around the wait-event timing submission.
The group reviewed Kirk Wolak's pg_dump patch for keeping loadable placeholders when table data is excluded, grounding the discussion in his large-table restore workflow. They debated a positive interface, filter-file actions, arbitrary dump queries, PII transformation, and referential-integrity risks, then posted supportive review feedback to pgsql-hackers. The final segment examined Salma El-Sayed's B-tree leaf-page merge design, including merged-page markers, scan correctness, vacuum cleanup, and review plans.
Independent benchmarks, observer effect, coverage, and patch restructuring.
Dmitry Fomin presented a seven-patch wait-event tracing series, split for review but intended to provide complete transition timing and query attribution. The group designed an independent benchmark ladder covering vanilla, compiled-disabled, stats, and full trace modes; corrected pgbench workloads; and distinguished static overhead from observer effect. Preliminary runs showed no clear slowdown, but they added pg_stat_statements, wait-event counts, repeated rounds, raw results, and independent review before submission.
End-to-end tests for archive-fed logical decoding and pause/resume behavior.
The session refined logical decoding from an archive-fed physical standby as a recoverable, production-independent pipeline: after losing the decoding node, a consumer can restore another standby at the acknowledged LSN and tolerate overlap. They reviewed the three-patch implementation and TAP test, found registration and naming issues, debated lock structure, and judged the code ready for discussion after fixes. They then specified an end-to-end WAL-G test with catalog churn, paused consumption, catch-up, and a final marker.
Pause replay instead of invalidating conflicting logical slots; design auto-resume.
The group connected archive-fed logical decoding to resilient analytical replication: replay should pause before catalog cleanup invalidates a lagging slot, then resume automatically once consumption catches up. They manually audited an AI-generated prototype and its complex TAP test, discovering that the test needed clearer assertions around the actual paused state. They accepted a proof-of-concept pause GUC, rejected manual resume as incomplete, and designed auto-resume behavior for drained, dropped, or otherwise nonblocking slots.
Use an archive-fed standby as a logical-decoding engine.
The session began by testing whether Postgres 16's logical decoding on a standby could turn an archive-fed recovery instance into a detached decoding engine. The group concluded a full server is the practical first implementation because it supplies catalog snapshots and output plugins; the missing behavior is to pause replay when it would invalidate a slot and continue when consumption advances. They also identified broader uses: per-record WAL verification, recovery debugging, and filtered, PII-free staging streams.
Custom command tags and logical decoding from an archive-fed recovery server.
The workshop first revisited customizable command tags, confirming legacy behavior remains the default and its added branch should be negligible, then explored extensible client protocols and better psql completion. The main direction was extracting data from managed Postgres without burdening production: decode archived WAL into a logical stream. They compared a full recovery server with a standalone tool, concluding the latter would need schema state at a starting LSN, checkpoint/full-page-image handling, and careful treatment of file swaps such as pg_repack.
Low-overhead per-event timing and trace capture.
The group compared pg_wait_tracer's external eBPF hardware-watchpoint tracing with Dmitri Fomin's new Postgres patch, which records wait transitions into per-backend lock-free ring buffers. They designed a shared-buffer-thrashing benchmark to stress transition overhead, explored transition, concurrency, and query-profile visualizations, and discussed eventual EXPLAIN integration. Preliminary claims of roughly 2% patched overhead were treated as unverified; the agreed next steps were finish benchmarks, publish the tool, review the code, and prepare a pgsql-hackers proposal.
pg_wait_tracer, core timing, USDT probes, and observer-effect trade-offs.
Dmitri Fomin demonstrated pg_wait_tracer, an eBPF-based tool that captures every Postgres wait-event transition with microsecond-to-nanosecond timestamps, replayable trace files, latency heatmaps, and query drill-down. The motivating case was intermittent primary-key lookups jumping from milliseconds to a one-second timeout. The group identified inlined pgstat_report_wait_start/end calls as the obstacle to ordinary probes, produced a small USDT-probe prototype, and planned worst-case overhead benchmarks before proposing always-on core instrumentation.
Custom protocol command tags and _pq_ capability negotiation.
After testing the newly committed REPACK command and confirming that it is transactional but takes an access-exclusive lock, the group built a prototype for customizable command-completion tags such as schema-qualified table names. A first server-only change broke psql's parser, exposing the need for client/server capability negotiation. The agent then used the existing _pq_ protocol-options framework so only requesting clients receive the new format. They reviewed compatibility tests and concluded the patch was useful for discussion but needed cleanup before pgsql-hackers.
Evaluate agentic hacking, develop GSoC project ideas, and experiment with pglz compression.
The first half examined AI-assisted Postgres development: community overload, specification-first agent workflows, independent review, and personal responsibility for generated work. The second half audited an agent-produced pglz optimization series. Existing benchmarks mixed runtime and work done, while some optimizations changed compressed output. The group therefore narrowed the project to byte-compatible changes, required old-versus-new output tests, fixed-transaction-count and multi-platform benchmarks, and a small reproducible pgsql-hackers result; a reported 14% workload gain still needed verification.
Turn workshop ideas into scoped GSoC projects, including wait-event coverage, pg_stat_statements scalability, and B-tree page merge.
The group turned Postgres GSoC brainstorming into a draft set of core-development projects. After Nikolay recounted his 2006 SQL/XML GSoC experience, they evaluated planner, parallel GiST build, TOAST slicing, test coverage, logged/unlogged tables, global temporary tables, and autovacuum ideas. They then added wait-event coverage, pg_stat_statements scalability, and B-tree page merge, using an AI-generated wiki draft. The draft still needed expert validation, clearer mentor ownership, and manual editing before merging into the official ideas page.
Prototype merging sparse B-tree leaf pages and audit its correctness failures.
The workshop focused on a prototype for reclaiming B-tree bloat by merging adjacent sparse leaf pages. Kirk proposed an incremental, access-exclusive-lock design that first merges only one pair, prioritizing correctness of forward and backward scans. The pgindex_reclaim extension identified merge candidates, but execution crashed. Inspection showed incomplete parent-page handling and incorrect WAL/critical-section logic. The group chose to stop trusting the generated merge code, add a reproducible regression test, study related upstream page-deletion work, and restart from the smallest verifiable merge.
Discuss wait-event coverage gaps; follow-up work added COPY file and program waits upstream.
Starting from an AI-assisted audit of missing wait-event coverage, the group distinguished genuine waits from CPU work and chose COPY as a testable first target. They reproduced an unreported wait in COPY FROM PROGRAM, prototyped events for program input and output, and used pg_stat_activity and pg_wait_sampling to validate them. The investigation also exposed missing coverage for ordinary COPY file reads and writes, expanding the planned patch to all four paths; the file/program work later reached core.
Partial refresh restricted by a predicate, including concurrency semantics.
The session explored adding a WHERE clause to REFRESH MATERIALIZED VIEW so selected rows can be refreshed without rebuilding the whole result. Reading the concurrent-refresh implementation revealed that Postgres creates a temporary difference table, then applies ordinary SQL deletes and inserts through SPI. After experimentally bypassing the normal DML guard, updates to a materialized view and its indexes worked. The group concluded that partial refresh looked technically approachable, while delete semantics, grammar, safety, and consistency still needed design work.
Review B-tree merge blockers and prototype commit-LSN logging for DROP TABLE.
After reviewing UUIDv7 and amcheck support for GIN in Postgres 18, the group discussed responsible AI-assisted hacking and briefly parked the B-tree merge work over unresolved scan concurrency. Most of the session revisited recovery from accidental DROP TABLE: they asked an agent to extend transaction callbacks with the commit LSN and build a logging extension. The prototype found table names through object-access hooks, but cleanup timing and an invalid commit LSN prevented a working result, leaving the design unfinished.
Test B-tree page merge against concurrent scans and expose correctness failures.
The group assessed the B-tree page-merge prototype after community feedback. They agreed benchmarks should emphasize extra buffer I/O, cache pollution, WAL, and sparse-page workloads rather than lookup latency alone. A new injection-point test then demonstrated the critical flaw: a concurrent forward scan returned duplicates while a backward scan missed tuples after pages were merged. Several recovery schemes were examined, but repeated vacuums and concurrent inserts defeated the simple designs. The session ended with correctness and concurrency still unresolved.
Continue page-merge implementation and correctness work.
The group refined a minimal B-tree merge: move tuples from a very sparse leaf page into its right sibling, then reuse existing page-deletion machinery. They inspected page layouts, asked an agent to implement the change inside vacuum, and built a sparse index. After removing an assertion, one page was successfully emptied without a crash. However, regression and foreign-key tests failed, and concurrent scans were not tested, so the result remained a potentially corrupt prototype rather than a valid patch.
Continue B-tree page-merge design and prototype.
The session established why sparse B-tree pages matter: they increase buffer churn, WAL full-page images, replica storage, and the cost of scans. The group then traced vacuum's existing half-dead page deletion and studied whether a merge could resemble a split. Moving tuples directly exposed a duplicate-read race for concurrent scans, implying a two-phase protocol that removes the parent downlink before relocation. By the end they identified split/finish-split as the code to reverse, but deferred implementation pending a sound scan protocol.
Merge sparse sibling B-tree pages to reduce bloat.
This B-tree page-merge session moved from automated REINDEX toward fixing the cause of persistent bloat. The group defined the target as partially empty leaf pages that vacuum cannot reclaim, then had an agent build a logical leaf-page scan that reports adjacent pages fitting into one block. On a randomized 90%-deleted workload it found widespread merge opportunities. They did not implement merging: backward-scan visibility, transaction horizons, WAL replay, lock coupling, and undetectable lightweight-lock deadlocks were identified as the core design problems.
Standby MultiXact creation, corruption edges, and deadlock.
The session reproduced a standby deadlock involving MultiXact lookup: a reader holds a heap buffer lock while waiting for a not-yet-replayed MultiXact offset, and the startup process needs that buffer before it can supply the offset. The team demonstrated the hang on Postgres 13 and current branches, confirmed that SIGINT cannot break it, evaluated three unsafe fixes, then implemented a localized WAL-redo fix that pre-populates the next offset on the same SLRU page.
Generic workshop near the start of the MultiXact standby-deadlock thread.
Responding to audience interest in locking, the group investigated a Postgres 17 standby hang introduced when a one-millisecond MultiXact polling sleep was replaced with condition variables. A reported workload could drive replica TPS to zero. They reconstructed the locking protocol, used AI to inspect the patch and report, and realized the likely failure is a true deadlock: a query waits for MultiXact replay while holding the heap page needed by startup. They planned timeout instrumentation and stronger diagnostics.
Rebase GiST amcheck and design useful corruption tests.
The group revived the long-running amcheck work for GiST indexes after shared infrastructure and the GIN checker had been committed. They manually rebased the remaining GiST patch, repaired build files and SQL upgrade scripts, and got its basic checks passing. They then asked Cursor to adapt newly committed GIN corruption tests. The generated tests initially assumed ordering that GiST does not have and later passed without actually corrupting indexes, leaving only a useful page-header corruption idea and more manual work.
Review commit-LSN logging for destructive DDL and its test strategy.
The workshop resumed the patch that logs a recovery LSN when destructive DDL commits. Review showed AI-generated schema support used the wrong hook, added an uncalled function, and supplied a nondeterministic regression test unsuitable for raw LSN output; a TAP test was deemed necessary. Rather than finish the substantial cleanup live, they switched to optimizing the regression-test schedule with Cursor. Its reordered groups caused failures and thermal throttling, demonstrating that faster scheduling must respect test dependencies and stable benchmarking conditions.
Add a pg_resetwal system-identifier option and audit the agentic patch workflow.
Nik presented an AI-assisted pg_resetwal option for changing the system identifier, needed to replay archived WAL after DBLab created a replacement cluster. Review accepted the use case but called for removing interactive safeguards, shortening documentation, reducing redundant tests, and aligning option identifiers with other frontend tools. The session then demonstrated Nik's agentic patch workflow: small commits, specification-first documentation, compilation and manual tests, strict review by stronger models, and a final human review that caught issues the models missed.
Merge improvements into commit-LSN logging for destructive DDL.
The session opened with AI-assisted Postgres development lessons from the committed pg_dump policy patch and a separate wal_compression-level prototype: write tests and documentation early, review every line, and use several strong models as independent critics. The practical task was merging Jim Jones's improvements into the patch that logs commit LSNs for destructive DDL. Cursor produced overbroad changes, but after resetting and supplying both patches, the group compiled and manually tested the result, found a callback-unregistration bug, and attempted test-driven repair.
Continue design and patch work on dump-time analysis.
Part two implemented the pg_dump side of per-object ANALYZE. The group modeled ANALYZE as a new dumpable archive object, dependent on its table and emitted in the post-data section after data and indexes. They limited the first prototype to ordinary tables and materialized views, excluding sequences, views, and foreign tables. The code compiled, but no ANALYZE appeared in output because the new object was not reached or enabled correctly; print debugging exposed control-flow problems, and they deferred completion.
Preserve or trigger statistics collection in dump/restore output.
The group investigated why pg_restore leaves restored relations without planner statistics and agreed that a database-wide ANALYZE in pg_restore would be too coarse. Instead, pg_dump should add an ANALYZE entry for every dumped table so archive filtering and partial restores retain correct behavior. They explored directory-format archives, TOC dependencies, table-data files, materialized-view refresh ordering, and index ArchiveEntry code. They concluded ANALYZE belongs after data, indexes, and materialized-view population, then began defining a new DumpableObject type before the call ended.
Log a recovery landmark when destructive DDL commits.
The group designed a recovery landmark for accidental DROP TABLE. They first considered emitting a named restore-point WAL record, then traced deletion through parser, dependency, permission, and lock paths. Rollback and the absence of a fresh LSN before any WAL write made that design misleading. They pivoted to logging a restore LSN after the table lock is acquired but before deletion, restricted it to ordinary tables, demonstrated the output, and prepared a small pgsql-hackers patch.
Link psql help to online SQL-command documentation.
The group prototyped richer psql help after noting that autocomplete and backslash-h do little for functions or unknown keywords. They modified the no-match path to print clickable documentation or search URLs, added a configurable HELP_URLS variable containing pipe-separated templates, implemented substitution and URL encoding, and tested PostgreSQL.org, Google, and DuckDuckGo links. They kept PostgreSQL.org as the default, refined the wording, and prepared a discussion patch while leaving external API/LLM help and reusable URL functions as future ideas.
Review UUIDv7 and build deterministic transaction_timeout tests.
The first section reviewed UUIDv7's evolving RFC, monotonic counter, distributed generation, timestamp extraction, and blocked core support. They also surveyed transaction-timeout and SLRU-locking work. The hands-on section tackled flaky transaction-timeout tests by combining injection points with a background psql watch loop. Testing uncovered false success from malformed watch parameters and a broken-pipe cleanup problem when timeout killed psql. The harness remained unfinished, needing a reliable way to detect whether the background session is active.
Explore compression paths and possible improvements.
The session began by designing an overflow hash table for pg_stat_statements and pg_stat_kcache so new query IDs would not block behind a busy main table; races and merge semantics made it unsuitable for an immediate patch. Discussion then shifted to compression throughout Postgres. Per-column dictionaries were judged invasive, while reusing compression context during B-tree WAL logging looked tractable. They examined pglz and LZ4 stream constraints and concluded that B-tree builds should first batch pages like GiST; no code was written.