コード例 #1
0
ファイル: rpdb.go プロジェクト: fengshao0907/rpdb
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
	}
}
コード例 #2
0
ファイル: rpdb.go プロジェクト: fengshao0907/rpdb
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
	}
}
コード例 #3
0
ファイル: slots.go プロジェクト: fengshao0907/rpdb
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
}
コード例 #4
0
ファイル: slots.go プロジェクト: fengshao0907/rpdb
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
}
コード例 #5
0
ファイル: main.go プロジェクト: fengshao0907/rpdb
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")
	}
}
コード例 #6
0
ファイル: sync.go プロジェクト: fengshao0907/rpdb
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)
}