From 24831f107c27e13405d9d62846b7c8d079651cf2 Mon Sep 17 00:00:00 2001 From: Boyu Yang Date: Tue, 9 Apr 2019 13:52:56 +0800 Subject: [PATCH] fix: try to repair a corrupted rocksdb automatically --- Cargo.lock | 1 + db/Cargo.toml | 1 + db/src/diskdb.rs | 17 ++++++++++++++++- 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index c245f47096..d495605010 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -431,6 +431,7 @@ dependencies = [ "ckb-util 0.9.0-pre", "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "rocksdb 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/db/Cargo.toml b/db/Cargo.toml index b3e845bf72..bfda8deb18 100644 --- a/db/Cargo.toml +++ b/db/Cargo.toml @@ -14,6 +14,7 @@ serde = "1.0" serde_derive = "1.0" serde_json = "1.0" failure = "0.1.5" +log = "0.4" [dev-dependencies] tempfile = "3.0" diff --git a/db/src/diskdb.rs b/db/src/diskdb.rs index 4990b1fd4b..0262c803cb 100644 --- a/db/src/diskdb.rs +++ b/db/src/diskdb.rs @@ -1,6 +1,7 @@ use crate::batch::{Batch, Col, Operation}; use crate::config::DBConfig; use crate::kvdb::{ErrorKind, KeyValueDB, Result}; +use log::warn; use rocksdb::{ColumnFamily, Options, WriteBatch, DB}; use std::ops::Range; @@ -21,7 +22,21 @@ impl RocksDB { let cfnames: Vec<_> = (0..columns).map(|c| format!("c{}", c)).collect(); let cf_options: Vec<&str> = cfnames.iter().map(|n| n as &str).collect(); - let db = DB::open_cf(&opts, &config.path, &cf_options).expect("Failed to open rocksdb"); + let db = DB::open_cf(&opts, &config.path, &cf_options).unwrap_or_else(|err| { + if err.as_ref().starts_with("Corruption:") { + warn!("Try repairing the rocksdb since {} ...", err); + let mut repair_opts = Options::default(); + repair_opts.create_if_missing(false); + repair_opts.create_missing_column_families(false); + DB::repair(repair_opts, &config.path) + .unwrap_or_else(|err| panic!("Failed to repair the rocksdb: {}", err)); + warn!("Try opening the repaired rocksdb ..."); + DB::open_cf(&opts, &config.path, &cf_options) + .unwrap_or_else(|err| panic!("Failed to open the repaired rocksdb: {}", err)) + } else { + panic!("Failed to open rocksdb: {}", err); + } + }); if let Some(db_opt) = config.options.as_ref() { let rocksdb_options: Vec<(&str, &str)> = db_opt