From 9d8c045ca0814eabe108540592220a36ea32f761 Mon Sep 17 00:00:00 2001 From: siddontang Date: Thu, 26 Jun 2014 11:04:54 +0800 Subject: [PATCH] add repair support --- cmd/ledis-repair/main.go | 41 ++++++++++++++++++++++++++++++ leveldb/db.go | 55 ++++++++++++++++++++++++++++++---------- 2 files changed, 82 insertions(+), 14 deletions(-) create mode 100644 cmd/ledis-repair/main.go diff --git a/cmd/ledis-repair/main.go b/cmd/ledis-repair/main.go new file mode 100644 index 0000000..71e65c3 --- /dev/null +++ b/cmd/ledis-repair/main.go @@ -0,0 +1,41 @@ +package main + +import ( + "encoding/json" + "flag" + "github.com/siddontang/ledisdb/ledis" + "github.com/siddontang/ledisdb/leveldb" + "io/ioutil" + "path" +) + +var fileName = flag.String("config", "/etc/ledis.config", "ledisdb config file") + +func main() { + flag.Parse() + + data, err := ioutil.ReadFile(fileName) + if err != nil { + println(err.Error()) + return + } + + var cfg ledis.Config + if err = json.Unmarshal(data, &cfg); err != nil { + println(err.Error()) + return + } + + if len(cfg.DataDir) == 0 { + println("must set data dir") + return + } + + if len(cfg.DataDB.Path) == 0 { + cfg.DataDB.Path = path.Join(cfg.DataDir, "data") + } + + if err = leveldb.Repair(&cfg.DataDB); err != nil { + println("repair error: ", err.Error()) + } +} diff --git a/leveldb/db.go b/leveldb/db.go index eb68d5a..7efed06 100644 --- a/leveldb/db.go +++ b/leveldb/db.go @@ -69,16 +69,7 @@ func OpenWithConfig(cfg *Config) (*DB, error) { } func (db *DB) open() error { - db.opts = db.initOptions(db.cfg) - - db.readOpts = NewReadOptions() - db.writeOpts = NewWriteOptions() - - db.iteratorOpts = NewReadOptions() - db.iteratorOpts.SetFillCache(false) - - db.syncWriteOpts = NewWriteOptions() - db.syncWriteOpts.SetSync(true) + db.initOptions(db.cfg) var errStr *C.char ldbname := C.CString(db.cfg.Path) @@ -86,12 +77,37 @@ func (db *DB) open() error { db.db = C.leveldb_open(db.opts.Opt, ldbname, &errStr) if errStr != nil { + db.db = nil return saveError(errStr) } return nil } -func (db *DB) initOptions(cfg *Config) *Options { +func Repair(cfg *Config) error { + db := new(DB) + db.cfg = cfg + + err := db.open() + + db.Close() + + //open ok, do not need repair + if err == nil { + return nil + } + + var errStr *C.char + ldbname := C.CString(db.cfg.Path) + defer C.leveldb_free(unsafe.Pointer(ldbname)) + + C.leveldb_repair_db(db.opts.Opt, ldbname, &errStr) + if errStr != nil { + return saveError(errStr) + } + return nil +} + +func (db *DB) initOptions(cfg *Config) { opts := NewOptions() opts.SetCreateIfMissing(true) @@ -129,12 +145,23 @@ func (db *DB) initOptions(cfg *Config) *Options { opts.SetMaxOpenFiles(cfg.MaxOpenFiles) - return opts + db.opts = opts + + db.readOpts = NewReadOptions() + db.writeOpts = NewWriteOptions() + + db.iteratorOpts = NewReadOptions() + db.iteratorOpts.SetFillCache(false) + + db.syncWriteOpts = NewWriteOptions() + db.syncWriteOpts.SetSync(true) } func (db *DB) Close() { - C.leveldb_close(db.db) - db.db = nil + if db.db != nil { + C.leveldb_close(db.db) + db.db = nil + } db.opts.Close()