Skip to content

Coverage debt: two of the three visibility-map clears are held by nothing, and CHANGELOG says all three are #877

Description

@OffgridwithJD

Summary

CHANGELOG.md says of the three visibility-map clears added by #869: "All three clear now." Two of the three are held by nothing. Filed as coverage debt at jdatcmd's request, out of the #869 review. Not a defect — the code is right; the claim is unsupported by the tree.

Measurement

src/columnar_vacuum.c has three PgColumnarVMClearForRowRange call sites: recluster, the partial-group rewrite behind compact_rewrite, and expire. Delete the first two, keep expire's (source md5 47a19cd1a67fed1877bace13, call sites 3 → 1, mutation asserted applied by reading the mutated lines back out of the file), and every suite that could plausibly see it stays green on pg18a:

native_recluster          12/0    recluster_extent          17/0    recluster_gate      13/0
native_reclaim            33/0    native_reclaim_frag        4/0    native_reclaim_cycles 12/0
native_reclaim_reconcile  11/0    rewrite_group_scan         5/0    native_rewrite      17/0
native_ios                11/0    index_only                27/0    ttl_expire          34/0
vm_privilege              30/0    sorted_pathkeys          113/0

14 suites, 319 checks, zero failures with two of the three clears gone. Only expire's is covered, by test/ttl_expire.sh's index-only arm — which is the one the original data-loss report was about.

I tried to build the arm and it does not discriminate

Mirroring the ttl_ios idiom: VACUUM to set bits (relallvisible 2, plan confirmed an Index Only Scan), DELETE a quarter of the rows, recluster, then index-only against seqscan. Distinct .so per arm, mutation asserted applied:

                   branch (clear present)   mutated (clear removed)
.so                   182c9c9349c6               8a3f78663df6
index-only count          6000                       6000
seqscan count             6000                       6000
index-only sum(id)    24000000                   24000000
seqscan sum(id)       24000000                   24000000

Identical. The fixture cannot tell the two trees apart, so shipping it would have added an arm that cannot fail. I did not ship it.

State of knowledge, stated three ways

  • Verified: the recluster and partial-group clears are uncovered.
  • Verified: the fixture above cannot discriminate.
  • Unknown: whether a fixture that can discriminate exists. I did not find one and I am not going to assert a mechanism I have not observed.

What blocks the honest arm

Reading the visibility map directly needs pg_visibility, which is not built under these prefixes (no pg_visibility.control in the extension directory). pg_class.relallvisible is not a substitute: it is a statistic VACUUM refreshes, and clearing a VM bit does not touch it — test/ttl_expire.sh records hitting exactly this wall and settles for asserting the clear through its consequence.

So the first concrete step is probably build contrib/pg_visibility alongside the test prefixes, which would let a suite assert the bits rather than a downstream effect, and would make expire's own arm stronger too.

Until then

Either the CHANGELOG sentence should say which of the three is actually held, or the arm should exist. Right now the sentence claims more than the tree can show, which is the thing this project does not merge — I am reporting my own branch's overclaim rather than leaving it for someone to find.

Measured on pg18a, tree #869 head 5ea1c95 (now merged as part of 4c024d0).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions