LevelDB SSTable文件数据布局 - 掘金深入浅出LevelDB —— 05 SSTable - 叉鸽 MrCroxx 的博客Archive - Ying's Blog参考源码使用table_builder_test进行梳理整个过程。Table类:读取sstable。sstable写入过程:创建文件 for: 插入kv创建data_block 将多个data_block插入到文件末尾 filter block写入sstable meta_index_block 写入 index block 写入footer//编解码BlockHandler,编解码Footer,根据BlockHandler读取一个键的内容 table/format.h table/format.cc //不断添加键值对,逐渐构建一个Block,主要是添加键值对,然后生成Block的数据 *table/block_builder.h table/block_builder.cc //对一个Block进行读取相关的功能 table/block.h table/block.cc table/f
源码:log_writer.cc。为了不丢失数据,需要持久化的功能。把数据持久化到磁盘上,最常用的技术就是日志技术,也就是当修改数据时,先把对数据的修改写到磁盘上,然后在MemTable里做修改。因为日志记录了每个操作,只要对日志进行重放便可以恢复MemTable,这样就做到了数据库实例崩溃、宕机或者停机维护的时候数据不丢失。这种日志技术在数据库里面很常用(Redis里的Aof,Innodb里的Redo Log都是这样的技术),一般称为WAL (Write Ahead Log),正如名字一样,就是在写入前先写入日志的意思。Put操作也不能简单的写入到 memtable,而是要先写日志、再写 memtable,都更新完成后再返回写入成功,write-ahead logging 名字也是由此而来。因为日志的写入都是Append的,也就是顺序写,所以写磁盘也是顺序写,虽然磁盘的随机写效率比较低,但是顺序写效率还是很高的,所以就算加入了日志,写效率还是很高,依然可以满足写多的场景。另外可以通过控制日志写同步的策略在性能和可靠性之间做折中:每次写入都做一次sync,可靠性最高,不会丢数据,但是性
设计MemTable是一个内存数据结构,简单说它就是一个SortedMap:MemTable是一个Map,提供了Get接口,也就是可以快速地根据键查找到值,也可以使用Put接口插入Kv。MemTable是Sorted,也就是里面存储的键都是有序的,可以按照键的顺序迭代Map,或者做范围查询。有了MemTable提供的Get和Put,就有了一个简单的内存Kv数据库,可以实现Kv的查询,插入和范围查询。Put,Delete,Update实际上都是一个Put。Update:等价于新插一个同样的key(LevelDB中没有Update)。Delete:将当前最新的key插入空,并且标志置为删除。因为MemTable是内存数据结构,不需要磁盘IO,所以读写的速度非常快,所以就达到了场景需求:高效的写性能。然而这会有个问题,当数据库实例崩溃、宕机或者停机维护的时候,存储的数据就会丢失,这时候需要持久化数据。class MemTable { typedef SkipList<const char*, KeyComparator> Table; KeyComparator comp
动静结合——编码 - 知乎参考源码util/coding.h util/coding.cc:编码实现的源代码定长整数32位和64位。变长整数1标识后面还有字节要读取,0表示结束。Slicelevel只保存字符串类型。无论字符串是英文还是中文,slice都是指向二进制的字符串,不关心中文英编码形式。至于打印,就是将slice指向的二进制传递给string进行打印。对于slice来说,它只关心二进制,至于解码打印或者比较,交给string。
Log(*.log):即Write Ahead Log,是用来记录LevelDB变更的append-only的文件,在LevelDB重启时用来恢复内存中的数据。MemTable、Immutable MemTable:用来Buffer最近写入的内存结构,其通过SkipList实现。当MemTable达到一定大小时会转为只读的Immutable MemTable,并等待后台线程通过Minor Compaction将其转为level-0的SSTable。MemTable是LSM-Tree将随机写入转为顺序写入的关键。SSTable(新:.ldb、旧:.sst):通过Compaction生成的SSTable。level-0的SSTable由Immutable MemTable直接转储得到,因此level-0的SSTable的key间存在overlap;其它level的SSTable每层间没有overlap。另外,除了level-0外,每层SSTable的总大小比上一层大10倍。Manifest(MANIFEST-*):记录SSTable文件等的版本变更,其中Record的格式与Log相同,Le
打开LevelDB每一个数据库有一个name,对应一个目录,所有的数据库文件都在这个目录里。通过Open可以打开或者新建一个数据库,得到数据库的引用,通过这个引用来操作数据库。可以这样打开一个数据库:leveldb::DB* db; leveldb::Options options; options.create_if_missing = true; leveldb::Status status = leveldb::DB::Open(options, "/tmp/testdb", &db);name指定数据库目录,options指定了打开数据库的选项,db获取了数据库的引用。这里使用了create_if_missing选项,当数据库不存在时会创建数据库。关闭只需要delete数据库实例即可:delete db基础APILevelDB的基础API有三个,分别是Get、Put和Delete,表示查询一个键、插入一个键和删除一个键。LevelDB没有更新操作,因为更新就是简单地插入一个Kv,会覆盖之前的值。db->Put(leveldb::WriteOpt
CppGuide/articles at master · balloonwj/CppGuide深入理解什么是LSM-Tree - 腾讯云开发者社区-腾讯云leveldb 日常使用安装:linux下leveldb的安装与编译Kilig_yo的博客-CSDN博客linux编译leveldb记录一次leveldb安装失败经历\_inoobkk的博客-CSDN博客源码解析深入分析LevelDB实现 - 惊雷123的专栏 - 掘金【推荐】leveldb\_草上爬的博客-CSDN博客【推荐】深入浅出LevelDB - 分类 - 叉鸽 MrCroxx 的博客【推荐】LevelDB Archive - Ying's Blog【推荐】SF-Zhou's Blog【推荐】LevelDB中文文档 - KevinsBobo Blogleveldb-handbook — leveldb-handbook 文档LSM-Tree - LevelDb 源码解析 - 掘金LevelDB源码剖析 - 知乎LevelDB - 文集 - 简书标签: leveldb | Calvin's MarbleslevelDB掘金收藏
ReferenceC语言函数栈帧实例程序编译后运行时的内存分配关于书上说的“编译的时候分配内存”内存中堆栈使用,函数调用示例c程序运行时的内存分配“在编译时分配的内存”的真正含义是什么?C/C中内存区域划分大总结上述函数的调用过程其实解释了静态变量和局部变量的分配过程。而关于动态内存的分配过程是使用malloc,参考以下文章:从操作系统内存管理来说,malloc申请一块内存的背后原理是什么?探秘malloc是如何申请内存的c语言 什么时候需要动态分配内存?从汇编层次理解malloc函数关联阅读:什么是堆栈和堆?程序执行大致过程程序被编译成二进制代码后放入硬盘。当程序执行时,将代码调入内存,放入内存的代码段。同时程序中的变量也会按变量类型在对应的内存段中分配内存。然后CPU会从代码段取出每一条指令进行执行。CPU在执行一条指令时,从指令中取出的是相对地址,需要经过寻址方式确定最终的逻辑地址。有了逻辑地址再经过地址映射找到逻辑地址对应的物理地址。那么问题是当被代码调入内存后,是什么时候为这个程序进行的内存分配?又是以什么样方式进行内存分配的?网上找到的答案如下:当执行这个EXE文件以后,此
YJ-Ma的小屋🍉
勿在浮沙筑高台