新聞中心
本篇內(nèi)容介紹了“Bytom持久化存儲(chǔ)LevelDB有哪些操作”的有關(guān)知識(shí),在實(shí)際案例的操作過程中,不少人都會(huì)遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
成都創(chuàng)新互聯(lián)公司是專業(yè)的昭蘇網(wǎng)站建設(shè)公司,昭蘇接單;提供成都網(wǎng)站制作、做網(wǎng)站、外貿(mào)營銷網(wǎng)站建設(shè),網(wǎng)頁設(shè)計(jì),網(wǎng)站設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行昭蘇網(wǎng)站開發(fā)網(wǎng)頁制作和功能擴(kuò)展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來合作!
LevelDB介紹
比原鏈默認(rèn)使用leveldb數(shù)據(jù)庫。Leveldb是一個(gè)google實(shí)現(xiàn)的非常高效的kv數(shù)據(jù)庫。LevelDB是單進(jìn)程的服務(wù),性能非常之高,在一臺(tái)4核Q6600的CPU機(jī)器上,每秒鐘寫數(shù)據(jù)超過40w,而隨機(jī)讀的性能每秒鐘超過10w。 由于Leveldb是單進(jìn)程服務(wù),不能同時(shí)有多個(gè)進(jìn)程進(jìn)行對(duì)一個(gè)數(shù)據(jù)庫進(jìn)行讀寫。同一時(shí)間只能有一個(gè)進(jìn)程,或一個(gè)進(jìn)程多并發(fā)的方式進(jìn)行讀寫。 比原鏈在數(shù)據(jù)存儲(chǔ)層上存儲(chǔ)所有鏈上地址、資產(chǎn)交易等信息。
LevelDB的增刪改查操作
LevelDB是google開發(fā)的一個(gè)高性能K/V存儲(chǔ),本節(jié)我們介紹下LevelDB如何對(duì)LevelDB增刪改查。
package main import ( "fmt" dbm "github.com/tendermint/tmlibs/db" ) var ( Key = "TESTKEY" LevelDBDir = "/tmp/data" ) func main() { db := dbm.NewDB("test", "leveldb", LevelDBDir) defer db.Close() db.Set([]byte(Key), []byte("This is a test.")) value := db.Get([]byte(Key)) if value == nil { return } fmt.Printf("key:%v, value:%v\n", Key, string(value)) db.Delete([]byte(Key)) } // Output // key:TESTKEY, value:This is a test.
以上Output是執(zhí)行該程序得到的輸出結(jié)果。
該程序?qū)eveld進(jìn)行了增刪改查操作。dbm.NewDB得到db對(duì)象,在/tmp/data目錄下會(huì)生成一個(gè)叫test.db的目錄。該目錄存放該數(shù)據(jù)庫的所有數(shù)據(jù)。 db.Set 設(shè)置key的value值,key不存在則新建,key存在則修改。 db.Get 得到key中value數(shù)據(jù)。 db.Delete 刪除key及value的數(shù)據(jù)。
比原鏈的數(shù)據(jù)庫
默認(rèn)情況下,數(shù)據(jù)存儲(chǔ)目錄在--home參數(shù)下的data目錄。以Darwin平臺(tái)為例,默認(rèn)數(shù)據(jù)庫存儲(chǔ)在 $HOME/Library/Bytom/data。
accesstoken.db token信息(錢包訪問控制權(quán)限) core.db 核心數(shù)據(jù)庫,存儲(chǔ)主鏈相關(guān)數(shù)據(jù)。包括塊信息、交易信息、資產(chǎn)信息等 discover.db 分布式網(wǎng)絡(luò)中端到端的節(jié)點(diǎn)信息
trusthistory.db txdb.db 存儲(chǔ)交易相關(guān)信息 txfeeds.db 目前比原鏈代碼版本未使用該功能,暫不介紹 wallet.db 本地錢包數(shù)據(jù)庫。存儲(chǔ)用戶、資產(chǎn)、交易、utox等信息
以上所有數(shù)據(jù)庫都由database模塊管理
比原數(shù)據(jù)庫接口
在比原鏈中數(shù)據(jù)持久化存儲(chǔ)由database模塊管理,但是持久化相關(guān)接口在protocol/store.go中
type Store interface { BlockExist(*bc.Hash) bool GetBlock(*bc.Hash) (*types.Block, error) GetStoreStatus() *BlockStoreState GetTransactionStatus(*bc.Hash) (*bc.TransactionStatus, error) GetTransactionsUtxo(*state.UtxoViewpoint, []*bc.Tx) error GetUtxo(*bc.Hash) (*storage.UtxoEntry, error) LoadBlockIndex() (*state.BlockIndex, error) SaveBlock(*types.Block, *bc.TransactionStatus) error SaveChainStatus(*state.BlockNode, *state.UtxoViewpoint) error }
BlockExist 根據(jù)hash判斷區(qū)塊是否存在
GetBlock 根據(jù)hash獲取該區(qū)塊
GetStoreStatus 獲取store的存儲(chǔ)狀態(tài)
GetTransactionStatus 根據(jù)hash獲取該塊中所有交易的狀態(tài)
GetTransactionsUtxo 緩存與輸入txs相關(guān)的所有utxo
GetUtxo(*bc.Hash) 根據(jù)hash獲取該塊內(nèi)的所有utxo
LoadBlockIndex 加載塊索引,從db中讀取所有block header信息并緩存在內(nèi)存中
SaveBlock 存儲(chǔ)塊和交易狀態(tài)
SaveChainStatus 設(shè)置主鏈的狀態(tài),當(dāng)節(jié)點(diǎn)第一次啟動(dòng)時(shí),節(jié)點(diǎn)會(huì)根據(jù)key為blockStore的內(nèi)容判斷是否初始化主鏈。
比原鏈數(shù)據(jù)庫key前綴
** database/leveldb/store.go **
var ( blockStoreKey = []byte("blockStore") blockPrefix = []byte("B:") blockHeaderPrefix = []byte("BH:") txStatusPrefix = []byte("BTS:") )
blockStoreKey 主鏈狀態(tài)前綴
blockPrefix 塊信息前綴
blockHeaderPrefix 塊頭信息前綴
txStatusPrefix 交易狀態(tài)前綴
GetBlock查詢塊過程分析
** database/leveldb/store.go **
func (s *Store) GetBlock(hash *bc.Hash) (*types.Block, error) { return s.cache.lookup(hash) }
** database/leveldb/cache.go **
func (c *blockCache) lookup(hash *bc.Hash) (*types.Block, error) { if b, ok := c.get(hash); ok { return b, nil } block, err := c.single.Do(hash.String(), func() (interface{}, error) { b := c.fillFn(hash) if b == nil { return nil, fmt.Errorf("There are no block with given hash %s", hash.String()) } c.add(b) return b, nil }) if err != nil { return nil, err } return block.(*types.Block), nil }
GetBlock函數(shù)最終會(huì)執(zhí)行l(wèi)ookup函數(shù)。lookup函數(shù)總共操作有兩步:
從緩存中查詢hash值,如果查到則返回
如果為從緩存中查詢到則回調(diào)fillFn回調(diào)函數(shù)。fillFn回調(diào)函數(shù)會(huì)將從磁盤上獲得到塊信息存儲(chǔ)到緩存中并返回該塊的信息。
fillFn回調(diào)函數(shù)實(shí)際上調(diào)取的是database/leveldb/store.go下的GetBlock,它會(huì)從磁盤中獲取block信息并返回。
“Bytom持久化存儲(chǔ)LevelDB有哪些操作”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!
當(dāng)前題目:Bytom持久化存儲(chǔ)LevelDB有哪些操作
分享路徑:http://fisionsoft.com.cn/article/goddpi.html