@@ -26,13 +26,26 @@ use crate::namespace::meta_store::{MetaStore, MetaStoreHandle};
2626use crate :: namespace:: NamespaceStore ;
2727
2828/// The process for migrating from bottomless to libsql wal is simple:
29- /// 1) iteratate over all namespaces, and make sure that they
29+ /// 1) iteratate over all namespaces, and make sure that they are up to date with bottomless by
30+ /// loading them
31+ /// 2) with a dummy registry, in a temp directory, with no storage, and no checkpointer, inject all the pages from the
32+ /// original db into a new temp db
33+ /// 3) when all namspace have been successfully migrated, make the dbs and wals folders permanent
3034pub async fn bottomless_migrate (
3135 meta_store : MetaStore ,
3236 base_config : BaseNamespaceConfig ,
3337 primary_config : PrimaryConfig ,
3438) -> anyhow:: Result < ( ) >
3539{
40+ let base_dbs_dir = base_config. base_path . join ( "dbs" ) ;
41+ let base_dbs_dir_tmp = base_config. base_path . join ( "_dbs" ) ;
42+ // the previous migration failed. The _dbs is still present, but the wals is not. In this case
43+ // we delete the current dbs if it exists and replace it with _dbs, and attempt migration again
44+ if base_dbs_dir_tmp. try_exists ( ) ? {
45+ tokio:: fs:: remove_dir_all ( & base_dbs_dir) . await ?;
46+ tokio:: fs:: rename ( & base_dbs_dir_tmp, & base_dbs_dir) . await ?;
47+ }
48+
3649 tracing:: info!( "attempting bottomless migration to libsql-wal" ) ;
3750
3851 let tmp = TempDir :: new ( ) ?;
@@ -90,11 +103,14 @@ pub async fn bottomless_migrate(
90103
91104 tmp_registry. shutdown ( ) . await ?;
92105
93- // FIXME: this is not atomic!!
94- tokio:: fs:: remove_dir_all ( base_config. base_path . join ( "dbs" ) ) . await ?;
95- tokio:: fs:: rename ( tmp. path ( ) . join ( "dbs" ) , base_config. base_path . join ( "dbs" ) ) . await ?;
106+ // unix prevents atomically renaming directories with mv, so we first rename dbs to _dbs, then
107+ // move the new dbs and wals, then remove old dbs.
108+ // when we perform a check form migration, whe verify if _dbs exists. If it exists, and wals
109+ // doesn't exist, then we restore it, otherwise, we delete it.
110+ tokio:: fs:: rename ( & base_dbs_dir, & base_dbs_dir_tmp) . await ?;
111+ tokio:: fs:: rename ( tmp. path ( ) . join ( "dbs" ) , base_dbs_dir) . await ?;
96112 tokio:: fs:: rename ( tmp. path ( ) . join ( "wals" ) , base_config. base_path . join ( "wals" ) ) . await ?;
97-
113+ tokio :: fs :: remove_dir_all ( base_config . base_path . join ( "_dbs" ) ) . await ? ;
98114
99115 Ok ( ( ) )
100116}
0 commit comments