超級帳本支持多帳本(詳細內容參考第7章實現數據隔離的多鏈及多通道),每一個帳本的數據是分開存儲的。數據庫
帳本編號(LedgerID)的數據存儲在LevelDB數據庫中,只是記錄了有哪些版本,建立新的帳本會檢查是否有相同的帳本編號存在,數組
這保證了全局惟一性。帳本編號庫並不存儲與區塊相關的數據。這和區塊索引不同。數據結構
帳本數據(Ledger)是以二進制文件的形式存儲的,每一個帳本數據存儲在不一樣的目錄下。app
後面內容都是在已經區分了帳本的狀況下再對數據進行查詢的。區塊鏈
基於文件系統的區塊存儲實現了以下功能接口。優化
【1】。帳本存儲管理atom
A。提交區塊到帳本(AddBlock)spa
B。獲取區塊鏈信息(GetBlockchainInfo)設計
C。獲取區塊數據(RetrieveBlocks)3d
D。關閉區塊存儲(Shutdown)
【2】。索引管理:跟蹤區塊和交易保存在哪一個文件。
A。根據哈希值獲取區塊(RetrieveBlockByHash)
B。根據區塊編號獲取區塊(RetrieveBlockByNumber)
C。根據交易編號獲取交易(RetrieveTxByID)
D。根據區塊編號和交易編號獲取交易(RetrieveTxByBlockNumTranNum)
E。根據交易編號獲取區塊(RetrieveBlockByTxID)
F。根據交易編號獲取交易驗證碼(RetrieveTxValidationCodeByTxID)
帳本數據的全部操做都是經過區塊文件管理器(blockfileMgr)實現的,定義以下:
type blockfileMgr struct{ rootDir String //區塊鏈中區塊存儲的根目錄 conf *Conf //配置信息 db *leveldbhelper.DBHandle //數據庫指針 index index //區塊索引接口 cpInfo *checkpointInfo //區塊檢查點信息 cpInfoCond *sync.Cond //條件變量 currentFileWriter *blockfileWriter //當前寫入區塊文件的指針 bcInfo atomic.Value //區塊鏈信息 }
區塊文件管理器實現的功能分爲幾類:
【1】帳本數據存儲管理
A。肯定文件存儲在哪一個目錄
B。肯定區塊存儲在哪一個文件
【2】檢查點管理:跟蹤最新持久化存儲的文件
【3】索引管理:跟蹤區塊和交易保存在哪一個文件
"data":"$rawJSON"
}
在超級帳本中:
【1】若是存儲的類型是JSON,且JSONValue的data字段是狀態值通過JSON序列化後的內容,則CouchDoc中的Attachments爲空;
【2】若是存儲的類型是字節數組,則JSONValue只保存版本信息,data字段爲空,狀態值放在Attachments的AttachmentBytes中,Attachments的Name爲「valueBytes」,ContentType爲「application/octet-stream」。在獲取時根據data字段是否爲空能夠判斷出存儲的狀態值類型,最後獲得存儲的版本和狀態值。
條件查詢是基於LevelDB的狀態數據庫所沒有的功能進行的。查詢前會對查詢條件進行轉換,增長「data.」前綴和查詢記錄限制等,查詢結果還會默認增長「_id」"version""chaincodeid"。好比原始的查詢條件爲:
{
"selector":{
"owner":{
"$seq":"tom"
}
},
「fields」:[
"owner",
"asset_name",
"color",
"size"
],
"sort":[
"size",
"color"
]
}
轉換後的查詢條件爲:
{
"selector":{
"$and":[
{
"chaincodeid":"marble"
},
{
歷史信息記錄最細的粒度就是交易,若在一個交易中屢次對同一個writeKey更新數據,則會以第一次數據爲準,歷史信息實際存儲的信息是固定的空字節數組[]byte{}。
更新區塊信息的時候,會同步更新檢查點信息,保存的內容是最新的區塊高度和最大的交易序號,檢查點信息用來判斷歷史信息的狀態是不是最新的。
區塊的提交過程分爲3個步驟:
【1】。先保存區塊到文件存儲的帳本數據中
【2】。而後更新狀態數據
【3】。最後更新歷史信息數據
這3個步驟是順序執行的,在這個過程當中有文件的操做,也有數據庫的操做,因此在任何一個步驟均可能出現錯誤或者中斷。恢復的過程會根據帳本數據記錄的區塊信息和狀態數據,歷史信息數據的檢查點進行比較,從新提交檢查點以後的區塊信息,保持帳本數據的一致性。
本章小結:
本章介紹了Hyperledger Fabric 1.0的數據存儲,包括帳本數據(Ledger)、區塊索引(Index)、狀態數據(state Database)、歷史數據(Hisotry database)等存儲結構。目前的數據存儲存在較大的優化空間,帳本數據結構的設計帶來的開銷很大,最新的版本並無實現帳本載剪(Ledger Prune)功能,不能進行歸檔,也不能刪除無效交易,因此會致使存儲空間持續增加。