Richard, Further experiments with snapshots reveal a behavior I did not expect.
My high-level goal is to *protect snapshots*: if a user of my SQLite wrapper GRDB.swift takes a snapshot, I want this snapshot to remain valid (usable without error) for the whole duration of its lifetime. During its lifetime, a snapshot will open transactions when it is used. But there are moments when a snapshot exists (has not been freed by sqlite3_snapshot_free()), but is not currently used by a transaction. I thus have to carefully manage checkpoints, so that they do not invalidate existing snapshots, even if they are not currently used in a transaction. I did attempt at protecting existing snapshots by opening a transaction and calling sqlite3_snapshot_open with the oldest open snapshot before calling sqlite3_wal_checkpoint_v2(). But this does not prevent snapshots from invalidation: 1. Create a snapshot with sqlite3_snapshot_get() 2. In connection A, open a deferred transaction, open the snapshot 3. In connection B, run the checkpoint (this fails with SQLITE_BUSY when checkpoint is RESTART OR TRUNCATE, as expected) 4. Close the transaction in connection A 5. In connection A, open a deferred transaction, open the snapshot, read, commit: success 6. In connection B, perform a write, commit: success 7. In connection A, open a deferred transaction, open the snapshot: SQLITE_ERROR (1), "not an error" Is the error at step 7 expected? On Fri, Sep 27, 2019 at 12:35 PM Richard Hipp <d...@sqlite.org> wrote: > On 9/26/19, Gwendal Roué <gwendal.r...@gmail.com> wrote: > > > > My question is: is it possible to prevent checkpoints from completing > > successfully when a snapshot is alive? > > > > That depends on what you mean by "alive"? > > An sqlite3_snapshot_get() simply records some numbers in private > memory of the database connection that called sqlite3_snapshot_get(). > There is no way for another process to know that those numbers have > been recorded, and hence no way to know that the snapshot exists, and > no way to prevent a checkpoint from happening. > > On the other hand, if you have run sqlite3_snapshot_open() so that > there is a transaction open on the snapshot, that takes locks on the > database which prevent checkpoints from running to completion and > erasing the snapshot. > > -- > D. Richard Hipp > d...@sqlite.org > _______________________________________________ > sqlite-users mailing list > sqlite-users@mailinglists.sqlite.org > http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users > _______________________________________________ sqlite-users mailing list sqlite-users@mailinglists.sqlite.org http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users