// Open creates options and opens the database. If the database // doesn't yet exist at the specified directory, one is initialized // from scratch. The RocksDB Open and Close methods are reference // counted such that subsequent Open calls to an already opened // RocksDB instance only bump the reference count. The RocksDB is only // closed when a sufficient number of Close calls are performed to // bring the reference count down to 0. func (r *RocksDB) Open() error { if r.rdb != nil { return nil } if r.memtableBudget < minMemtableBudget { return util.Errorf("memtable budget must be at least %s: %s", humanize.IBytes(minMemtableBudget), humanizeutil.IBytes(r.memtableBudget)) } var ver storageVersion if len(r.dir) != 0 { log.Infof("opening rocksdb instance at %q", r.dir) // Check the version number. var err error if ver, err = getVersion(r.dir); err != nil { return err } if ver < versionMinimum || ver > versionCurrent { // Instead of an error, we should call a migration if possible when // one is needed immediately following the DBOpen call. return fmt.Errorf("incompatible rocksdb data version, current:%d, on disk:%d, minimum:%d", versionCurrent, ver, versionMinimum) } } else { log.Infof("opening in memory rocksdb instance") // In memory dbs are always current. ver = versionCurrent } status := C.DBOpen(&r.rdb, goToCSlice([]byte(r.dir)), C.DBOptions{ cache_size: C.uint64_t(r.cacheSize), memtable_budget: C.uint64_t(r.memtableBudget), block_size: C.uint64_t(envutil.EnvOrDefaultBytes("rocksdb_block_size", defaultBlockSize)), wal_ttl_seconds: C.uint64_t(envutil.EnvOrDefaultDuration("rocksdb_wal_ttl", 0).Seconds()), allow_os_buffer: C.bool(true), logging_enabled: C.bool(log.V(3)), }) if err := statusToError(status); err != nil { return util.Errorf("could not open rocksdb instance: %s", err) } // Update or add the version file if needed. if ver < versionCurrent { if err := writeVersionFile(r.dir); err != nil { return err } } // Start a goroutine that will finish when the underlying handle // is deallocated. This is used to check a leak in tests. go func() { <-r.deallocated }() r.stopper.AddCloser(r) return nil }
// newBookie creates a reservations system and starts its timeout queue. func newBookie( clock *hlc.Clock, stopper *stop.Stopper, metrics *storeMetrics, reservationTimeout time.Duration, ) *bookie { b := &bookie{ clock: clock, metrics: metrics, reservationTimeout: reservationTimeout, maxReservations: envutil.EnvOrDefaultInt("max_reservations", defaultMaxReservations), maxReservedBytes: envutil.EnvOrDefaultBytes("max_reserved_bytes", defaultMaxReservedBytes), } b.mu.reservationsByRangeID = make(map[roachpb.RangeID]*reservation) b.start(stopper) return b }