go-sqlite3 Tightens Linux Temporary Database Handling

go-sqlite3 is a cgo free SQLite wrapper for Go that ships its own VFS layer. This week the project made a small but useful Linux temp database fix, plus a CI refresh that keeps the platform test surface honest.

Linux temp files move closer to SQLite intent

The important commit is Fix #380. The change moves unnamed file creation out of vfs/file.go and into an operating system helper. That is a better boundary for this code. SQLite temp database behavior depends on file system semantics, not only on Go file open flags.

On Linux, vfs/os_linux.go now tries O_TMPFILE before falling back to os.CreateTemp. That means an unnamed temp database can be backed by an anonymous inode when the file system supports it. There is no directory entry to race on or clean up. For data jobs that create many short lived SQLite databases, this is a quieter failure mode than create then unlink.

The helper still respects SQLITE_TMPDIR, then falls back to os.TempDir. It also retries on EINTR, and it leaves the older path in place when the kernel or file system does not support anonymous temp files. That fallback matters in container images, CI runners, and mounted volumes where Linux is present but not every mount behaves like a local ext4 or xfs path.

Shared memory is skipped for unnamed databases

The same commit also changes when shared memory is created. Before this patch, the VFS construction path always passed name.String()+"-shm" into NewSharedMemory. Since Filename.String() is empty for an unnamed database, that could build a shared memory path from an empty name. The new guard only creates shared memory when name.String() is not empty.

That is the right shape for a SQLite VFS. A WAL index file needs a stable file name that all connections can agree on. An unnamed temp database does not have that durable identity. Skipping shared memory in that case avoids pretending that a path exists when the real object is intentionally anonymous.

This is mostly internal plumbing, but it matters to pipeline code. Temporary SQLite databases show up in extract and transform stages because they are cheap local state. If a worker fails between tasks, operators want fewer leftover files and fewer surprise -shm artifacts in the current directory. This patch reduces that class of cleanup problem on Linux.

The portable fallback stays explicit

The project added vfs/os_std_temp.go for builds that are not covered by the Linux helper, or that use the sqlite3_flock build tag. That file keeps the simple os.CreateTemp behavior and removes the file immediately when OPEN_DELETEONCLOSE is set on Unix.

This split is useful because VFS code gets messy when platform choices are hidden in one large function. Linux can use O_TMPFILE. Other targets can keep the conservative path. The build tag makes that choice visible to maintainers and to anyone debugging a difference between a local Linux run and a BSD or macOS run.

There is also a subtle error mapping detail. Temp path creation failures now stay inside the helper and return _IOERR_GETTEMPPATH where appropriate. Named file errors still go through the normal EISDIR and read only directory checks in OpenFilename. That keeps the user facing error closer to the failing operation.

CI follows the platform surface

The second commit, CI, is not a feature change. It updates .github/workflows/test.yml so FreeBSD test jobs move from 15.0 to 15.1, and the cross platform action moves from v1.2.0 to v1.3.0.

For most libraries, that would be housekeeping. For this project, it is more important. The README calls out a wide platform matrix, and the VFS package contains separate behavior for Linux, Windows, BSD systems, illumos, and build tags such as sqlite3_flock. A temp file fix on Linux should not make maintainers less certain about BSD behavior.

The CI update also fits the nature of the code. File locks, WAL shared memory, temp files, and delete on close behavior are areas where tests on only one operating system can miss real defects. Keeping the runner versions fresh is a small cost compared with debugging a database file artifact that only appears on one platform family.

What to watch

First, watch for follow up around O_TMPFILE edge cases. Anonymous temp files depend on mount support, kernel support, and open flag details. The fallback path is present, but real deployments have varied temp directories.

Second, look at how this behaves in worker pools that use temp SQLite databases for batch transforms. The visible win should be less file system residue during normal operation and after failed jobs.

Third, treat this as a maintenance change, not a new API. No application code should need to change. The value is in making the existing VFS behavior match SQLite temp file expectations more closely on Linux.