Skip to content

Lmdb native txn isolation#5666

Draft
hmottestad wants to merge 12 commits intodevelopfrom
lmdb-native-txn-isolation
Draft

Lmdb native txn isolation#5666
hmottestad wants to merge 12 commits intodevelopfrom
lmdb-native-txn-isolation

Conversation

@hmottestad
Copy link
Contributor

GitHub issue resolved: #

Briefly describe the changes proposed in this PR:


PR Author Checklist (see the contributor guidelines for more details):

  • my pull request is self-contained
  • I've added tests for the changes I made
  • I've applied code formatting (you can use mvn process-resources to format from the command line)
  • I've squashed my commits where necessary
  • every commit message starts with the issue number (GH-xxxx) followed by a meaningful description of the change

@hmottestad hmottestad changed the base branch from main to develop January 3, 2026 23:09
@kenwenzel
Copy link
Contributor

@hmottestad How will you handle parallel writes from multiple threads? (I also thought about using native isolation but dropped it in favor of parallel write support.)

@hmottestad
Copy link
Contributor Author

@hmottestad How will you handle parallel writes from multiple threads? (I also thought about using native isolation but dropped it in favor of parallel write support.)

At the moment I've just been prompting Codex until all the tests have passed. Still one failing test though, which is a test with a lot of threads :(

What I wanted to know is if I can leverage the transaction isolation in LMDB to simplify the ID-based joins approach. Maybe it won't work, or maybe there is some in-between solution that I need. Not sure yet, just experimenting.

@kenwenzel
Copy link
Contributor

@hmottestad Something like a query-local ID service for values could maybe help here. If the value ID is already known within the underlying store then this ID is used, else a new ID is generated based on a query-local lookup table.

@hmottestad hmottestad force-pushed the lmdb-native-txn-isolation branch from 743699e to c79b203 Compare January 6, 2026 09:52
@hmottestad
Copy link
Contributor Author

hmottestad commented Jan 6, 2026

Running benchmarks with 4 threads

Develop branch

Benchmark                                                                     Mode  Cnt      Score      Error  Units
TransactionsPerSecondMultithreadedBenchmark.largerTransaction                thrpt    5      2.491 ±    1.094  ops/s
TransactionsPerSecondMultithreadedBenchmark.largerTransactionLevelNone       thrpt    5     29.195 ±    1.767  ops/s
TransactionsPerSecondMultithreadedBenchmark.mediumTransactionsLevelNone      thrpt    5   9039.738 ± 1237.084  ops/s
TransactionsPerSecondMultithreadedBenchmark.mediumTransactionsLevelSnapshot  thrpt    5  12037.565 ± 2148.435  ops/s
TransactionsPerSecondMultithreadedBenchmark.transactions                     thrpt    5  38075.516 ± 2348.471  ops/s
TransactionsPerSecondMultithreadedBenchmark.transactionsLevelNone            thrpt    5  29732.611 ± 2033.212  ops/s
TransactionsPerSecondMultithreadedBenchmark.veryLargerTransactionLevelNone   thrpt    5      0.428 ±    0.083  ops/s

I suspect that the TransactionsPerSecondMultithreadedBenchmark.largerTransaction benchmark causes a lot of GC when running with default transaction isolation, and that that's why it's so slow on develop. I'll try to verify that by increasing the memory and rerunning the benchmark.

Also noting that TransactionsPerSecondMultithreadedBenchmark.mediumTransactionsLevelSerializable is missing from the "develop" run. It's not actually the develop branch, just the first commit of the current branch. I know that RDF4J will throw exceptions when transactions violate SERIALIZABLE instead of retrying or attempting to interleave safely. So if I want the benchmark to be realistic I need to add retry logic to that benchmark method.

This branch

Benchmark                                                                         Mode  Cnt      Score      Error  Units
TransactionsPerSecondMultithreadedBenchmark.largerTransaction                    thrpt    5     16.203 ±    2.483  ops/s
TransactionsPerSecondMultithreadedBenchmark.largerTransactionLevelNone           thrpt    5     16.298 ±    0.978  ops/s
TransactionsPerSecondMultithreadedBenchmark.mediumTransactionsLevelNone          thrpt    5   7591.256 ±  628.834  ops/s
TransactionsPerSecondMultithreadedBenchmark.mediumTransactionsLevelSerializable  thrpt    5   7473.773 ± 1793.933  ops/s
TransactionsPerSecondMultithreadedBenchmark.mediumTransactionsLevelSnapshot      thrpt    5   7236.125 ± 1399.710  ops/s
TransactionsPerSecondMultithreadedBenchmark.transactions                         thrpt    5  26129.475 ± 7896.544  ops/s
TransactionsPerSecondMultithreadedBenchmark.transactionsLevelNone                thrpt    5  28859.452 ± 3009.007  ops/s
TransactionsPerSecondMultithreadedBenchmark.veryLargerTransactionLevelNone       thrpt    5      0.206 ±    0.162  ops/s

@hmottestad hmottestad force-pushed the lmdb-native-txn-isolation branch from c79b203 to d91f78f Compare January 6, 2026 21:21
@hmottestad
Copy link
Contributor Author

Obviously some correctness issues still, since the SHACL test is failing. That test relies heavily on the transaction isolation being correct and uses a lot of concurrent connections and multiple threads.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants