jrgemignani opened a new pull request, #2551:
URL: https://github.com/apache/age/pull/2551

   Four problems with the TID-based VLE cache and its version counters, all 
from 798917c2 ("VLE cache + performance improvements").
   
   1. A path bound by MATCH could not be projected once the same statement 
deleted its endpoints (#2549):
   
          MATCH p = (n0)<-[:R*..2]-(n1) DETACH DELETE n0, n1 RETURN p
          ERROR:  get_vertex_entry_properties: stale TID - ...
   
      That commit replaced the properties Datum in vertex_entry and edge_entry 
with a TID fetched lazily at projection. cypher_delete() advances 
es_snapshot->curcid past every delete, so a path's own endpoints fail the 
visibility test by the time they are read; before, properties were captured at 
cache build and a later delete could not affect them.
   
      Such a tuple is still physically present, the deleting transaction having 
not committed, so it is read anyway and the path reports the properties it was 
matched with. The relaxation is narrow: only a tuple deleted by our own 
transaction qualifies, and only while the row still carries the cached entity, 
so a recycled line pointer cannot be substituted. Any other unreachable TID 
still raises the error, keeping a real invalidation bug visible. Properties are 
detoasted under the buffer pin, and the buffer is now released on the failing 
path too, since heap_fetch is called with keep_buf, which leaves it pinned when 
only visibility fails.
   
   2. VACUUM FULL and CLUSTER rewrite the heap, moving every cached TID, and 
announce themselves through no trigger and no version counter. A cached context 
then resolved stale TIDs against the new file, giving the stale TID error or 
"could not read block", which never reaches AGE's guard. Both are now 
intercepted in ag_ProcessUtility_hook as TRUNCATE already was, and the 
database-wide forms invalidate every tracked graph. Plain VACUUM and ANALYZE do 
not move tuples and are ignored.
   
   3. NULL properties were reported as a stale TID. Label tables are created 
with properties NOT NULL, so a NULL means the table was altered out from under 
AGE; that is now said plainly rather than blamed on the cache.
   
   4. Version counter slots were never released, making the table a tally of 
every graph ever mutated rather than of those that exist. A server cycling 
graphs filled it, then warned on every mutation and fell back to snapshot 
invalidation. drop_graph() now releases its slot and a freed slot is reused; a 
new occupant seeds its version above every value the table has issued, so a 
context cached for the previous occupant cannot compare equal. The cap moves 
128 -> 256, about 4 KB of shared memory at 16 bytes per entry; lookups scan 
only the entries in use, so unused slots cost nothing.
   
   Both accessors now share one helper, and hardcoded column numbers give way 
to the Anum_ag_label_* constants.
   
   cypher_vle gains 14 cases: the reported query, a fan-out that fails if the 
result depends on which row is projected first, partial and edge-only deletes, 
the edge-list projection, an edge property constraint reaching the accessor 
during traversal, zero-length bounds, self-loops, labelled vertices, a 
multi-hop chain, a delete from an earlier statement that must not be 
resurrected, savepoint and transaction rollback, and out-of-line TOAST asserted 
set-identical to a live read.
   
   age_global_graph covers CLUSTER and all three VACUUM FULL spellings (named, 
parenthesised, database-wide), plus plain VACUUM, ANALYZE and FULL false which 
must not invalidate; NULL properties on a vertex and an edge; 260 create/drop 
cycles that must stay silent; a rolled-back drop; and a graph recreated under a 
dropped name.
   
   Verified on PostgreSQL 18.4 and 18.6: clean build, no warnings; installcheck 
43/43 on 18.4 before and after, run twice; and 43/43 on 18.6 with 
--enable-cassert, reporting no assertion failure or resource leak.
   
   Fixes #2549
   
   
   modified:   regress/expected/age_global_graph.out
   modified:   regress/expected/cypher_vle.out
   modified:   regress/sql/age_global_graph.sql
   modified:   regress/sql/cypher_vle.sql
   modified:   src/backend/catalog/ag_catalog.c
   modified:   src/backend/commands/graph_commands.c
   modified:   src/backend/utils/adt/age_global_graph.c
   modified:   src/include/utils/age_global_graph.h


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to