losfair / mvsqlite

Distributed, MVCC SQLite that runs on FoundationDB.
https://github.com/losfair/mvsqlite/wiki
Apache License 2.0
1.36k stars 39 forks source link

Incorrect page-level conflict check logic in `commit()` #47

Closed losfair closed 1 year ago

losfair commented 1 year ago

This was fixed in https://github.com/losfair/mvsqlite/commit/365bb6be9b5f45474b1cc5476a4c940b82d777b2. Opened a issue just as a record of reasoning.

PLCC commit works in 4 steps:

  1. Check the existence of the requested page hashes.
  2. Read last-write-version, check for idempotent commits, and write a new last-write-version. This read is a snapshot read, because the transaction flow is not affected by the value.
  3. Read the current latest version of all the pages in the read set. If any of the versions are newer than client_assumed_version, it is a conflict.
  4. Write new hashes to the page index, and write a new changelog entry.

Previously, step 3 incorrectly only added a read conflict range on the current latest version itself. This only protects against truncate_namespace, but not a concurrent commit that adds a newer version of an overlapping page. The fix is to add a entire read conflict range of key..=range_end instead, so concurrent conflicting commits will abort our transaction.