Skip to content

Commit a840d14

Browse files
LucioFrancohaaawk
authored andcommitted
server: flag to destroy metastore on restore err
This adds a new flag that when set to true will destroy the metastore and start with a fresh db file when restore runs into issues. This is a temp fix to for larger metastore restore issues that include disk malformed issues that we have seen.
1 parent bc00d3e commit a840d14

File tree

3 files changed

+63
-1
lines changed

3 files changed

+63
-1
lines changed

libsql-server/src/config.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,8 @@ pub struct HeartbeatConfig {
180180
pub struct MetaStoreConfig {
181181
pub bottomless: Option<BottomlessConfig>,
182182
pub allow_recover_from_fs: bool,
183+
/// Destroy the metastore if there is a restore error
184+
pub destroy_on_error: bool,
183185
}
184186

185187
#[derive(Debug, Clone)]

libsql-server/src/main.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,13 @@ struct Cli {
227227
#[clap(long, env = "SQLD_META_STORE_BUCKET_ENDPOINT")]
228228
meta_store_bucket_endpoint: Option<String>,
229229

230+
#[clap(
231+
long,
232+
env = "SQLD_META_STORE_DESTROY_ON_ERROR",
233+
default_value = "false"
234+
)]
235+
meta_store_destroy_on_error: bool,
236+
230237
/// encryption_key for encryption at rest
231238
#[clap(long, env = "SQLD_ENCRYPTION_KEY")]
232239
encryption_key: Option<bytes::Bytes>,
@@ -586,6 +593,7 @@ fn make_meta_store_config(config: &Cli) -> anyhow::Result<MetaStoreConfig> {
586593
Ok(MetaStoreConfig {
587594
bottomless,
588595
allow_recover_from_fs: config.allow_metastore_recovery,
596+
destroy_on_error: config.meta_store_destroy_on_error,
589597
})
590598
}
591599

libsql-server/src/namespace/meta_store.rs

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,7 @@ impl MetaStoreInner {
291291

292292
Err(e) => {
293293
tracing::error!("meta store restore failed: {}", e);
294+
294295
return Err(Error::from(e));
295296
}
296297
}
@@ -399,7 +400,58 @@ impl MetaStore {
399400
wal_manager: MetaStoreWalManager,
400401
) -> Result<Self> {
401402
let (changes_tx, mut changes_rx) = mpsc::channel(256);
402-
let inner = Arc::new(MetaStoreInner::new(base_path, conn, wal_manager, config).await?);
403+
404+
let destroy_on_error = config.destroy_on_error;
405+
406+
let inner = match MetaStoreInner::new(base_path, conn, wal_manager, config.clone()).await {
407+
Ok(inner) => inner,
408+
Err(e) => {
409+
if destroy_on_error {
410+
let db_path = base_path.join("metastore");
411+
412+
tracing::info!(
413+
"meta store set to destroy on restore error, removing metastore db path folder ({:?})", db_path
414+
);
415+
416+
if let Err(e) = std::fs::remove_dir_all(&db_path) {
417+
tracing::error!("failed to remove base path({:?}): {}", &db_path, e);
418+
}
419+
420+
if let Err(e) = std::fs::create_dir_all(&db_path) {
421+
tracing::error!(
422+
"failed to create meta store base path: {:?} with {}",
423+
&db_path,
424+
e
425+
);
426+
}
427+
428+
if let Err(e) = std::fs::File::create(db_path.join("data")) {
429+
tracing::error!(
430+
"failed to create `data` file in {:?} with: {}",
431+
&db_path,
432+
e
433+
);
434+
}
435+
436+
let (maker, wal) =
437+
metastore_connection_maker(config.bottomless.clone(), base_path).await?;
438+
439+
let conn = maker()?;
440+
441+
tracing::info!("recreating metastore and restoring with fresh data");
442+
443+
let inner = MetaStoreInner::new(base_path, conn, wal, config).await?;
444+
445+
tracing::info!("metastore destroy on error successful");
446+
447+
inner
448+
} else {
449+
return Err(e);
450+
}
451+
}
452+
};
453+
454+
let inner = Arc::new(inner);
403455

404456
tokio::spawn({
405457
let inner = inner.clone();

0 commit comments

Comments
 (0)