2024-05-27 17:46:15 +02:00
|
|
|
# Go SQLite VFS API
|
|
|
|
|
|
|
|
This package implements the SQLite [OS Interface](https://sqlite.org/vfs.html) (aka VFS).
|
|
|
|
|
|
|
|
It replaces the default SQLite VFS with a **pure Go** implementation,
|
|
|
|
and exposes [interfaces](https://pkg.go.dev/github.com/ncruces/go-sqlite3/vfs#VFS)
|
2024-10-25 18:09:18 +02:00
|
|
|
that should allow you to implement your own [custom VFSes](#custom-vfses).
|
2024-05-27 17:46:15 +02:00
|
|
|
|
|
|
|
Since it is a from scratch reimplementation,
|
|
|
|
there are naturally some ways it deviates from the original.
|
|
|
|
|
|
|
|
The main differences are [file locking](#file-locking) and [WAL mode](#write-ahead-logging) support.
|
|
|
|
|
|
|
|
### File Locking
|
|
|
|
|
|
|
|
POSIX advisory locks, which SQLite uses on Unix, are
|
|
|
|
[broken by design](https://github.com/sqlite/sqlite/blob/b74eb0/src/os_unix.c#L1073-L1161).
|
|
|
|
|
2024-10-25 18:09:18 +02:00
|
|
|
On Linux and macOS, this package uses
|
2024-05-27 17:46:15 +02:00
|
|
|
[OFD locks](https://www.gnu.org/software/libc/manual/html_node/Open-File-Description-Locks.html)
|
|
|
|
to synchronize access to database files.
|
|
|
|
OFD locks are fully compatible with POSIX advisory locks.
|
|
|
|
|
2024-10-25 18:09:18 +02:00
|
|
|
This package can also use
|
2024-05-27 17:46:15 +02:00
|
|
|
[BSD locks](https://man.freebsd.org/cgi/man.cgi?query=flock&sektion=2),
|
|
|
|
albeit with reduced concurrency (`BEGIN IMMEDIATE` behaves like `BEGIN EXCLUSIVE`).
|
|
|
|
On BSD, macOS, and illumos, BSD locks are fully compatible with POSIX advisory locks;
|
|
|
|
on Linux and z/OS, they are fully functional, but incompatible;
|
|
|
|
elsewhere, they are very likely broken.
|
|
|
|
BSD locks are the default on BSD and illumos,
|
|
|
|
but you can opt into them with the `sqlite3_flock` build tag.
|
|
|
|
|
2024-10-25 18:09:18 +02:00
|
|
|
On Windows, this package uses `LockFileEx` and `UnlockFileEx`,
|
2024-05-27 17:46:15 +02:00
|
|
|
like SQLite.
|
|
|
|
|
|
|
|
Otherwise, file locking is not supported, and you must use
|
|
|
|
[`nolock=1`](https://sqlite.org/uri.html#urinolock)
|
|
|
|
(or [`immutable=1`](https://sqlite.org/uri.html#uriimmutable))
|
|
|
|
to open database files.
|
|
|
|
To use the [`database/sql`](https://pkg.go.dev/database/sql) driver
|
|
|
|
with `nolock=1` you must disable connection pooling by calling
|
|
|
|
[`db.SetMaxOpenConns(1)`](https://pkg.go.dev/database/sql#DB.SetMaxOpenConns).
|
|
|
|
|
|
|
|
You can use [`vfs.SupportsFileLocking`](https://pkg.go.dev/github.com/ncruces/go-sqlite3/vfs#SupportsFileLocking)
|
|
|
|
to check if your build supports file locking.
|
|
|
|
|
|
|
|
### Write-Ahead Logging
|
|
|
|
|
2024-10-25 18:09:18 +02:00
|
|
|
On little-endian Unix, this package uses `mmap` to implement
|
2024-05-27 17:46:15 +02:00
|
|
|
[shared-memory for the WAL-index](https://sqlite.org/wal.html#implementation_of_shared_memory_for_the_wal_index),
|
|
|
|
like SQLite.
|
|
|
|
|
2024-06-07 15:06:43 +02:00
|
|
|
With [BSD locks](https://man.freebsd.org/cgi/man.cgi?query=flock&sektion=2)
|
|
|
|
a WAL database can only be accessed by a single proccess.
|
|
|
|
Other processes that attempt to access a database locked with BSD locks,
|
2024-10-25 18:09:18 +02:00
|
|
|
will fail with the [`SQLITE_PROTOCOL`](https://sqlite.org/rescode.html#protocol) error code.
|
2024-06-07 15:06:43 +02:00
|
|
|
|
2024-05-27 17:46:15 +02:00
|
|
|
Otherwise, [WAL support is limited](https://sqlite.org/wal.html#noshm),
|
|
|
|
and `EXCLUSIVE` locking mode must be set to create, read, and write WAL databases.
|
|
|
|
To use `EXCLUSIVE` locking mode with the
|
|
|
|
[`database/sql`](https://pkg.go.dev/database/sql) driver
|
|
|
|
you must disable connection pooling by calling
|
|
|
|
[`db.SetMaxOpenConns(1)`](https://pkg.go.dev/database/sql#DB.SetMaxOpenConns).
|
|
|
|
|
|
|
|
You can use [`vfs.SupportsSharedMemory`](https://pkg.go.dev/github.com/ncruces/go-sqlite3/vfs#SupportsSharedMemory)
|
|
|
|
to check if your build supports shared memory.
|
|
|
|
|
|
|
|
### Batch-Atomic Write
|
|
|
|
|
2024-10-25 18:09:18 +02:00
|
|
|
On 64-bit Linux, this package supports
|
|
|
|
[batch-atomic writes](https://sqlite.org/cgi/src/technote/714)
|
2024-05-27 17:46:15 +02:00
|
|
|
on the F2FS filesystem.
|
|
|
|
|
2024-10-25 18:09:18 +02:00
|
|
|
### Checksums
|
|
|
|
|
|
|
|
This package can be [configured](https://pkg.go.dev/github.com/ncruces/go-sqlite3#Conn.EnableChecksums)
|
|
|
|
to add an 8-byte checksum to the end of every page in an SQLite database.
|
|
|
|
The checksum is added as each page is written
|
|
|
|
and verified as each page is read.\
|
|
|
|
The checksum is intended to help detect database corruption
|
|
|
|
caused by random bit-flips in the mass storage device.
|
|
|
|
|
|
|
|
The implementation is compatible with SQLite's
|
|
|
|
[Checksum VFS Shim](https://sqlite.org/cksumvfs.html).
|
|
|
|
|
2024-05-27 17:46:15 +02:00
|
|
|
### Build Tags
|
|
|
|
|
|
|
|
The VFS can be customized with a few build tags:
|
|
|
|
- `sqlite3_flock` forces the use of BSD locks; it can be used on z/OS to enable locking,
|
|
|
|
and elsewhere to test BSD locks.
|
|
|
|
- `sqlite3_nosys` prevents importing [`x/sys`](https://pkg.go.dev/golang.org/x/sys);
|
|
|
|
disables locking _and_ shared memory on all platforms.
|
|
|
|
- `sqlite3_noshm` disables shared memory on all platforms.
|
|
|
|
|
|
|
|
> [!IMPORTANT]
|
2024-06-07 15:06:43 +02:00
|
|
|
> The default configuration of this package is compatible with the standard
|
|
|
|
> [Unix and Windows SQLite VFSes](https://sqlite.org/vfs.html#multiple_vfses);
|
|
|
|
> `sqlite3_flock` builds are compatible with the
|
|
|
|
> [`unix-flock` VFS](https://sqlite.org/compile.html#enable_locking_style).
|
|
|
|
> If incompatible file locking is used, accessing databases concurrently with
|
|
|
|
> _other_ SQLite libraries will eventually corrupt data.
|
2024-10-25 18:09:18 +02:00
|
|
|
|
|
|
|
### Custom VFSes
|
|
|
|
|
|
|
|
- [`github.com/ncruces/go-sqlite3/vfs/adiantum`](https://pkg.go.dev/github.com/ncruces/go-sqlite3/vfs/adiantum)
|
|
|
|
wraps a VFS to offer encryption at rest.
|
|
|
|
- [`github.com/ncruces/go-sqlite3/vfs/memdb`](https://pkg.go.dev/github.com/ncruces/go-sqlite3/vfs/memdb)
|
|
|
|
implements an in-memory VFS.
|
|
|
|
- [`github.com/ncruces/go-sqlite3/vfs/readervfs`](https://pkg.go.dev/github.com/ncruces/go-sqlite3/vfs/readervfs)
|
|
|
|
implements a VFS for immutable databases.
|
|
|
|
- [`github.com/ncruces/go-sqlite3/vfs/xts`](https://pkg.go.dev/github.com/ncruces/go-sqlite3/vfs/xts)
|
|
|
|
wraps a VFS to offer encryption at rest.
|