add option to migrate database in-place without copying

I originally didn't plan to include anything like this, but a few people
in #grapevine:computer.surgery pointed out use-cases where it might be
desirable:

 - a server that doesn't have enough room to store two full copies of
   the db. Transferring a copy over the network to back up is viable.
 - making a reflinked copy on a CoW filesystem (we could support this in
   the tool, but don't currently)
 - a server with some other backup mechanism available like snapshotting
   the entire filesystem
This commit is contained in:
Benjamin Lee 2024-09-14 01:41:04 -07:00
parent b93d4f471c
commit 3226d3a9eb
No known key found for this signature in database
GPG key ID: FB9624E2885D55A4
3 changed files with 55 additions and 7 deletions

View file

@ -96,12 +96,36 @@ pub(crate) struct MigrateDbArgs {
pub(crate) to: DbMigrationTarget,
/// Path to read database from.
#[clap(long = "in", short)]
pub(crate) in_path: PathBuf,
#[clap(long = "in", short, required_unless_present("inplace_path"))]
pub(crate) in_path: Option<PathBuf>,
/// Path to write migrated database to.
#[clap(long = "out", short)]
pub(crate) out_path: PathBuf,
#[clap(long = "out", short, required_unless_present("inplace_path"))]
pub(crate) out_path: Option<PathBuf>,
/// Path to modify an existing database in-place, instead of copying before
/// migrating.
///
/// Note that even a successful migration may lose data, because some parts
/// of the schema present in the initial database may not exist in the
/// target version. Because of this, it's very important to have a
/// backup of the initial database when migrating. The preferred way to
/// do this is with the --in and --out flags, which ensure that the
/// original database path is left unmodified. In some situations, it
/// may be possible to take a backup some other way (transferring it
/// over the network, for example), but copying the files locally is
/// undesirable. In this case, setting the --i-have-tested-my-backups
/// flag enables the use of --inplace to modify the database without
/// copying to a new location first.
#[clap(long = "inplace", conflicts_with_all(["in_path", "out_path"]))]
pub(crate) inplace_path: Option<PathBuf>,
/// Set if you have tested your backups, to enable use of the --inplace
/// flag.
///
/// See the documentation of --inplace for more details.
#[clap(long)]
pub(crate) i_have_tested_my_backups: bool,
}
#[derive(Clone, Debug, PartialEq, Eq)]