Miklós Győrfi created JENA-1746:
-----------------------------------

             Summary: TDB2 rollback method clashes with nodetable cache
                 Key: JENA-1746
                 URL: https://issues.apache.org/jira/browse/JENA-1746
             Project: Apache Jena
          Issue Type: Bug
          Components: TDB2
    Affects Versions: Jena 3.12.0, Jena 3.11.0
         Environment: Linux  3.16.0-9-amd64 #1 SMP Debian 3.16.68-2 
(2019-06-17) x86_64 GNU/Linux

java version "1.8.0_05"
Java(TM) SE Runtime Environment (build 1.8.0_05-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.5-b02, mixed mode)
            Reporter: Miklós Győrfi


*Issue:* Inserting triplets, then rollbacking the TDB2 dataset, and loading 
back nodes, including some nodes again with the same content causes some 
artifacts and mess: some nodes disappear, some nodes are replaced. Moreover it 
unrecoverably *corrupts* the database files: accessing triplets then may cause 
RiotThriftException.

**org.apache.jena.riot.thrift.RiotThriftException: No conversion to a
Node: <RDF_Term >

*Reproduction*: Create some quads into a non-empty dataset, then rollback it, 
and create again the same triplets in another order, using anonymous and URL 
nodes  simultaneously. Although this method does not guarantee the issue, the 
possibility is high. 

*Cause*: My inverstigation shows, that the culprit is the {{NodeTableCache}}. 
It caches the node - nodeId relation of the backed table ({{NodeTableTRDF}}), 
but the cache does not react to the rollback (abort) operation. The backing 
table - during rollback - invalidates the  node Id-s. The node Id is in close 
relation of the position of the node data in the node data file, so new inserts 
can reuse these invalidated node Ids, or close to it for other nodes. As the 
nodes (remaining in cache, but not written, and the new ones) then overlaps 
each other, reading  back them causes Thrift errors, or later it causes missing 
nodes in the index. The data of the cached nodes disappears, if they fall out 
from the cache, or the dataset reopens.

*Possible fix:* None of the NodeTables registers and reacts to the rollback,  
only the backing file and index are restored. Best possible solution is 
_creating an option for these components to react to the restoration_. Cache 
then may evict cached data, or may track changes in transactions, and can evict 
only those. Anyway it is very justifiable for the rollback situations to evict 
all the caches.
TransactionCoordinator has collections for shutdownHooks, and for 
transactionsComponents. This is a good pattern for creating another collection 
for notification interfaces, and calling back these on transactional events. 
CacheNodeTable (and other objects) can then be a listener to this events, and 
may evict the cache, if necessary.

Other possibility to create callback option in the NodeTable to react to the 
invalidation, and propagate back  the invalidation in the NodeTable hierarchy. 

Another simpler fix is to propagate down the thread-safe storage "version" in 
the NodeTables, and check it in the cache, and evict.


*Workaround:* Skipping the cache (setting nodeToIdCacheSize and 
idToNodeCacheSize to -1 in StoreParams) is a good workaround now, but causes 
performance issues.

 



--
This message was sent by Atlassian Jira
(v8.3.2#803003)

Reply via email to