You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
GlobalQueryCache is cleared when a schema-changing update transaction commits. However, read transactions that pinned the previous graph snapshot are allowed to continue while the new snapshot is committed.
A reader can therefore race with cache invalidation as follows:
A read transaction pins the current snapshot and begins resolving a query against its schema.
A concurrent schema-changing update clears the global query cache and publishes a new snapshot.
The existing reader compiles the query against its pinned old snapshot and inserts that plan into the now-empty global cache.
A reader on the new snapshot looks up the same query and reuses the plan compiled against the old schema.
sequenceDiagram
participant R as Reader Thread
participant W as Schema Update Thread
participant C as GlobalQueryCache
participant S as Snapshot Store
R->>S: Pin current snapshot S0
R->>S: Check S0 is current
S-->>R: true
Note over R,W: Reader is paused before accessing the cache
W->>C: Clear all cached plans
W->>S: Publish schema snapshot S1
W->>W: Commit completes
R->>C: Get query Q
C-->>R: Cache miss
R->>R: Compile plan P0 against pinned S0
R->>C: Insert Q to P0
Note over C,S: Cache now contains P0 while the current snapshot is S1
Loading
The reverse mismatch is also possible: an old-snapshot reader may reuse a plan that was compiled and cached for the newly published schema.
Because cache entries are keyed only by query text and do not carry a schema or snapshot version, clearing the cache alone does not prevent plans from crossing schema generations.
Impact
After a concurrent schema change, a cached physical plan may be executed against a different schema from the one used during compilation. Depending on the schema change, this can produce incorrect property or label resolution, execution-time errors, or allow a query that should fail during planning to bypass schema validation.
Problem
GlobalQueryCache is cleared when a schema-changing update transaction commits. However, read transactions that pinned the previous graph snapshot are allowed to continue while the new snapshot is committed.
A reader can therefore race with cache invalidation as follows:
sequenceDiagram participant R as Reader Thread participant W as Schema Update Thread participant C as GlobalQueryCache participant S as Snapshot Store R->>S: Pin current snapshot S0 R->>S: Check S0 is current S-->>R: true Note over R,W: Reader is paused before accessing the cache W->>C: Clear all cached plans W->>S: Publish schema snapshot S1 W->>W: Commit completes R->>C: Get query Q C-->>R: Cache miss R->>R: Compile plan P0 against pinned S0 R->>C: Insert Q to P0 Note over C,S: Cache now contains P0 while the current snapshot is S1The reverse mismatch is also possible: an old-snapshot reader may reuse a plan that was compiled and cached for the newly published schema.
Because cache entries are keyed only by query text and do not carry a schema or snapshot version, clearing the cache alone does not prevent plans from crossing schema generations.
Impact
After a concurrent schema change, a cached physical plan may be executed against a different schema from the one used during compilation. Depending on the schema change, this can produce incorrect property or label resolution, execution-time errors, or allow a query that should fail during planning to bypass schema validation.