美文网首页Fabric操作用例Go
如何查看leveldb的数据库内容

如何查看leveldb的数据库内容

作者: CodingCode | 来源:发表于2018-08-20 16:33 被阅读909次

    如何访问leveldb的数据库内容

    当fabric的状态数据库设置为leveldb的时候(也是缺省设置),那么状态数据是存储在leveldb里面的;本文给出一个简单go语言例子,直接读取leveldb的内容。

    在peer容器里面leveldb的缺省存着路径是

    /var/hyperledger/production/ledgersData/stateLeveldb
    

    包含下面类似内容:

    $ ls -l
    -rw-r--r-- 1 root root 5122 Aug 20 15:03 000006.log
    -rw-r--r-- 1 root root   16 Aug 20 14:56 CURRENT
    -rw-r--r-- 1 root root    0 Aug 20 14:45 LOCK
    -rw-r--r-- 1 root root 1842 Aug 20 14:56 LOG
    -rw-r--r-- 1 root root   41 Aug 20 14:56 MANIFEST-000007
    

    第一步:准备leveldb第三方库
    可以直接从官网下载

    $ go get github.com/syndtr/goleveldb/leveldb
    

    或者不下载直接引用fabric里面的库也可以,因为fabric包里面已经嵌入了。
    路径在:fabric/vendor/github.com/syndtr/goleveldb/leveldb

    第二步,编写测试程序如下

    $ cat main.go 
    package main
    
    import (
        "fmt"
        "flag"
        "bytes"
        "strings"
    
        "github.com/syndtr/goleveldb/leveldb"
    )
    
    var (
        channel     string
        chaincode   string
        key         string
    
        dbpath      string
    )
    
    func init() {
        flag.StringVar(&channel,   "channel",   "mychannel",    "Channel name")
        flag.StringVar(&chaincode, "chaincode", "mychaincode",  "Chaincode name")
        flag.StringVar(&key,       "key",       "",             "Key to query; empty query all keys")
    
        flag.StringVar(&dbpath,    "dbpath",   "",              "Path to LevelDB")
    }
    
    func readKey(db *leveldb.DB, key string) {
        var b bytes.Buffer
        b.WriteString(channel)
        b.WriteByte(0)
        b.WriteString(chaincode)
        b.WriteByte(0)
        b.WriteString(key)
    
        value, err := db.Get(b.Bytes(), nil)
        if err != nil {
            fmt.Printf("ERROR: cannot read key[%s], error=[%v]\n", key, err)
            return
        }
        fmt.Printf("Key[%s]=[%s]\n", key, string(value))
    }
    
    func readAll(db *leveldb.DB) {
        var b bytes.Buffer
        b.WriteString(channel)
        b.WriteByte(0)
        b.WriteString(chaincode)
        prefix := b.String()
    
        iter := db.NewIterator(nil, nil)
        for iter.Next() {
            key   := string(iter.Key())
            if strings.HasPrefix(key, prefix) {
                value := string(iter.Value())
                fmt.Printf("Key[%s]=[%s]\n", key, value);
            }
        }
        iter.Release()
        //err := iter.Error()
    }
    
    func main() {
        flag.Parse()
        if channel == "" || chaincode== "" || dbpath  == "" {
            fmt.Printf("ERROR: Neither of channel, chaincode, key nor dbpath could be empty\n")
            return
        }
    
        db, err := leveldb.OpenFile(dbpath, nil)
        if err != nil {
            fmt.Printf("ERROR: Cannot open LevelDB from [%s], with error=[%v]\n", dbpath, err);
        }
        defer db.Close()
    
        if key == "" {
            readAll(db)
        } else {
            readKey(db, key)
        }
    }
    

    这个代码例子给出了一个读取单个key,和遍历所有key的例子:
    以sample02为例子,如果输入key=a,那么返回a的值,如果没有输入key,那么返回所有的key,在我们例子中只有有a和b两个key。

    $  ./testleveldb -key a -dbpath /var/hyperledger/production/ledgersData/stateLeveldb
    Key[a]=[��1001]
    
    $ ./testleveldb -dbpath /var/hyperledger/production/ledgersData/stateLeveldb
    Key[mychannelmychaincodea]=[��1001]
    Key[mychannelmychaincodeb]=[��1999]
    

    多说两句:
    我们看到value的值有乱码"��1001",其中1001是值,前面的乱码用在其他用处,例如版本信息等;因为我们使用leveldb的原始工具查询出来的是原始值,而fabric内部是有完整的数据结构类型定义来描述value或者key字段的每一个字节的含义。
    从代码里我们也看到key的值实际是由channel+'\0'+chaincode+'\0'+key组成。

    另外整个数据库还有其他的信息,不止是用户数据,还有metadata数据。我们遍历的时候,如果打印出所有的key,会看到:

    key=[mychannel]
    key=[mychannelresourcesconfigtx.CHANNEL_CONFIG_KEY]
    key=[mychannellsccmychaincode]
    key=[mychannelmychaincodea]
    key=[mychannelmychaincodeb]
    

    有包含channel的metadata信息,以及chaincode的metadata信息。(注意虽然我们看到的都是字符串,实际上他们都包含不可显示的字符的)

    附录:LevelDB的修改和删除

    
    func DBPutKey(db *leveldb.DB, key string, value []byte) error {
        var k bytes.Buffer
        k.WriteString(key)
    
        err := db.Put(k.Bytes(), value, nil)
        if err != nil {
            return err
        }
        return nil
    }
    
    func DBDelKey(db *leveldb.DB, key string) error {
        var k bytes.Buffer
        k.WriteString(key)
    
        err := db.Delete(k.Bytes(), nil)
        if err != nil {
            return err
        }
        return nil
    }
    

    相关文章

      网友评论

        本文标题:如何查看leveldb的数据库内容

        本文链接:https://www.haomeiwen.com/subject/nfyliftx.html