leveldb的DBSequence从哪里来,到哪里去?

(Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu)

leveldb数据库的DBSequence从哪里来,到哪里去?

大概的情形是,leveldb的记录初始DBSequence为0,随着记录的增加,记录sequence不断随着增加,并持久化到文件中。

细节在哪呢?

sequence如何一步一步递增加上来的;

WriteBatch同一批写入的记录,dbsequence一样吗?
如果一样的话,WriteBatch写入一批记录后,dbsequence怎么变化的?

一般DBSequence会出现跳变吗?是一直能反映记录数吗?

dbsequence记录到哪?记录到sstable中吗?记录到manifest中吗?记录到wal中吗?或者记录在哪?

下面,一步步来分析看。

1. 初始空库的首次写入

第一条记录来的时候,或第一个WriteBatch写入的时候;
其中一条记录写入情况,也包装成WriteBatch,按WriteBatch写入;

WriteBatch的结构:
在WriteBatch的rep_开头的12字节里,前8个字节记录db-sequence,后4个字节记录count数量。
也就是一个WriteBatch对应的一批记录,统一使用的同一个db-sequence。

// WriteBatch header has an 8-byte sequence number followed by a 4-byte count.
static const size_t kHeader = 12;
void WriteBatch::Clear() {rep_.clear();rep_.resize(kHeader);
}
int WriteBatchInternal::Count(const WriteBatch* b) {return DecodeFixed32(b->rep_.data() + 8);
}
void WriteBatchInternal::SetCount(WriteBatch* b, int n) {EncodeFixed32(&b->rep_[8], n);
}
SequenceNumber WriteBatchInternal::Sequence(const WriteBatch* b) {return SequenceNumber(DecodeFixed64(b->rep_.data()));
}
void WriteBatchInternal::SetSequence(WriteBatch* b, SequenceNumber seq) {EncodeFixed64(&b->rep_[0], seq);
}

2. DBSequence的来源

每次写入记录时,会在WriteBatch中写入的db-sequence。并基于WriteBatch的记录数,来更新最新的db-sequence。
所以可以认为DBSequence的变动来源于每次记录的写入。
其中,WriteBatch的db-sequence并不是一开始写入进来的,而是在leveldb::DBImpl::Write中写入时赋值的,写入时赋值从记录的version中获取值,更新值。
从下面的代码中,可以看到

  • WriteBatch中的db-sequence从version中获取;
  • WriteBatch写入之后,要更新db-sequence到version;
  • DB-Sequence增加的大小是WriteBatch写入记录的个数;
Status DBImpl::Write(const WriteOptions& options, WriteBatch* updates) {
...uint64_t last_sequence = versions_->LastSequence();
...WriteBatchInternal::SetSequence(updates, last_sequence + 1);last_sequence += WriteBatchInternal::Count(updates);
...versions_->SetLastSequence(last_sequence);
...
}

3. DBSequence的持久化

DBSequence的持久话,有了写入之后,会把最新Sequence记录到文件中,持久化下来。
每当有数据写入到库中,就会发生dbsequence更新;
dbsequence数据更新时,会首先持久化到WAL日志上,当Write时,会把带有db-sequence的WriteBatch写入到WAL日志中。

Status DBImpl::Write(const WriteOptions& options, WriteBatch* updates) {
...uint64_t last_sequence = versions_->LastSequence();
...WriteBatchInternal::SetSequence(updates, last_sequence + 1);
...status = log_->AddRecord(WriteBatchInternal::Contents(updates));
...
}

DBSequence数据会存入到了记录的key中去,并在数据MinorCompact时,存储到sstable中,key with dbsequence信息都会记录进来;
不过sstable中的sequence一般只是查询用,不会用作其它用途,例如不会用作dbsequence的还原等操作。

有了新的sstable之后,这个新增文件的记录要记录到manifest文件,记录到manifest文件时,会记录当前的dbsequence。
每次LogAndApply记录一条edit记录到manifest文件,就会记录最新的dbsequence。

Status VersionSet::LogAndApply(VersionEdit* edit, port::Mutex* mu) {
...edit->SetLastSequence(last_sequence_);
...std::string record;edit->EncodeTo(&record);s = descriptor_log_->AddRecord(record);
...
}

4. DBSequence的还原

上面的存有db-sequnce值的文件,包括了WAL文件,sstable,manifest文件。
通常用于DBSequence还原的文件主要是manifest文件和WAL日志文件。
从manifest文件的最后一条有效记录中,中可以获取到已经存到sstable的db-sequence信息。

另外从wal日志中呢,从WAL日志的最后一条有效记录中,可以获取到最新的db-sequence,这是还未写入到sstable的最新记录的dbsequence;
但wal日志也可能是没有的,例如所有数据都已经放到sstable中了,此时的wal日志是空的,从manifest中获取即可。

总体过程,先从manifest还原db-sequence,然后再考虑从存在的wal中还原出最新的db-sequence。

