The Irreversible Schema Change

The Irreversible Schema Change

The config-sync changes involve what is labeled as an "irreversible schema change". (See check-in [1654456ef5aa8d].) Here is what that means:

The Fossil repository database schema has two components. The "persistent" schema contains source information and the "auxiliary" schema contains secondary information. The auxiliary schema is rebuilt from scratch from the source information whenever you run "fossil rebuild". So, in other words, the auxiliary schema does not contain any information that is not also inherent in the persistent schema - it merely expresses that information in a more convenient form.

Most schema changes involve changes to the auxiliary schema only. That means that if you upgrade to a newer version of Fossil that contains a schema change but later decide do not like the new version and want to revert back to an older version, you can. After reverting, simply run "fossil rebuild" again, which deletes all of the auxiliary schema tables and rebuilds them from scratch based on the persistent schema.

But the recent config-sync enhancement makes changes to the persistent schema, using ALTER TABLE statements. The config-sync enhancement adds an "mtime" column to all of the persistent tables that store server configuration data (things like USER, and REPORTFMT). The mtime field records the time that each row was last modified. Then when two repositories want to synchronize their configuration, they can take the most recent edits from each repository. The config-sync enhancement addresses (among other things) the problem of ticket [9b8333b29826deba].

When you upgrade to a version of Fossil that support config-sync, you have to run "fossil rebuild". And this rebuild uses ALTER TABLE to add the mtime column to various persistent tables (as well as make a few other minor tweaks). Because it uses ALTER TABLE on a primary data source, there is no way easy way to back out the schema change. Once you update to a version of Fossil that supports config-sync, you are mostly committed to staying with the later versions.

There is one escape route back to an older version of Fossil. You can run a newer Fossil in server mode on the converted database, then clone the repository using an older version of Fossil:

new-fossil server new-repo.fossil -localauth
old-fossil clone http://localhost:8080/ old-repo.fossil

One could probably also come up with an SQL script that would remove the "mtime" columns and other changes from the new schema as well, but that would be tricky and is not recommended.

About The Config-Sync Capability

The config-sync enhancement allows configuration changes on two different servers to be synchronized. For example, suppose Alice changes her password on server P and Bob changes his password on server Q. By running a "user" configuration sync between P and Q, Alice's password change would be copied from P to Q while Bob's change would be copied from Q to P. Prior to the config-sync change, one could copy the user password information from one repository to another, but you could not merge together changes made on separate repositories.

The config-sync enhancement also changes the protocol for sending configuration content from one repo to another. Formerly, many of the configuration changes were sent by shipping raw SQL statements over the wire. This was dangerous since it opened one up to SQL injection attacks if you sync with a compromised server and it was brittle since it assumed the exact same schema on both ends of the connection. A new protocol is now in place that does not use raw SQL and does not make unreasonable assumptions about the schemas.

The older configuration transfer protocol is retained for compatibility. The plan is to discontinue the older protocol after one year, after everyone has had plenty of time to upgrade. In the meantime, newer servers will automatically recognize that they are talking with older clients and will use the older protocol. Newer clients will not exchange configuration information with older servers, though, unless the --legacy option is included on the "fossil configuration pull" command-line. And even then, "shun" configuration information cannot be moved from older servers into newer clients - if you try the process will fail with a database error. Hence, the best strategy is to upgrade servers first, and then clients. Note that the 50 different Fossil repositories that are hosted on the server have all already been upgraded.