Syncthing SQLite rollout

So, the experiment has in my opinion turned out well and I think we should make it the database backend of the future.

However, I think we should release Syncthing-with-SQLite as Syncthing 2.0. The reason for this is more to do with deployment and building than it bringing amazing new user-facing features. To be clear, I do expect it to be more stable, more correct, and easier to debug, however I expect the rollout to be bumpy.

It’s a new way to build, with a new compiler in the mix. It’s an entirely new dependency for a critical part of the system. There’s a significant migration at startup, which takes up a significant amount of disk space and which can leave Syncthing in a bad state if it fails. We’ll probably break all the distribution packagers, and the Debian people will freak out about the bundled SQLite dependency and need ugly hacks to use dynamic linking to their packages etc.

All of this points to it not being a great idea to just roll it out to all users without saying anything, hence the 2.0. The new major version is significant in that the current auto upgrade code will not upgrade to it without prompting. So, I suggest;

  • We release a 2.0.0-rc. Nobody will get this automatically. We make a widespread request for help in testing it. Some users will test it, we’ll find and fix some bugs. Iterate for further rc:s as long as necessary.

  • We release a stable 2.0.0. Existing users will not be automatically upgraded to it. New users will get it from our download site. In our APT repo it stays in the “candidate” channel, or like a new “new” channel or whatever, as we cannot control auto upgrades with more granularity. We’ll get another, larger wave of “testers” and probably bug reports. Rinse and repeat. Some existing users will want to bring their existing setup up to the new hotness. People reporting weird out of sync issues will be pointed to upgrade, and we can see if it helps or not.

  • At some point we may feel that everyone should migrate and the old version be deprecated. We can drop a 1.50 or whatever that will auto upgrade to 2.0, and that is the stepping stone for users on autopilot.

Yeah?

To alleviate any possible doubt, the 2.0 version is and will be completely wire compatible with existing 1.x versions. I expect them to interoperate just as well as always, though of course the set of bugs will be the union of the two versions. :wink:

12 Likes

Sure sounds reasonable and well thought through.

One missing piece is feature development. E.g. we have the WebAuthn stuff in the pipeline (still), so I expect we will regularly merge the main branch into sqlite to pick up accumulated improvements.

And the new release will carry the migration code (thus LevelDB) for the foreseeable future? We should build in some features to avoid a footgun experience when someone switches back to an older version. Renaming the DB directory is a good step, but we need to make clear that simply putting the old DB back in place after a longer period with 2.0 experimentation will lead to possible data loss. Instead, it needs to be rebuilt from scratch.

And let’s please take our time to stabilize and review the new code. I took a very brief look, but intend to check much more in-depth before the 2.0.0 milestone goes live… :slight_smile:

1 Like

We’re going to hit Hyrum’s Law with the database location. I sense quite a few incoming bug reports because people went with custom docker mount points etc. Not that we could do anything about it, but it’s going to spawn a few support threads :slight_smile:

@bt90 I’m not sure what you mean, can you clarify?

@acolomb I don’t envision separate branches. Main will be main, new features will go into the new version, 1.x will stagnate.

I think the problem may be that some people store their databases in other locations (e.g. on a RAM disk), and they do it by pointing at the index-v0.14.0.db folder. If the name changes on upgrade (and also the type from directory to file), this may lead to unpredictable consequences.

I myself sync Syncthing home folders for backup purposes. For this reason, I’ve had index-v0.14.0.db in my ignore patterns since the very beginning. I’ve already changed the patterns to match also the new database name, but if I hadn’t, I would likely end up trying to sync the new database unwillingly.

My initial fear was that people might have just mounted the index-v0.14.0.db directory in their Docker container. But I checked my own installation and the fact that the parent directory contains important files like the certificate, this place should already be writable.

I’m not sure this is possible without introducing too much complexity, but one way of discovering issues like the ones mentioned would be to ‘dry run’ the migration in a first version (just build the sqlite file, then remove it and continue using the old database) on an opt-in basis (and/or only for those instances with usage reporting enabled). A somewhat commonly known example of this tactic is from Apple, who did this for their migration from HFS+ to APFS on iOS devices.

Speaking of iOS, there I am mostly worried about running out of disk space during the migration, or iOS interrupting the migration process at random times (or even the user by putting the device to sleep). These scenarios could happen outside of iOS as well and should be thought about (and possibly tested) carefully.

1 Like

In other words, this will stay on its PR branch until deemed ready for production. The moment we merge it, migration will be a prerequisite to enjoy any further feature enhancements or non-trivial fixes. Looking at the DB as a minor implementation detail warrants this, but the scary new major version may raise different expectations.

I just wish people had a choice for an extended period of time to hold off migrating until it stabilizes, but not causing the wait to block access to other developments. When they finally do decide to upgrade, the amount of changes might have accumulated unusually high by then.

Yeah, if you’ve done funny hacks you need to stay on top of the details. This is why it’s not an automatic upgrade, so everyone gets a chance to read release notes. A new major version should be a red flag for these people.

You make this sound like some sort of great hardship. In practice, we have almost no new features released for a very long time, any significant changes are probably by me anyway, and sure – if there’s a significant bugfix that needs to go out to existing users we can course make a release for them. However, I’m not going to maintain and release two separate branches of Syncthing for the foreseeable future to satsify a hypothetical. If you want this to stabilize quicker, why not help testing it. :slight_smile:

2 Likes

I do this myself with docker. I bind mount the config folder to get the configuration and keys someplace permanent. But I volume mount the database which makes it easy to blow away and rebuild and separates it from the backup path for my restic backups.

It’s an easy fix if the DB ends up in a separate place but yeah I will have to adjust my config.

Good release notes should solve this problem for anyone who took the time to setup a custom bind in the first place.

:grimacing: let’s hope that particular use case won’t be as necessary

1 Like

Someone should create a Hackernews post about the upcoming transition. Drop the claim that sqlite is slower than the old DB and half of HN will start investigating our schema and queries to proof us wrong. The cargo cult around sqlite on HN is on a different level :stuck_out_tongue_closed_eyes:

4 Likes

Oh god let’s not right now

2 Likes

Might as well post about rewriting in Rust :wink:

4 Likes

Suggest we check that db location has atleast 2x db size if free space before we even attempt the migration? Just outright fail otherwise.

5 Likes