美文网首页LevelDb
LevelDb之manifest文件

LevelDb之manifest文件

作者: ieasy_tm | 来源:发表于2017-08-21 20:51 被阅读137次

从这篇文章开始想写写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文件结构和文件的由来。文件结构如图:


manifest.png

再配合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是一个链表,每个节点就是一个versionversion中主要包含有.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文件的创建和修改过程。这个问题还是有点难度的,这里还是以Golanggithub.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 ~

相关文章

网友评论

    本文标题:LevelDb之manifest文件

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