Dmitry Werner created IGNITE-29014:
--------------------------------------

             Summary: Non-monotonic cache versions after fast full cluster 
restart cause "Invalid version for inner update" and B+ tree corruption
                 Key: IGNITE-29014
                 URL: https://issues.apache.org/jira/browse/IGNITE-29014
             Project: Ignite
          Issue Type: Task
            Reporter: Dmitry Werner


*Problem*
When a full cluster restart (all nodes stopped, then restarted) happens within 
a few seconds, cache versions generated by the new cluster incarnation can be 
LOWER than the versions of entries restored from the previous incarnation's 
persistent storage. In a real environment this manifests as "Invalid version 
for inner update" errors and B+ tree corruption (CorruptedTreeException) in the 
logs after a fast grid restart.

*Root cause*
GridCacheVersionManager#onLocalJoin derives the cache version offset from the 
cluster grid start time with 1-second precision:

         offset = (gridStartTime - TOP_VER_BASE_TIME) / 1000

The leading field of GridCacheVersion is (topologyVersion + offset). After a 
restart the topology version resets to a small value (1..N), so the offset has 
to compensate for that. If the new incarnation starts within a few seconds of 
the previous one, its offset is too small: versions generated at the new low 
topology versions end up below versions persisted by the previous incarnation 
(which reached a higher topology version while running). The first write to 
such an entry then fails the version check in GridCacheMapEntry ("Invalid 
version for inner update") and can lead to B+ tree corruption.

*Related work*
See IGNITE-28886. IgniteWalRebalanceTest.testWithLocalWalChange / 
testWithGlobalWalChange reproduced exactly this scenario in a test environment: 
starting a 2-node cluster right after stopping a 4-node (respectively 3-node) 
cluster failed with "Invalid version for inner update" / B+ tree corruption. 
The fix in IGNITE-28886 is a test-side workaround only — the test now waits at 
least TOP_VER_OFFSET_WAIT_SECS (5) seconds between cluster incarnations. This 
is a timeout stub that masks the underlying product issue: in a real 
environment (planned maintenance, 
full-cluster upgrade, failover) a fast restart can still corrupt data, and the 
test's 5-second wait is not a product-level guarantee.

*Suggested fix (for discussion)*
Guarantee cache version monotonicity across incarnations: persist the maximum 
generated cache version (e.g. the last data version) in durable storage, and on 
startup initialize the version offset/order strictly above the persisted value 
instead of relying solely on the wall-clock grid start time.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to