@@ -177,6 +177,9 @@ pub struct Server<C = HttpConnector, A = AddrIncoming, D = HttpsConnector<HttpCo
177177 pub connector : Option < D > ,
178178 pub migrate_bottomless : bool ,
179179 pub enable_deadlock_monitor : bool ,
180+ pub should_sync_from_storage : bool ,
181+ pub force_load_wals : bool ,
182+ pub sync_conccurency : usize ,
180183}
181184
182185impl < C , A , D > Default for Server < C , A , D > {
@@ -203,6 +206,9 @@ impl<C, A, D> Default for Server<C, A, D> {
203206 connector : None ,
204207 migrate_bottomless : false ,
205208 enable_deadlock_monitor : false ,
209+ should_sync_from_storage : false ,
210+ force_load_wals : false ,
211+ sync_conccurency : 8 ,
206212 }
207213 }
208214}
@@ -781,10 +787,10 @@ where
781787 tokio:: select! {
782788 _ = shutdown. notified( ) => {
783789 let shutdown = async {
790+ namespace_store. shutdown( ) . await ?;
784791 task_manager. shutdown( ) . await ?;
785792 // join_set.shutdown().await;
786793 service_shutdown. notify_waiters( ) ;
787- namespace_store. shutdown( ) . await ?;
788794
789795 Ok :: <_, crate :: Error >( ( ) )
790796 } ;
@@ -958,19 +964,30 @@ where
958964 Ok ( ( ) )
959965 } ) ;
960966
961- // If we have performed the migration, load all shared wals to force flush to storage with
962- // the new registry
963- if did_migrate {
967+ // If we performed a migration from bottomless to libsql-wal earlier, then we need to
968+ // forecefully load all the wals, to trigger segment storage with the actual storage. This
969+ // is because migration didn't actually send anything to storage, but just created the
970+ // segments.
971+ if did_migrate || self . should_sync_from_storage || self . force_load_wals {
972+ // eagerly load all namespaces, then call sync_all on the registry
973+ // TODO: do conccurently
964974 let dbs_path = base_config. base_path . join ( "dbs" ) ;
965975 let stream = meta_store. namespaces ( ) ;
966976 tokio:: pin!( stream) ;
967977 while let Some ( conf) = stream. next ( ) . await {
968978 let registry = registry. clone ( ) ;
969979 let namespace = conf. namespace ( ) . clone ( ) ;
970- let path = dbs_path. join ( namespace. as_str ( ) ) . join ( "data" ) ;
971- tokio:: task:: spawn_blocking ( move || registry. open ( & path, & namespace. into ( ) ) )
972- . await
973- . unwrap ( ) ?;
980+ let path = dbs_path. join ( namespace. as_str ( ) ) ;
981+ tokio:: fs:: create_dir_all ( & path) . await ?;
982+ tokio:: task:: spawn_blocking ( move || {
983+ registry. open ( & path. join ( "data" ) , & namespace. into ( ) )
984+ } )
985+ . await
986+ . unwrap ( ) ?;
987+ }
988+
989+ if self . should_sync_from_storage {
990+ registry. sync_all ( self . sync_conccurency ) . await ?;
974991 }
975992 }
976993
@@ -1236,31 +1253,31 @@ where
12361253 base_config : & BaseNamespaceConfig ,
12371254 primary_config : & PrimaryConfig ,
12381255 ) -> anyhow:: Result < bool > {
1239- let is_previous_migration_successful = self . check_previous_migration_success ( ) ?;
1240- let is_libsql_wal = matches ! ( self . use_custom_wal, Some ( CustomWAL :: LibsqlWal ) ) ;
1241- let is_bottomless_enabled = self . db_config . bottomless_replication . is_some ( ) ;
12421256 let is_primary = self . rpc_client_config . is_none ( ) ;
1243- let should_attempt_migration = self . migrate_bottomless
1244- && is_primary
1245- && is_bottomless_enabled
1246- && !is_previous_migration_successful
1247- && is_libsql_wal;
1248-
1249- if should_attempt_migration {
1250- bottomless_migrate ( meta_store, base_config. clone ( ) , primary_config. clone ( ) ) . await ?;
1251- Ok ( true )
1252- } else {
1253- // the wals directory is present and so is the _dbs. This means that a crash occured
1254- // before we could remove it. clean it up now. see code in `bottomless_migrate.rs`
1255- let tmp_dbs_path = base_config. base_path . join ( "_dbs" ) ;
1256- if tmp_dbs_path. try_exists ( ) ? {
1257- tracing:: info!( "removed dangling `_dbs` folder" ) ;
1258- tokio:: fs:: remove_dir_all ( & tmp_dbs_path) . await ?;
1259- }
1257+ if self . migrate_bottomless && is_primary {
1258+ let is_previous_migration_successful = self . check_previous_migration_success ( ) ?;
1259+ let is_libsql_wal = matches ! ( self . use_custom_wal, Some ( CustomWAL :: LibsqlWal ) ) ;
1260+ let is_bottomless_enabled = self . db_config . bottomless_replication . is_some ( ) ;
1261+ let should_attempt_migration =
1262+ is_bottomless_enabled && !is_previous_migration_successful && is_libsql_wal;
1263+
1264+ if should_attempt_migration {
1265+ bottomless_migrate ( meta_store, base_config. clone ( ) , primary_config. clone ( ) ) . await ?;
1266+ return Ok ( true ) ;
1267+ } else {
1268+ // the wals directory is present and so is the _dbs. This means that a crash occured
1269+ // before we could remove it. clean it up now. see code in `bottomless_migrate.rs`
1270+ let tmp_dbs_path = base_config. base_path . join ( "_dbs" ) ;
1271+ if tmp_dbs_path. try_exists ( ) ? {
1272+ tracing:: info!( "removed dangling `_dbs` folder" ) ;
1273+ tokio:: fs:: remove_dir_all ( & tmp_dbs_path) . await ?;
1274+ }
12601275
1261- tracing:: info!( "bottomless already migrated, skipping..." ) ;
1262- Ok ( false )
1276+ tracing:: info!( "bottomless already migrated, skipping..." ) ;
1277+ }
12631278 }
1279+
1280+ Ok ( false )
12641281 }
12651282
12661283 fn check_previous_migration_success ( & self ) -> anyhow:: Result < bool > {
0 commit comments