Status DBImpl::Recover(VersionEdit* edit, bool* save_manifest) {
...
s = versions_->Recover(save_manifest);
SequenceNumber max_sequence(0);
...// Recover in the order in which the logs were generatedstd::sort(logs.begin(), logs.end());for (size_t i = 0; i < logs.size(); i++) {s = RecoverLogFile(logs[i], (i == logs.size() - 1), save_manifest, edit,&max_sequence);if (!s.ok()) {return s;}// The previous incarnation may not have written any MANIFEST// records after allocating this log number.  So we manually// update the file number allocation counter in VersionSet.versions_->MarkFileNumberUsed(logs[i]);}
...if (versions_->LastSequence() < max_sequence) {versions_->SetLastSequence(max_sequence);}
...
}

从manifest还原db-sequence:

Status VersionSet::Recover(bool* save_manifest) {
...
while (reader.ReadRecord(&record, &scratch) && s.ok()) {
...VersionEdit edit;s = edit.DecodeFrom(record);
...if (edit.has_last_sequence_) {last_sequence = edit.last_sequence_;have_last_sequence = true;}
...
last_sequence_ = last_sequence;
...
}

从wal中还原db-sequence:

Status DBImpl::RecoverLogFile(uint64_t log_number, bool last_log,bool* save_manifest, VersionEdit* edit,SequenceNumber* max_sequence) {
...
while (reader.ReadRecord(&record, &scratch) && status.ok()) {
...WriteBatchInternal::SetContents(&batch, record);
...const SequenceNumber last_seq = WriteBatchInternal::Sequence(&batch) +WriteBatchInternal::Count(&batch) - 1;if (last_seq > *max_sequence) {*max_sequence = last_seq;}
...
}

5. dbsequence从哪来的,到哪去了呢?

回到问题:dbsequence从哪来的,到哪去的?

dbsequence从哪来的:
dbsequence是从0开始,随着write的Batch记录数的增多,不断加上来的,通常最新的dbsequence可以反映总的记录数。

dbsequence到哪了去了:
dbsequence会存储到wal日志,sstable中,manifest这些持久化的文件中。
dbsequence会附加到每个key的后面作为key的隐藏部分。

(Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/66000.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

docker内外如何实现ROS通信

写在前面 在一台电脑上装有docker&#xff0c;docker内外均装有ROS系统&#xff0c;现在想要实现docker内外的ROS通信&#xff0c;怎么办呢&#xff1f; 首先&#xff0c;因为是同一台电脑的docker内外&#xff0c;所以IP本身是互通的&#xff0c;不需要在/etc/hosts中添加IP…

双指针与滑动窗口

双指针 相向双指针 两数之和 题意是找到不同两个数使得它们相加和为target&#xff0c;数组有序 利用数组有序的性质&#xff0c;判断指针前后的区间的性质 例如&#xff1a;2 3 4 6 8, target 9 2 8 10 > 9, 因为非递减序列&#xff0c;2之后的每个数都会大等于2&…

unity开发之shader 管道介质流动特效

效果 shader graph 如果出现下面的效果&#xff0c;那是因为你模型的问题&#xff0c;建模做贴图的时候没有设置好UV映射&#xff0c;只需重新设置下映射即可

python +tkinter绘制彩虹和云朵

python tkinter绘制彩虹和云朵 彩虹&#xff0c;简称虹&#xff0c;是气象中的一种光学现象&#xff0c;当太阳光照射到半空中的水滴&#xff0c;光线被折射及反射&#xff0c;在天空上形成拱形的七彩光谱&#xff0c;由外圈至内圈呈红、橙、黄、绿、蓝、靛、紫七种颜色。事实…

stable diffusion安装mov2mov

第一步&#xff1a; 下载mov2mov&#xff0c;地址&#xff1a;https://gitcode.com/gh_mirrors/sd/sd-webui-mov2mov 下载包到web-ui的sd-webui-aki-v4.10\extensions文件夹面解压 第二步&#xff1a;在文件夹中调出cmd窗口&#xff0c;执行下列命令&#xff0c; git restore…

SpringSpringBoot常用注解总结

目录 1. SpringBootApplication 2. Spring Bean 相关 2.1. Autowired 2.2. Component,Repository,Service, Controller 2.3. RestController 2.4. Scope 2.5. Configuration 3. 处理常见的 HTTP 请求类型 3.1. GET 请求 3.2. POST 请求 3.3. PUT 请求 3.4. DELETE 请…

STM32 软件I2C读写

单片机学习&#xff01; 目录 前言 一、软件I2C读写代码框架 二、I2C初始化 三、六个时序基本单元 3.1 引脚操作的封装和改名 3.2 起始条件执行逻辑 3.3 终止条件执行逻辑 3.4 发送一个字节 3.5 接收一个字节 3.5 发送应答&接收应答 3.5.1 发送应答 3.5.2 接…

七种改进爬山算法的方法

一、爬山算法 爬山算法(Hill Climbing Algorithm)是一种启发式的基于局部最优解的搜索算法,用于在给定的搜索空间中寻找全局最优解或足够好的解。它属于局部搜索算法,通常用于解决优化问题,包括连续和离散问题。 爬山算法模拟了爬山的过程,从某个随机起始点开始,不断向更…

MYSQL--------MYSQL中的运算符

以下是 MySQL 中各种运算符的介绍及代码示例&#xff1a; 算术运算符 算术运算符用于执行基本的数学运算&#xff0c;包括加、减、乘、除、取模&#xff08;取余&#xff09;。 -- 创建一个名为 operator_demo 的表 CREATE TABLE operator_demo (a INT,b INT );-- 插入示例数…

MySQL图形化界面工具--DataGrip

之前介绍了在命令行进行操作&#xff0c;但是不够直观&#xff0c;本次介绍图形化界面工具–DataGrip。 安装DataGrip 官网链接&#xff1a;官网下载链接 常规的软件安装流程。 参考链接&#xff1a;DataGrip安装 使用DataGrip 添加数据源&#xff1a; 第一次使用最下面会…

【虚拟机】VMware 16图文安装和配置 AlmaLinux OS 9.5 教程

准备工作 下载AlmaLinux ISO文件&#xff1a;从AlmaLinux官方网站&#xff08;https://almalinux.org/&#xff09;下载最新版本的ISO文件。 安装VMware Workstation&#xff1a;确保您的计算机上已安装VMware Workstation。&#xff08;注&#xff1a;我这边使用的是VMware16…

中国联通首次推出一套量化大模型的新标准

新基准的诞生 中国联通的研究团队近日公布了一套创新性的量化标准&#xff0c;主要针对大型语言模型的能力评估。这一基准的灵感来源于动物智能演化的规律&#xff0c;为用户在选择语言模型时提供了科学依据。现代社会中&#xff0c;各种语言模型如雨后春笋般涌现&#xff0c;…

aardio —— 虚表 —— 使用ownerDrawCustom列类型制作喜马拉雅播放器列表

不会自绘也能做漂亮列表&#xff0c;你相信吗&#xff1f; 看看这个例子&#xff0c;虚表_vlistEx_ColType_OwnerDrawCustom列类型&#xff0c;移植自godking.customPlus&#xff0c;简单好用&#xff0c;做漂亮列表的大杀器&#xff0c;玩aardio必备利器&#xff01; 请更新…

网安数学基础期末复习

目录 整除同余同余方程群和环 整除 a的显然因数/平凡因数1&#xff0c;a整除的传递性和组合性 若 a ∣ b , b ∣ a a|b,b|a a∣b,b∣a 则 a b a\pm b ab欧几里得带余除法 公因数和最大公因数在整除里的定义&#xff0c;最大公因数为1则两数互质&#xff0c;注意公因数有正…

【论文阅读笔记】SCI算法与代码 | 低照度图像增强 | 2022.4.21

目录 一 SCI 1 SCI网络结构 核心代码&#xff08;model.py&#xff09; 2 SCI损失函数 核心代码&#xff08;loss.py&#xff09; 3 实验 二 SCI效果 1 下载代码 2 运行 一 SCI &#x1f49c;论文题目&#xff1a;Toward Fast, Flexible, and Robust Low-Light Image …

AcWing练习题:平均数2

读取三个浮点数 A&#xff0c;B 和 C 的值&#xff0c;对应于三个学生的成绩。 请你计算学生的平均分&#xff0c;其中 A 的成绩的权重为 2&#xff0c;B 的成绩的权重为 3&#xff0c;C 的成绩的权值为 5。 成绩的取值范围在 0 到 10 之间&#xff0c;且均保留一位小数。 输…

aardio —— 改变按钮文本颜色

import win.ui; /*DSG{{*/ var winform win.form(text"改变按钮颜色示例";right279;bottom239;composited1) winform.add( button{cls"button";text"点这里1";left16;top104;right261;bottom159;fontLOGFONT(h-14);z1}; button2{cls"butto…

Scratch教学作品 | 白水急流——急流勇进,挑战反应极限! ‍♂️

今天为大家推荐一款刺激又好玩的Scratch冒险作品——《白水急流》&#xff01;由AgentFransidium制作&#xff0c;这款作品将带你体验惊险的急流救援任务&#xff0c;帮助那位“睡着的疯狂人”安全穿越湍急水域&#xff01;想要挑战自己的反应极限&#xff1f;快来试试吧&#…

Android测试ABD环境及语句

1、什么是adb ADB 全称为 Android Debug Bridge&#xff0c;起到调试桥的作用&#xff0c;是一个客户端-服务器端程序。其中客户端是用来操作的电脑&#xff0c;服务端是 Android 设备。 ADB 也是 Android SDK 中的一个工具&#xff0c;可以直接操作管理 Android 模拟器或者真…

库伦值自动化功耗测试工具

1. 功能介绍 PlatformPower工具可以自动化测试不同场景的功耗电流&#xff0c;并可导出为excel文件便于测试结果分析查看。测试同时便于后续根据需求拓展其他自动化测试用例。 主要原理&#xff1a;基于文件节点 coulomb_count 实现&#xff0c;计算公式&#xff1a;电流&…