appcore-sync-sqlite
English guide | Guia em português | Guide français
Optional post-1.0 SQLite persistence for AppCore synchronization state.
The crate implements the existing replication-log, outbox and checkpoint contracts. It also provides portable snapshots, bounded opaque tombstones, integrity inspection and verified online backup/restore. It never exposes a SQLite connection or accepts application SQL, tables, migrations or workflows.
Every database uses transactional internal schema V2, WAL, synchronous=FULL,
a bounded connection pool, busy timeout, SQLite runtime limits and startup
integrity validation. Unknown, unversioned and future schemas fail with
NO MORE SUPPORTED PLEASE UPDATE.
Schema V2 adds bounded attempt counters and readiness timestamps to the outbox.
peek and next_ready select count/byte metadata before reading BLOBs; stats
contain no payload and a partial receipt deletes only an exact ordered prefix
in one transaction. Enqueue measures the exact canonical JSON length first,
then writes directly to a zeroblob; duplicate comparison, page reads and
startup integrity validation also stream BLOB content. No encoded
record-sized Vec<u8> coexists with the owned message. The stream buffers use
the encoded record size up to fixed 64 KiB read and 1 MiB write ceilings, so a
small record never reserves either maximum. A known schema V1 database migrates
atomically with zeroed
retry metadata. Preserve a pre-migration backup for rollback.
Portable snapshot creation moves the payloads read from SQLite into the V1
snapshot. Restore validates the caller-owned snapshot by reference, checks its
aggregate payload against max_database_bytes before mutation and inserts
directly from those borrowed records in one transaction. No complete in-memory
replication log or second payload collection coexists with the snapshot.
The capability descriptor declares transactions, locking, snapshot,
online_backup and multi_process. It deliberately does not declare
streaming or multi_host.
This development crate is not selected by stable V1 manifests or by the SDK.
Direct consumers opt in explicitly. See
release/sqlite-sync-provider-v1.md.
Each pool connection and backup/restore auxiliary connection explicitly sets
and checks cache_size=-2048 and mmap_size=0. The cache setting is a suggested
2 MiB target, not a hard heap cap. Eight default pool connections imply about
16 MiB of cache targets before auxiliary connections, queries, temporary data,
WAL, payloads and allocator overhead. No process-global SQLite heap policy is
changed. Temporary storage and WAL growth still require deployment budgets.
See SQLite cache semantics.
Connections also request and verify temp_store=FILE before use, without
changing the process-global temporary directory. This is not a guarantee that
all temporary work goes to disk: SQLITE_TEMP_STORE=3 overrides the request
(the bundled Android build uses it). SQLite may also retain temporary pages
in cache. Deployments must inspect their build and budget private temporary
storage, memory and cleanup; memory-only builds need a separate memory budget.
See SQLite temporary storage.
WAL autocheckpoint at 1,000 pages is a trigger, not a disk-space cap. A held reader can prevent complete checkpointing while writers keep extending the WAL. An internal regression holds one read transaction across eight 1 MiB appends, observes more than 1,000 frames, then verifies truncation and intact records after releasing the reader and reopening. The test uses private SQL; it does not add a public checkpoint API. Bound readers/backups and monitor WAL and filesystem capacity in deployment; never delete a live WAL to reclaim space.
Replication-log pages now validate the aggregate length(payload) values
before converting any page BLOB into a Rust Vec. Count, metadata and payload
reads share one deferred transaction, so concurrent replacement cannot change
the admitted page between passes. An oversized selected page still fails as
a whole, preserving the existing contract. This adds a metadata pass and does
not bound SQLite's internal cache or provide streaming output.
Stable documentation
Stable ID: ACR-026. See the supplemental architecture and integration guide. This permanent ID remains valid if the wiki page moves.