←back to thread

Sqlite3 WebAssembly

(sqlite.org)
506 points whatever3 | 7 comments | | HN request time: 1.05s | source | bottom
Show context
koeng ◴[] No.41851815[source]
For use in Golang, I really like ncruces wasm SQLite package - https://github.com/ncruces/go-sqlite3 . Unlike cznic's go package (which is great, btw), the wasm version works well on OpenBSD and the like.
replies(1): >>41853244 #
1. ncruces ◴[] No.41853244[source]
Author here. If you're interested, do ask questions.
replies(2): >>41853458 #>>41855097 #
2. TN1ck ◴[] No.41853458[source]
Very cool project! Do you know if this would be possible for duckdb? Is there something about sqlites APIs and wasm build that made it feasible?

Context: Currently using go-duckdb and while it's working for us, getting rid of cgo would be a huge help. Would be quite interested myself to attempt this.

replies(1): >>41853561 #
3. ncruces ◴[] No.41853561[source]
I don't know much about DuckDB's architecture.

Wasm is fine for compute (though concurrency is still a somewhat open question).

To have Wasm talk to the outside world, you need “host calls” where the guest calls the host.

On a browser that's Wasm calling JavaScript. On my Go driver, it's Wasm calling Go.

For server side, there's also a standard set of “host calls” modeled around POSIX/Linux syscalls called WASI.

I could've build my project around WASI, but WASI is rather limited (and SQLite support for WASI was more limited even, it's improved a bit since). DuckDB might work out-of-the-box this way.

I, instead, took advantage of SQLite's architecture and replaced its VFS layer with one in Go: https://sqlite.org/vfs.html

So SQLite in Wasm is just doing compute, and I do all the OS level stuff in Go. No need for Wasm concurrency, cause I can load multiple instances of my Wasm which act like independent OS processes that communicate through the filesystem (SQLite excels at this).

As I said, I dunno how well all those decisions would map to DuckDB.

replies(1): >>41853953 #
4. koeng ◴[] No.41853953{3}[source]
> So SQLite in Wasm is just doing compute, and I do all the OS level stuff in Go. No need for Wasm concurrency, cause I can load multiple instances of my Wasm which act like independent OS processes that communicate through the filesystem (SQLite excels at this).

Interesting. So when I am running concurrent readers using your package, it is just loading multiple instances of the wasm code? (I bottleneck to a single writer in the application)

replies(1): >>41856932 #
5. infogulch ◴[] No.41855097[source]
Hey how's the mmap-based shared memory WAL approach working out? It's been about half a year since you finished the implementation and I only see one issue about it on the tracker, a good sign?
replies(1): >>41856487 #
6. ncruces ◴[] No.41856487[source]
It's turning out great, I guess.

The current approach is not portable to Windows, but it works fine on Linux, macOS, BSD and illumos. In general, portability is hindered more by file locking (I hate POSIX locks) than mmap.

The currently open GitHub issue is more bad default configuration than anything else. Configuring connections to use less memory by default should fix it.

I already have a PR ready for the next release that also opens this up for 32-bit platforms.

7. ncruces ◴[] No.41856932{4}[source]
Yes.

Each connection lives in its own isolated sandbox, and only communicates with other connections through the “file system” (which is a virtual abstraction, actually).

WAL mode is the “exception”: a few pages of the sandbox's memory are mapped to a file, and shared by all connections to the same database.

Each sandbox is single threaded, and mostly lock free, does all its business in the calling goroutine, and regularly checks back with the Go runtime to play nice with the Go scheduler.

It's a bit like an OS running multiple processes, with the VFS layer handling all syscalls.