LevelDb之manifest檔案
從這篇文章開始想寫寫leveldb的小知識。先了解manifest檔案,因為這個檔案關係到例項的讀取。至於這個檔案的內部結構以及如何來的,等會再聊。
if instances[Name], err = leveldb.OpenFile(Dir, instance); err != nil {
return errors.New(fmt.Sprintf(`leveldbs: err while open %s : %s`, Dir, err.Error()))
}
這段程式碼在manifest檔案損壞的情況下會出現報錯,報錯內容:
ERROR leveldb: manifest corrupted: missing [file=MANIFEST-*******]
報錯原因:leveldb在儲存過程中因為一些其他原因導致程式突然的down掉可能導致manifest檔案損害或者丟失。這樣就只能手動repair
下了,打不開一個instance
就沒有辦法執行get
命令。repair
的業務方程式碼可以這樣寫,這裡以Golang
程式碼來說明:
if instances[cfgIns.Name], err = leveldb.OpenFile(Dir, instance); err != nil {
if instances[cfgIns.Name], err = leveldb.RecoverFile(Dir, instance); err != nil {
return errors.New(fmt.Sprintf(`err while recoverfile%s : %s`, Dir, err.Error()))
}
}
RecoverFile
這個API函式的原始碼是:
func RecoverFile(path string, o *opt.Options) (db *DB, err error) {
stor, err := storage.OpenFile(path)
if err != nil {
return
}
db, err = Recover(stor, o)
if err != nil {
stor.Close()
} else {
db.closer = stor
}
return
}
manifest檔案修復還是蠻簡單的,說明Google的大神早就想到了這些東西。通過上面的例子先感受下manifest檔案的存在,下面我們學習下manifest檔案結構和檔案的由來。檔案結構如圖:
再配合Golang中定義的struct看看:
type session struct {
stNextFileNum uint64 // current unused file number
stJournalNum uint64 // current journal file number; need external synchronization
stPrevJournalNum uint64 // prev journal file number; no longer used; for compatibility with older version of leveldb
stSeqNum uint64 // last mem compacted seq; need external synchronization
stTempFileNum uint64
stor storage.Storage
storLock util.Releaser
o *cachedOptions
icmp *iComparer
tops *tOps
manifest *journal.Writer
manifestWriter storage.Writer
manifestFile storage.File
stCompPtrs []iKey // compaction pointers; need external synchronization
stVersion *version // current version
vmu sync.Mutex
}
manifest
檔案存放versionset
(版本集合資訊)。versionset
是一個連結串列,每個節點就是一個version
,version
中主要包含有.sstable
檔案大小,檔案編號,有序值的最大值和最小值等等資訊。
type tSet struct {
level int
table *tFile
}
type version struct {
s *session
tables []tFiles
cLevel int
cScore float64
cSeek unsafe.Pointer
ref int
next *version
}
type tFile struct {
file storage.File
seekLeft int32
size uint64
imin, imax iKey
}
好吧,manifest檔案裡面存放的東西大致上就這些了,下面聊聊manifest檔案的建立和修改過程。這個問題還是有點難度的,這裡還是以Golang
的github.com/syndtr/goleveldb/leveldb
這個庫為例來說明。newManifest
是建立一個manifest, encode
編碼後寫入檔案,最後將manifest檔案的名稱寫入到current
檔案中,current
只記錄當前的manifest檔案的檔名稱: _, err = fmt.Fprintln(w, f2.name())
。
func (s *session) newManifest(rec *sessionRecord, v *version) (err error) {
num := s.allocFileNum()
file := s.stor.GetFile(num, storage.TypeManifest)
writer, err := file.Create()
if err != nil {
return
}
jw := journal.NewWriter(writer)
if v == nil {
v = s.version()
defer v.release()
}
if rec == nil {
rec = &sessionRecord{}
}
s.fillRecord(rec, true)
v.fillRecord(rec)
defer func() {
if err == nil {
s.recordCommited(rec)
if s.manifest != nil {
s.manifest.Close()
}
if s.manifestWriter != nil {
s.manifestWriter.Close()
}
if s.manifestFile != nil {
s.manifestFile.Remove()
}
s.manifestFile = file
s.manifestWriter = writer
s.manifest = jw
} else {
writer.Close()
file.Remove()
s.reuseFileNum(num)
}
}()
w, err := jw.Next()
if err != nil {
return
}
err = rec.encode(w)
if err != nil {
return
}
err = jw.Flush()
if err != nil {
return
}
err = s.stor.SetManifest(file)
return
}
一邊學習,一邊記錄,end ~
相關文章
- Android知識點回顧之Manifest檔案-上篇Android
- Android知識點回顧之Manifest檔案-下篇Android
- 深入 LevelDB 資料檔案 SSTable 的結構
- android manifest.xml 配置檔案 雜AndroidXML
- Android的Manifest配置檔案介紹Android
- 聊一聊 JAR 檔案和 MANIFEST.MFJAR
- LevelDB 原始碼解析之 Arena原始碼
- Android Manifest.xml檔案的結構及作用AndroidXML
- LevelDB 原始碼解析之 Varint 編碼原始碼
- LSM-Tree - LevelDb之LRU快取快取
- (12)caffe總結之影像資料轉換成db(leveldb/lmdb)檔案
- LevelDB 原始碼解析之 Random 隨機數原始碼random隨機
- Android學習之 主專案合併Library子專案中的ManifestAndroid
- LevelDB學習筆記 (1):初識LevelDB筆記
- LevelDB 入門 —— 全面瞭解 LevelDB 的功能特性
- 檔案操作之按照行讀寫檔案
- Golang 專案之配置檔案Golang
- 檔案共享之nfsNFS
- 檔案操作之flock
- LevelDB 實現分析
- SAP Fiori Elements 應用的 manifest.json 檔案執行時如何被解析的JSON
- 載入AB的4種方式以及透過Manifest檔案得到某個包的依賴
- LevelDB原始碼分析:理解Slice實現 - 高效的LevelDB引數物件原始碼物件
- Ajax 之檔案上傳
- HTTP 之 檔案壓縮HTTP
- mysql之pid檔案MySql
- PHP之開啟檔案PHP
- SVN之檔案同步更新
- Leveldb原始碼分析--1原始碼
- Manifest 與TypeTag
- php檔案操作之提取檔案/目錄的名稱PHP
- 檔案包含之包含了Linux檔案描述符Linux
- oracle之 利用 controlfile trace檔案重建控制檔案Oracle
- ASM與檔案系統之間copy資料檔案--檔案系統到ASMASM
- SpringMVC之檔案上傳SpringMVC
- Java 檔案 IO 操作之 DirectIOJava
- 7、python之檔案操作Python
- python 基礎之檔案Python