Replies: 3 comments 2 replies
-
I don't think wa-sqlite as-is has everything you need for SQLite WAL. First of all, right now wa-sqlite only supports sqlite3_io_methods version 1 when implementing a JavaScript VFS, which doesn't include the shared memory methods WAL needs. Enabling that support should be straightforward, but it's not in my own plans. The trickier problem is that WAL uses atomic load/store on shared memory without calling the VFS. It does this via macros that call intrinsic functions, directly on WASM memory. If you're planning on implementing the "shared memory" VFS methods by transferring data between WASM memory and a distinct SharedArrayBuffer, then you would to need to redefine these macros to operate on your SharedArrayBuffer. I think this is doable but not within the scope of wa-sqlite - you'll likely need your own custom SQLite build. A possible alternative to using a JavaScript VFS that stores files in a dedicated SharedArrayBuffer is to instantiate your entire WASM module into a SharedArrayBuffer using WebAssembly.Memory (so all your workers use the same WASM address space). Then you could write your VFS in C, which should be good for performance as it wouldn't need to cross the language boundary nearly as often. I have not tried running multiple Workers in the same address space like this, but my reading of the doc is that can be made to work with the right build options (both Emscripten and SQLite). I think you would still need to customize the atomic macros. If neither of those approaches is both workable and appealing, it is possible to implement something like WAL completely within a VFS. I see you tagged that post, so maybe you are considering or have already considered that. The details would be quite different with the "WAL" in a SharedArrayBuffer (instead of OPFS and IndexedDB) and using only synchronous APIs, but the basic idea would be the same. There's a good chance such a VFS could work with the stock wa-sqlite build. I don't know anything about WAL2 so I have nothing to offer there. |
Beta Was this translation helpful? Give feedback.
-
Separate sub-thread: How are you planning to implement checkpointing to persistent storage? I can think of a few ways:
|
Beta Was this translation helpful? Give feedback.
-
Thanks Roy, there is much to digest there and I need to read up a little more. Maybe the route here is to experiment first with a non-persisted shared memory VFS not using the WAL, keep it as simple as possible. That way it would be possible to learn more about locking (I hadn't considered a tab holding a lock when closing) and having a SharedArrayBuffer based VFS.
My (possibly naive) thinking was that as the VFS would know if a file is a main DB file or a journal/wal file, when it writes to the main file it multiplexes the write to both the in-memory file and the on disk file. So, hopefully it could just use SQLites own WAL checkpointing to update the pages on disk. You may be 10 steps ahead of me win your thinking though. |
Beta Was this translation helpful? Give feedback.
-
I've been thinking of trying to build a cross tab/worker in-memory VFS with persistence to OPFS. In essence:
PRAGMA journal_mode=WAL; PRAGMA wal_autocheckpoint=0;
If I'm not mistaken the only async call would be xOpen as it requires cross tab communication to retrieve the SharedArrayBuffer. However, that could be made sync if there was a preload function that the developer could call to preemptively load the database into memory in that worker. We then have a fully sync (when in a worker as we need Atomics.wait) VFS that could be used with the sync build of SQLite.
There are then a few extra things that could built on top of this:
BEGIN CONCURRENT
to have better concurrency. With the periodic checkpoints WAL2 should help.So, my question is, how crazy is this as an idea and do you think it could work?
Beta Was this translation helpful? Give feedback.
All reactions