-
Notifications
You must be signed in to change notification settings - Fork 39
Caveats
This page documents various behaviors of mvSQLite that are a little different from SQLite. These differences do not cause correctness issues, but may confuse some applications a bit.
mvSQLite does not take locks on databases. Instead, it performs optimistic conflict checking at commit time. If a conflict is found, the "database is locked" error is returned from the COMMIT
statement. In that case the only reasonable thing to do is ROLLBACK
.
Some applications may retry failed COMMIT
without checking the error type. This will never succeed when running with mvSQLite.
In case of network errors and crashes, mvsqlite implements AA-style idempotency. Continuously retrying the same commit will keep returning the same successful result. But in case the global commit order is A-B-A, the second attempt of the A commit will conflict and fail.
This means that, in a very rare circumstance as described below:
mvstore crashed during commit, just between FDB commit success and returning the result to the client. Then, another client acquired the database lock, wrote to the database, and committed successfully. Now, the first client retries the commit.
The first client will get a commit conflict and abort. This is the expected behavior, since unbounded idempotency requires too much overhead.
Currently the max transaction size in mvsqlite is 50000 pages (~390MiB with 8KiB page size) and the time limit is 1 hour.
SQLite does synchronous "disk" I/O. While we can (and do) concurrently execute write operations, reads from FoundationDB block the SQLite thread.
This is probably fine if you don't expect to get very I/O intensive on a single database, but you may want to enable coroutine
in the IoEngine
config if you have an event loop outside, so that network I/O won't block the thread.