Repository navigation
pkg/sorted: survey of the KeyValue backends #1832
Description
When this survey started, Perkeep had seven sorted.KeyValue implementations (plus an unused eighth), from a time when Go had few embedded or networked key/value options and we tried several. This issue surveys what each one is and its state today, so that follow-up changes (removing, fixing, or bringing a backend up to parity) can each make their own case and link here. As changes land, I'll check off the findings they resolve and list the changes at the bottom.
Backends
Line numbers are at f890de4.
| Backend (type) | Dependency | Optional interfaces | Tests | Config key | Notes |
|---|---|---|---|---|---|
sqlite |
modernc.org/sqlite v1.60.1 |
Wiper, TransactionalReader, Reindexer, NeedWipeError | pass | sqlite (the default) |
Batched reindex; rows stored WITHOUT ROWID (#1828). A single-slot gate serializes all access (sqlitekv.go:74) |
leveldb |
syndtr/goleveldb, 2021 pseudo-version (upstream's last commit is 2022-07) |
Wiper, TransactionalReader | pass | levelDB |
Writes with Sync: false (leveldb.go:81); also the fallback type for queues and caches (below) |
kv |
modernc.org/kv v1.0.6 |
Wiper | pass | kvIndexFile |
Deprecated in #1851; removal planned for no earlier than 2027-04-13 (#1850). app/publisher/main.go:393 hard-codes it for its thumbnail cachesorted.DefaultKVFileType) |
mysql |
go-sql-driver/mysql v1.9.2 |
Wiper, TransactionalReader | skipped | mysql |
Gate of 20, "arbitrary limit. TODO" (mysqlkv.go:91) |
postgres |
github.com/jackc/pgx/v5 v5.11.0 (lib/pq v1.10.9 |
Wiper (generic DELETE), TransactionalReader |
skipped | postgres |
Wipe TODO (sqlkv.go:330) |
mongo |
gopkg.in/mgo.v2, 2016 |
mongo |
Removed in #1835. CommitBatch isn't atomic (mongokv.go:183) |
||
memory |
github.com/google/btree v1.1.3 (already a perkeepd dependency, via tsnet) |
Wiper | pass | memoryIndex |
Reimplemented on google/btree in #1840; it no longer depends on goleveldb. Iterators read a copy-on-write snapshot, so they don't see writes made after Find |
buffer (pkg/sorted/buffer) |
Removed in #1836. |
Findings
- The DBMS backends get no test coverage. On a current Docker (containerd 2.1+), the MySQL, Postgres
and Mongotests, including all20_MySQL/_Postgres/index tests, are skipped. The pinned Postgres_Mongoand Mongotest images use a manifest format containerd no longer accepts, and with Docker 29, dockertest can't find the MySQL container's IP. Tracked in CI: test the MySQL and Postgres backends against real servers in GitHub Actions #1833; fixed by pkg/test/dockertest, .github: test MySQL and Postgres against real servers in CI #1837. - The Mongo backend can't talk to a current MongoDB. mgo's
socket.goonly writes opcodes 2001–2007 (OP_UPDATE, OP_INSERT, OP_QUERY, OP_GET_MORE, OP_DELETE, OP_KILL_CURSORS), never OP_MSG, and MongoDB 6.0 removed those opcodes (starting in 5.1). Removed in all: remove MongoDB support #1835. - Only SQLite has batched reindex (
sorted.Reindexer) and crash-safe detection of an interrupted reindex (NeedWipeError). - No caller uses
TransactionalReader, other thankvtest. - Every backend drops oversized writes. All of them (
sqlkvfor MySQL/Postgres/SQLite,leveldb,kv,memory, and SQLite's reindex session) checksorted.CheckSizes(MaxKeySize767,MaxValueSize63000, inherited from MySQL/InnoDB limits) and, for a write over the limit, log it and skip it:Setreturns nil and batches skip the mutation, so the caller never sees an error. See sorted: key of 1979 bytes too large #1812 for a case where this drops index rows. - Even with a DBMS index, some stores are leveldb files. With a local
blobPath, the thumbnail cache and cloud sync queues usekvFileType()(pkg/serverinit/genconfig.go:358), which falls back tosorted.DefaultKVFileType = "leveldb"(pkg/sorted/kv.go:35). diskpacked's default index type is also leveldb (diskpacked.go:109). - The docs don't help anyone choose.
doc/server-config.md:119just lists the options.:214still says SQLite is hard to get working on Windows because of mattn/go-sqlite3, though we use pure-Gomodernc.org/sqlitenow, and:232says Mongo is "not as well tested as the MySQL one".doc/status.md:30anddoc/overview.md:143still list App Engine. (docs mostly fixed in doc: update index backend guidance and Windows SQLite support #1842, except for helping users choose) - Other direct users:
cmd/pk-put's have/stat caches use goleveldb directly, notpkg/sorted(see cmd/pk: use sqlite for havecache? #1773 about moving the havecache to SQLite).cmd/pk dbinitsupports mysql, postgres and sqliteand mongo.dev/kvcopy(dev/kvcopy: add a tool to copy or dump sorted.KeyValue stores #1827) can copy any store into any other, which gives users of a backend that changes or goes away a migration path.
Changes
Each change that addresses a finding above should link this issue; I'll list it here and check off what it resolves.
- all: remove MongoDB support #1835: removed MongoDB support: the
mongoindex and blob storage, themongoconfig option,pk dbinit --dbtype=mongo, and thegopkg.in/mgo.v2dependency. - pkg/sorted: remove unused buffer package #1836: removed the unused
pkg/sorted/bufferpackage. - pkg/test/dockertest, .github: test MySQL and Postgres against real servers in CI #1837: MySQL and Postgres tests run against real servers in CI (CI: test the MySQL and Postgres backends against real servers in GitHub Actions #1833).
- pkg/sorted: implement the memory KeyValue with google/btree #1840: reimplemented the
memorybackend on google/btree, removing its dependency on goleveldb, and documented onFindthat an iterator may or may not observe writes made afterFindreturns (backends differ). - pkg/sorted/postgres, cmd/pk: use pgx instead of lib/pq #1843: switched the Postgres driver from
lib/pqtojackc/pgx/v5(via itsdatabase/sqladapter), for thepostgresindex,pk dbinitand dockertest. - pkg/sorted/kvfile: deprecate the "kv" sorted type #1851: deprecated the
kvsorted type and thekvIndexFileconfig field: opening a kv store logs a warning, kv is dropped from the docs and the suggested index options, and the publisher's thumbnail cache usessorted.DefaultKVFileTypeinstead of kv. Removal and migration withdev/kvcopyare tracked in pkg/sorted/kvfile: the "kv" sorted type is deprecated; removal no earlier than 2027-04-13 #1850.
Related: #126 and #46 (making the Mongo and Postgres indexers efficient), #790 and #1093 (LevelDB Sync and file descriptors), #258 (Postgres connection count), #523 (better pkg/sorted tests), #786 (a kv "unexpected EOF"), #1829 (startup performance).
Activity
all: remove MongoDB support
pkg/sorted: remove unused buffer package
go.mod: bump modernc.org/kv from v1.0.4 to v1.0.6
pkg/sorted: implement the memory KeyValue with google/btree
doc: update index backend guidance and Windows SQLite support
doc: update index backend guidance and Windows SQLite support
pkg/sorted/postgres, cmd/pk: use pgx instead of lib/pq
pkg/sorted/kvfile: deprecate the "kv" sorted type
pkg/sorted/kvfile: deprecate the "kv" sorted type
go.mod: update goleveldb to upstream HEAD
go.mod: update goleveldb to upstream HEAD