我们都知道,Hyperledger用的数据库是rocksDB,如果你不做修改的话,数据会存储在/var/hyperledger/production/db目录下。
现在我们来分析一下图中灰色部分的相关代码。
代码结构图如下
// 启动数据库, 初始化openchainDB实例并打开数据库.注意该方法不能保证正确行为的并发调用
func Start() {
openchainDB.open()
}
//
Open
打开已经存在于hyperledger中的数据库
func (openchainDB *OpenchainDB) open() {
dbPath := getDBPath()
missing, err := dirMissingOrEmpty(dbPath)
if err != nil {
panic(fmt.Sprintf("Error while trying to open DB: %s", err))
}
dbLogger.Debugf("Is db path [%s] empty [%t]", dbPath, missing)
if missing {
err = os.MkdirAll(path.Dir(dbPath), 0755)
if err != nil {
panic(fmt.Sprintf("Error making directory path [%s]: %s", dbPath, err))
}
}
opts := gorocksdb.NewDefaultOptions()
defer opts.Destroy()
maxLogFileSize := viper.GetInt("peer.db.maxLogFileSize")
if maxLogFileSize > 0 {
dbLogger.Infof("Setting rocksdb maxLogFileSize to %d", maxLogFileSize)
opts.SetMaxLogFileSize(maxLogFileSize)
}
keepLogFileNum := viper.GetInt("peer.db.keepLogFileNum")
if keepLogFileNum > 0 {
dbLogger.Infof("Setting rocksdb keepLogFileNum to %d", keepLogFileNum)
opts.SetKeepLogFileNum(keepLogFileNum)
}
logLevelStr := viper.GetString("peer.db.loglevel")
logLevel, ok := rocksDBLogLevelMap[logLevelStr]
if ok {
dbLogger.Infof("Setting rocks db InfoLogLevel to %d", logLevel)
opts.SetInfoLogLevel(logLevel)
}
opts.SetCreateIfMissing(missing)
opts.SetCreateIfMissingColumnFamilies(true)
cfNames := []string{"default"}
cfNames = append(cfNames, columnfamilies...)
var cfOpts []*gorocksdb.Options
for range cfNames {
cfOpts = append(cfOpts, opts)
}
db, cfHandlers, err := gorocksdb.OpenDbColumnFamilies(opts, dbPath, cfNames, cfOpts)
if err != nil {
panic(fmt.Sprintf("Error opening DB: %s", err))
}
openchainDB.DB = db
openchainDB.BlockchainCF = cfHandlers[1]
openchainDB.StateCF = cfHandlers[2]
openchainDB.StateDeltaCF = cfHandlers[3]
openchainDB.IndexesCF = cfHandlers[4]
openchainDB.PersistCF = cfHandlers[5]
}
//
NewDefaultOptions
创建一个默认的Options.
func NewDefaultOptions() *Options {
return NewNativeOptions(C.rocksdb_options_create())
} // Options表示当以open形式打开一个数据库时所有可选的options// NewNativeOptions 创建一个Options对象.type Options struct {c *C.rocksdb_options_t// 保持引用GC.env *Envbbto *BlockBasedTableOptions// 在Destroy的时候我们要保证能够释放他们的内存ccmp *C.rocksdb_comparator_tcmo *C.rocksdb_mergeoperator_tcst *C.rocksdb_slicetransform_tccf *C.rocksdb_compactionfilter_t}
// NewDefaultOptions 创建一个默认的Options.func NewDefaultOptions() *Options {return NewNativeOptions(C.rocksdb_options_create())}
// NewNativeOptions 创建一个Options对象.func NewNativeOptions(c *C.rocksdb_options_t) *Options {return &Options{c: c}}
func NewNativeOptions(c *C.rocksdb_options_t) *Options {
return &Options{c: c}
}
//
Options表示当以open形式打开一个数据库时所有可选的options
type Options struct {
c *C.rocksdb_options_t
// 保持引用GC.
env *Env
bbto *BlockBasedTableOptions
// 在Destroy的时候我们要保证能够释放他们的内存
ccmp *C.rocksdb_comparator_t
cmo *C.rocksdb_mergeoperator_t
cst *C.rocksdb_slicetransform_t
ccf *C.rocksdb_compactionfilter_t
}
//
SetMaxLogFileSize
设置信息日志文件的最大尺寸
// 如果日志文件大于max_log_file_size常量,新的日志将会被创建
// 如果max_log_file_size等于0,所有的日志都被写到一个log日志
// 默认大小:0
func (opts *Options) SetMaxLogFileSize(value int) {
C.rocksdb_options_set_max_log_file_size(opts.c, C.size_t(value))
}
//
SetKeepLogFileNum
设置保存的最大日志信息文件
// 默认大小: 1000
func (opts *Options) SetKeepLogFileNum(value int) {
C.rocksdb_options_set_keep_log_file_num(opts.c, C.size_t(value))
}
//
SetInfoLogLevel
设置日志信息的级别.
// 默认级别: InfoInfoLogLevel
func (opts *Options) SetInfoLogLevel(value InfoLogLevel) {
C.rocksdb_options_set_info_log_level(opts.c, C.int(value))
}
//
InfoLogLevel描述日志级别.
type InfoLogLevel uint
// 日志级别.
const (
DebugInfoLogLevel = InfoLogLevel(0)
InfoInfoLogLevel = InfoLogLevel(1)
WarnInfoLogLevel = InfoLogLevel(2)
ErrorInfoLogLevel = InfoLogLevel(3)
FatalInfoLogLevel = InfoLogLevel(4)
)
//
SetCreateIfMissing
如果数据库丢失了指定数据库是不是应该被创建
// 默认值: false
func (opts *Options) SetCreateIfMissing(value bool) {
C.rocksdb_options_set_create_if_missing(opts.c, boolToChar(value))
}
//
SetCreateIfMissingColumnFamilies
如果指定的列丢失啦是不是应该被创建
func (opts *Options) SetCreateIfMissingColumnFamilies(value bool) {
C.rocksdb_options_set_create_missing_column_families(opts.c, boolToChar(value))
}
//
打开列家族
db, cfHandlers, err := gorocksdb.OpenDbColumnFamilies(opts, dbPath, cfNames, cfOpts)