func (b *Rpdb) Reset() error { if err := b.acquire(); err != nil { return err } defer b.release() log.Infof("rpdb is reseting...") for i := b.splist.Len(); i != 0; i-- { v := b.splist.Remove(b.splist.Front()).(*RpdbSnapshot) v.Close() } for i := b.itlist.Len(); i != 0; i-- { v := b.itlist.Remove(b.itlist.Front()).(*rpdbIterator) v.Close() } if err := b.db.Clear(); err != nil { b.db.Close() b.db = nil log.ErrorErrorf(err, "rpdb reset failed") return err } else { b.serial++ log.Infof("rpdb is reset") return nil } }
func (b *Rpdb) compact(start, limit []byte) error { if err := b.db.Compact(start, limit); err != nil { log.ErrorErrorf(err, "rpdb compact failed") return err } else { return nil } }
func (b *Rpdb) migrateOne(addr string, timeout time.Duration, db uint32, key []byte) (int64, error) { n, err := b.migrate(addr, timeout, db, key) if err != nil { log.ErrorErrorf(err, "migrate one failed") return 0, err } return n, nil }
func (b *Rpdb) migrateTag(addr string, timeout time.Duration, db uint32, tag []byte) (int64, error) { keys, err := allKeysWithTag(b, db, tag) if err != nil || len(keys) == 0 { return 0, err } n, err := b.migrate(addr, timeout, db, keys...) if err != nil { log.ErrorErrorf(err, "migrate tag failed") return 0, err } return n, nil }
func main() { usage := ` Usage: rpdb [--config=CONF] [--create|--repair] [--ncpu=N] Options: -n N, --ncpu=N set runtime.GOMAXPROCS to N -c CONF, --config=CONF specify the config file --create create if not exists --repair repair database ` d, err := docopt.Parse(usage, nil, true, "", false) if err != nil { log.PanicErrorf(err, "parse arguments failed") } if s, ok := d["--ncpu"].(string); ok && len(s) != 0 { if n, err := strconv.ParseInt(s, 10, 64); err != nil { log.PanicErrorf(err, "parse --ncpu failed") } else if n <= 0 || n > 64 { log.Panicf("parse --ncpu = %d, only accept [1,64]", n) } else { runtime.GOMAXPROCS(int(n)) } } args.config, _ = d["--config"].(string) args.create, _ = d["--create"].(bool) args.repair, _ = d["--repair"].(bool) conf := &Config{ DBType: "rocksdb", DBPath: "testdb-rocksdb", LevelDB: leveldb.NewDefaultConfig(), RocksDB: rocksdb.NewDefaultConfig(), Service: service.NewDefaultConfig(), } if args.config != "" { if err := conf.LoadFromFile(args.config); err != nil { log.PanicErrorf(err, "load config failed") } } log.Infof("load config\n%s\n\n", conf) var db store.Database switch t := strings.ToLower(conf.DBType); t { default: log.Panicf("unknown db type = '%s'", conf.DBType) case "leveldb": db, err = leveldb.Open(conf.DBPath, conf.LevelDB, args.create, args.repair) case "rocksdb": db, err = rocksdb.Open(conf.DBPath, conf.RocksDB, args.create, args.repair) case "boltdb": db, err = boltdb.Open(conf.DBPath, conf.BoltDB, args.create, args.repair) } if err != nil { log.PanicErrorf(err, "open database failed") } bl := rpdb.New(db) defer bl.Close() if args.repair { return } c := make(chan os.Signal, 1) signal.Notify(c, os.Interrupt) go func() { for _ = range c { log.Infof("interrupt and shutdown") bl.Close() os.Exit(0) } }() if err := service.Serve(conf.Service, bl); err != nil { log.ErrorErrorf(err, "service failed") } }
func (h *Handler) doSyncTo(c *conn) error { defer func() { h.counters.syncTotalBytes.Set(0) h.counters.syncCacheBytes.Set(0) }() filePath := h.config.SyncFilePath fileSize := h.config.SyncFileSize buffSize := h.config.SyncBuffSize var file *os.File if filePath != "" { f, err := pipe.OpenFile(filePath, false) if err != nil { log.ErrorErrorf(err, "open pipe file '%s' failed", filePath) } else { file = f } } pr, pw := pipe.PipeFile(buffSize, fileSize, file) defer pr.Close() wg := &sync.WaitGroup{} defer wg.Wait() wg.Add(1) go func(r io.Reader) { defer wg.Done() defer pw.Close() p := make([]byte, 8192) for { deadline := time.Now().Add(time.Minute) if err := c.nc.SetReadDeadline(deadline); err != nil { pr.CloseWithError(errors.Trace(err)) return } n, err := r.Read(p) if err != nil { pr.CloseWithError(err) return } h.counters.syncTotalBytes.Add(int64(n)) s := p[:n] for len(s) != 0 { n, err := pw.Write(s) if err != nil { pr.CloseWithError(err) return } s = s[n:] } } }(c.r) wg.Add(1) go func() { defer wg.Done() for { time.Sleep(time.Millisecond * 200) n, err := pr.Buffered() if err != nil { return } h.counters.syncCacheBytes.Set(int64(n)) } }() c.r = bufio.NewReader(pr) size, err := c.presync() if err != nil { return err } log.Infof("sync rdb file size = %d bytes\n", size) c.w = bufio.NewWriter(ioutil.Discard) if err := c.Rpdb().Reset(); err != nil { return err } if err := h.doSyncRDB(c, size); err != nil { return err } log.Infof("sync rdb done") return c.serve(h) }