levedb 导入 mysql_如何查看leveldb的数据库内容

如何访问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

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值