leveldb代码阅读(4)——打开数据库的流程

        1、创建一个DBImpl对象,DBImpl是DB的子类
        2、加锁
        3、调用Recover把数据库恢复成为上次退出时的状态
        4、创建日志文件以及对应的内存table
        5、把版本变更应用到当前的版本上,使当前版本的状态最新
        6、删除过期文件
        7、调度后台进程,后台进程的功能是进行table数据的合并压缩

        8、返回

// 打开数据库
Status DB::Open(const Options& options,     // 选项
                const std::string& dbname,              // 数据库名字
                DB** dbptr)                                         // DB指针的指针
{
    *dbptr = NULL;

    // DBImpl是数据库的实现
    // 创建一个DB对象
    DBImpl* impl = new DBImpl(options, dbname);

    // 上锁
    impl->mutex_.Lock();

    // VersionEdit表示一个Version和另一个Version之间的变化
    VersionEdit edit;
    // Recover handles create_if_missing, error_if_exists

    // 是否保存清单
    bool save_manifest = false;

    // 恢复成为上次崩溃前或者退出前的状态
    Status s = impl->Recover(&edit, &save_manifest);

    // 成功,但是在内存中不存在,那么需要创建内存表格
    if (s.ok() && impl->mem_ == NULL)
    {
        // Create new log and a corresponding memtable.
        // 创建一个日志文件以及相对应的内存表
        // 注意这里的日志并不是我们所说的那种打印几行文字的信息
        // 而是在把数据写入数据库之前,先数据记录到日志文件中,成功之后才会写入到数据库中
        // 这样就会更加安全了

        // 创建一个日志编号
        uint64_t new_log_number = impl->versions_->NewFileNumber();

        // 创建一个可写文件——日志
        WritableFile* lfile;
        s = options.env->NewWritableFile(LogFileName(dbname, new_log_number),
                                         &lfile);
        // 成功
        if (s.ok())
        {
            // 设置日志编号
            edit.SetLogNumber(new_log_number);

            // 设置日志文件
            impl->logfile_ = lfile;
            impl->logfile_number_ = new_log_number;
            // 日志写入器,是对lfile的包装
            impl->log_ = new log::Writer(lfile);
            // 创建内存表格
            impl->mem_ = new MemTable(impl->internal_comparator_);
            // 增加内存表的引用
            impl->mem_->Ref();
        }
    }

    if (s.ok() && save_manifest)
    {
        // 设置版本变更的一些信息
        edit.SetPrevLogNumber(0);  // No older logs needed after recovery.
        edit.SetLogNumber(impl->logfile_number_);

        // 记录并应用——对于当前的版本应用一次版本变更,市值成为最新的状态
        s = impl->versions_->LogAndApply(&edit, &impl->mutex_);
    }

    if (s.ok())
    {
        // 删除过时的文件
        impl->DeleteObsoleteFiles();

        // 调度后台进行进行压缩等等
        impl->MaybeScheduleCompaction();
    }

    // 解锁
    impl->mutex_.Unlock();

    if (s.ok())
    {
        assert(impl->mem_ != NULL);
        *dbptr = impl;
    }
    else
    {
        delete impl;
    }

    return s;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值