leveldb源码分析--日志
我们知道在一个数据库系统中为了保证数据的可靠性,我们都会记录对系统的操作日志。日志的功能就是用来在系统down掉的时候对数据进行恢复,所以日志系统对一个要求可靠性的存储系统是极其重要的。接下来我们分析leveldb的日志,首先在leveldb源码目录中有doc/log_format.txt,这个文件详细的描述了leveldb的日志格式:
record :=
checksum: uint32 // crc32c of type and data[] ; little-endian
length: uint16 // little-endian
type: uint8 // One of FULL,FIRST, MIDDLE, LAST
data: uint8[length]
如下图(图片引用):
leveldb在写日志时,对日志文件进行了划分为多个32K的文件块,每次读写日志时都以这样的每个32K为单位。这样进行处理以后leveldb的日志文件的大致组成就可以看做为如下的形式:
那么我们初步描述一下Log的写入情况为:
当要写入一条首先判断当前block中是否足够存放该条日志
S1.如果足够那么直接安装格式写入;
S2.如果不够那么计算出去头以外可以存放多少内容,将内容组装为FIRST的Log typpe写入;然后新取一个块判断是否足够存放剩下的日志数据
while(数据未写完)
S21. 如果足够就组装为LAST的形式写入;
S22. 如果仍然不够就组装为MIDDLE的形式写入
所以就容易理解这里的FULL,FIRST,MIDDLE和LAST了:
FULL:一条完整的日志被写到block
FIRST:一条日志,但是当前block无法完全写入,有部分数据被写到了下一个block,当前block的数据只是日志的开始(第一)部分
MIDDLE:该日志内容是接着前一个block里面的最后一条日志的继续,而且本block还无法完全写完,在下一个block中继续有该条日志的数据
LAST: 之前block的未写完的日志的最后一部分;
另外需要注意的就是根据前面的描述我们可以想象得到一个block在写入一部分数据以后会剩下部分空间,这个空间可能是大于7byte,等于7byte,小于7byte;这里为什么要以7byte为分界呢?日志记录的header(crc|length|type)长度为7,如果超过7就至少可以存一个FISRT的部分日志记录,而等于7就刚好存一个header,少于7就连header都存不了。LOG也正是基于这样的原因,小于7时就补充”\0”,7就存一个空header。我们来看看代码逻辑
Status Writer::AddRecord(const Slice& slice) {
bool begin = true;
// 循环向日志文件写,直到写完为止
do {
const int leftover = kBlockSize - block_offset_;
if (leftover < kHeaderSize) {// 小于 7 byte (header size )填充 0x0
if (leftover > ) {
dest_->Append(Slice("\x00\x00\x00\x00\x00\x00", leftover));
}
block_offset_ = ;
}
const size_t avail = kBlockSize - block_offset_ - kHeaderSize;
const size_t fragment_length = (left < avail) ? left : avail;
RecordType type;
const bool end = (left == fragment_length);{// 判断本段能否写完
if (begin && end) { // 开始结束都在本block
type = kFullType;
} else if (begin) { // 开始在本block,结束不在
type = kFirstType;
} else if (end) { // 结束在,开始不在
type = kLastType;
} else { // 开始结束都不在本block
type = kMiddleType;
}
// encode 然后再写入文件中
s = EmitPhysicalRecord(type, ptr, fragment_length);
ptr += fragment_length;
left -= fragment_length;
begin = false;
} while (s.ok() && left > );
return s;
}
读日志的代码在log_reader.cc中,代码的逻辑比写负责很多,主要是读入时会需要增加很多错误处理相关的内容,具体的代码不在罗列,理解了日志文件的格式以后的很容易就能读懂。当然同时其异常处理的逻辑也是我们码农们学习的材料,理解一下高手们是如何进行各种错误处理的。
leveldb源码分析--日志的更多相关文章
- leveldb源码分析--WriteBatch
从[leveldb源码分析--插入删除流程]和WriteBatch其名我们就很轻易的知道,这个是leveldb内部的一个批量写的结构,在leveldb为了提高插入和删除的效率,在其插入过程中都采用了批 ...
- leveldb源码分析--SSTable之block
在SSTable中主要存储数据的地方是data block,block_builder就是这个专门进行block的组织的地方,我们来详细看看其中的内容,其主要有Add,Finish和CurrentSi ...
- leveldb源码分析--Key结构
[注]本文参考了sparkliang的专栏的Leveldb源码分析--3并进行了一定的重组和排版 经过上一篇文章的分析我们队leveldb的插入流程有了一定的认识,而该文设计最多的又是Batch的概念 ...
- Leveldb源码分析--1
coming from http://blog.csdn.net/sparkliang/article/details/8567602 [前言:看了一点oceanbase,没有意志力继续坚持下去了,暂 ...
- 精尽Spring Boot源码分析 - 日志系统
该系列文章是笔者在学习 Spring Boot 过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring Boot 源码分析 GitHub 地址 进行阅读 Sprin ...
- leveldb源码分析之Slice
转自:http://luodw.cc/2015/10/15/leveldb-02/ leveldb和redis这样的优秀开源框架都没有使用C++自带的字符串string,redis自己写了个sds,l ...
- LevelDB源码分析--Cache及Get查找流程
本打算接下来分析version相关的概念,但是在准备的过程中看到了VersionSet的table_cache_这个变量才想起还有这样一个模块尚未分析,经过权衡觉得leveldb的version相对C ...
- leveldb源码分析--SSTable之TableBuilder
上一篇文章讲述了SSTable的格式以后,本文结合源码解析SSTable是如何生成的. void TableBuilder::Add(const Slice& key, const Slice ...
- leveldb源码分析之内存池Arena
转自:http://luodw.cc/2015/10/15/leveldb-04/ 这篇博客主要讲解下leveldb内存池,内存池很多地方都有用到,像linux内核也有个内存池.内存池的存在主要就是减 ...
随机推荐
- 用Elasticsearch做大规模数据的多字段、多类型索引检索
本文同时发布在我的个人博客 之前尝试了用mysql做大规模数据的检索优化,可以看到单字段检索的情况下,是可以通过各种手段做到各种类型索引快速检索的,那是一种相对简单的场景. 但是实际应用往往会复杂一些 ...
- 前端组件化Polymer入门教程(1)——初识&&安装
前端组件化Polymer入门教程目录: 前端组件化Polymer入门教程(1)--初识&&安装 前端组件化Polymer入门教程(2)--快速入门 前端组件化Polymer入门教程(3 ...
- mysql 主键和唯一索引的区别
主键是一种约束,唯一索引是一种索引,两者在本质上是不同的. 主键创建后一定包含一个唯一性索引,唯一性索引并不一定就是主键. 唯一性索引列允许空值,而主键列不允许为空值. 主键列在创建时,已经默认为非空 ...
- 前端自动构建工具Gulp入门
基于nodeJs:通过不同插件能自动完成一系列动作,比如压缩js/css/img.解析模版标签.解析less等: 一.安装gulp 安装nodeJs 打开Node.js command prompt ...
- 如何精准实现OCR文字识别?
欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由云计算基础发表于云+社区专栏 前言 2018年3月27日腾讯云云+社区联合腾讯云智能图像团队共同在客户群举办了腾讯云OCR文字识别-- ...
- js的轮播效果
图片的轮播效果!主要运用了元素的style样式属性,与 setInterval(); <!DOCTYPE html> <html> <head lang="en ...
- CRM项目完成实现
这两天我们都在写项目的接口与实现的! 今天主要是遇到的问题: 当我在添加新的班级的时候,班级的老师 我需要去判断这个老师是否存在,如果不存在的话,我就要把这个老师添加到学校的员工表中! 我会先判断这个 ...
- Spring事务传播属性介绍(三).Nested
Required.Required_New传播属性分析传送门:https://www.cnblogs.com/lvbinbin2yujie/p/10259897.html Mandatory.Neve ...
- 自制 Chrome Custom.css 设置网页字体为微软雅黑扩展
自己做的將網頁自動替換為微軟雅黑的擴展.很好用. 將Customcss.rcx拖到擴展裏就可. 下載:Customcss.zip
- C# Owin初探 概念理解(一)
本文是阅读网上大牛的文章总结而成. 目录 1.Owin定义 2.为什么要用Owin 3.作用 4.总结 1.Owin定义 Owin是Open Web Interface For .NET.也就是.Ne ...