In-memory database with persistence #189
rhashimoto
started this conversation in
Ideas
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
TL;DR IDBMirrorVFS is a new example VFS that keeps all SQLite files in memory while persisting to IndexedDB. It allows multiple concurrent readers with a writer (like WAL), and works on all contexts (Window, dedicated worker, shared worker, service worker). It is very fast, but is limited to databases that can fit into available memory.
One of the key tricks that OPFSPermutedVFS uses is to use BroadcastChannel to send write transaction information from the writing connection to all other connections (in addition to storing it in IndexedDB). I earlier noted that this could also be used to implement a smart page cache where only pages that were actually changed would be invalidated.
I did make a brief attempt to add such a smart cache to OPFSPermutedVFS, but it wasn't obvious how to test and demo it. The conditions to show it off require multiple connections and an access pattern that mainly read the unchanged parts of the database (which would still be in the cache). So I never finished it because I didn't have a ready way to see if and how well it worked.
Nevertheless, that is the basic idea behind the new example IDBMirrorVFS. It can be thought of as a VFS that keeps everything in cache. Changes to the database are broadcast and each connection updates its cache.
The advantages of this approach are speed and concurrency. Since everything is cached in memory, reads and writes are synchronous and fast. It also allows WAL-like synchronization, i.e. where read transactions don't need to sync with write transactions or each other. The disadvantage is that everything must fit into memory, so it can only accommodate databases up to a certain size (depending on browser limits and application memory usage), and opening a database requires reading the entire file.
This idea could be used with any browser storage but because its main feature is speed, it seemed like a good match for IndexedDB. Using IndexedDB for persistence means that the database can always be in the same context as the application code that needs it, unlike OPFS which only runs in a dedicated Worker, so messaging costs can be avoided.
Here are some performance comparisons with IDBBatchAtomicVFS using the contention demo (which mainly measures latency, not throughput). All runs use
PRAGMA synchronous=normal
to trade durability for performance.Here IDBMirrorVFS is vastly faster with a single reader:
Both allow concurrent readers, so IDBMirrorVFS extends its massive edge:
With a single writer, IDBMirrorVFS is still significantly faster but not nearly as much:
Writes are not concurrent (for either VFS):
Here a mix of 2 readers and 1 writer, where IDBMirrorVFS shows off its reader/writer concurrency:
In case you're interested here is OPFSPermutedVFS, the previous holder of the concurrency crown, with 2 readers and 1 writer:
Beta Was this translation helpful? Give feedback.
All reactions