[LevelDB]LevelDB版本管理的黑魔法-為什么能在不鎖表的情況下管理數據?

文章摘要

  1. LevelDB的日志管理系統是怎么通過雙鏈表來進行數據管理
  2. 為什么LevelDB能夠在不鎖表的情況下進行日志新增

適用人群:

  1. 對版本管理機制有開發訴求,并且希望參考LevelDB的版本開發機制。
  2. 數據庫相關從業者的專業人士。
  3. 計算機狂熱愛好者,對計算機的存儲機制有強烈技術追求的同志。

閱讀建議:

  1. 作者本人功底有限不太可能考慮到所有讀者的閱讀細節,建議讀者先通盤閱讀下本文,先熟悉本文中會出現哪些關鍵概念和關鍵流程,并配合上AI工具對文章中個別流程進行細致理解。

LevelDB版本管理機制

核心抽象

在這里插入圖片描述
主要分為

  1. 版本管理層:版本抽象相關的操作和邏輯。
  2. 文件管理層: 主要和文件磁盤上的物化數據打交道。
  3. 快照管理層:依托快照對外暴露固化查詢的服務。
抽象職能
Version版本管理的最小單位,維護特定時刻的數據庫狀態,管理文件集合
VersionSet版本集合管理器,負責管理所有版本,維護當前版本,處理版本切換
VersionEdit版本變更記錄,記錄版本間的差異,支持變更的序列化和反序列化
Builder版本構建器,負責構建新版本,應用版本變更
Compaction壓縮任務管理,處理文件壓縮,生成新的版本變更
FileMetaData文件元數據,記錄文件的基本信息(大小、范圍等)
Manifest清單文件管理,持久化版本信息,支持數據庫恢復
Snapshot數據庫某一時刻的快照,提供一致性讀取視圖,基于序列號實現
SnapshotList快照列表管理,維護所有活躍的快照,管理快照的生命周期

這里面的重點是:

  • Version是整個版本管理機制的最小單元抽象
  • compaction 的機制非常復雜,本文不贅述,感興趣移步: [LevelDB]揭秘LevelDB暗藏的合并秘技,Compaction內部的超神操作讓工程師都驚呆了!

版本管理層(Version)核心邏輯

在這里插入圖片描述

  1. 客戶端向VersionSet抽象請求版本變更操作
  2. VersionSet 通過創建VersionEdit來記錄一些當前操作的變更
  3. 使用Build模式來創建新版本并更新當前的版本

亮點設計:

  1. 使用新建Version的方式來實現無鎖讀取,簡化并發控制。
  2. 使用Builder(構建者模式)來進行構建,對代碼進行解耦。
  3. 使用VersionEdit進行增量更新,并且能夠通過VersionEdit來進行日志記錄。

源代碼細節說明

客戶端(通常理解是應用LevelDB的機器)調用LevelDB的LogAndApply接口來進行版本新增

// 調用入口
s = versions_->LogAndApply(&edit, &mutex_);

簡單來說,就是生成一個新的版本Version,并添加到當前的版本管理鏈表中。
在這里插入圖片描述
LogAndApply方法主要有以下的核心階段(流程圖見下文

  • 初始化一些必要參數,如log_number_(日志編號: 用于后續清理WAL無用日志), file_number(文件編號-用于實現文件的唯一性),Sequence(用于實現序列號唯一性)
    在這里插入圖片描述
    源碼參考:
  // 日志版本號-用于實現WAL 預寫入機制-用于清理當時用不了的文件if (edit->has_log_number_) {assert(edit->log_number_ >= log_number_);assert(edit->log_number_ < next_file_number_);} else {edit->SetLogNumber(log_number_);}if (!edit->has_prev_log_number_) {edit->SetPrevLogNumber(prev_log_number_);}// file_number 文件編號-用于實現文件的唯一性  // sequence: 用于控制序列唯一性edit->SetNextFile(next_file_number_);edit->SetLastSequence(last_sequence_);
  • 構建新版本(包括對版本的壓縮打分)
    在這里插入圖片描述
  1. 創建新版本 -亮點: 使用Builder模式來構建新版本
  2. Apply 方法 用于根據edit中的信息來生成對應的build構造器
  3. SaveTo 方法 用于將build構造器中的信息應用到新的version中
  Version* v = new Version(this);{Builder builder(this, current_);builder.Apply(edit);builder.SaveTo(v);}// 計算 最佳壓縮層級Finalize(v);
  • MANIFEST處理階段, 這里的MANIFEST
    在這里插入圖片描述
 // MANIFEST 文件處理std::string new_manifest_file;Status s;if (descriptor_log_ == nullptr) {// 日志assert(descriptor_file_ == nullptr);// 底層文件操作new_manifest_file = DescriptorFileName(dbname_, manifest_file_number_);s = env_->NewWritableFile(new_manifest_file, &descriptor_file_);if (s.ok()) {descriptor_log_ = new log::Writer(descriptor_file_);// 寫入快照-本質上是向 Manifest 日志中寫入當前的文件狀態,防止記錄丟失s = WriteSnapshot(descriptor_log_);}}
  • 文件同步階段
    在這里插入圖片描述
{mu->Unlock();if (s.ok()) {std::string record;edit->EncodeTo(&record);s = descriptor_log_->AddRecord(record);if (s.ok()) {s = descriptor_file_->Sync();}if (!s.ok()) {Log(options_->info_log, "MANIFEST write: %s\n", s.ToString().c_str());}}if (s.ok() && !new_manifest_file.empty()) {s = SetCurrentFile(env_, dbname_, manifest_file_number_);}// 重新獲取鎖mu->Lock();}
  • 完成安裝階段
    在這里插入圖片描述
// 讓基于VersionEdit和老版本if (s.ok()) {// 將新版本添加到版本鏈表AppendVersion(v);// 更新日志文件號log_number_ = edit->log_number_;prev_log_number_ = edit->prev_log_number_;} else {//  快照寫入失敗delete v;if (!new_manifest_file.empty()) {// 清理新創建的 MANIFEST 文件相關資源delete descriptor_log_;delete descriptor_file_;descriptor_log_ = nullptr;descriptor_file_ = nullptr;env_->RemoveFile(new_manifest_file);}}return s;
}

猜你喜歡

C++多線程: https://blog.csdn.net/luog_aiyu/article/details/145548529
一文了解LevelDB數據庫讀取流程:https://blog.csdn.net/luog_aiyu/article/details/145946636
一文了解LevelDB數據庫寫入流程:https://blog.csdn.net/luog_aiyu/article/details/145917173
關于LevelDB存儲架構到底怎么設計的:https://blog.csdn.net/luog_aiyu/article/details/145965328?spm=1001.2014.3001.5502

PS

你的贊是我很大的鼓勵
我是darkchink,一個計算機相關從業者&一個摩托佬&AI狂熱愛好者
本職工作是某互聯網公司數據相關工作,歡迎來聊,內推或者交換信息
vx 二維碼見: https://www.cnblogs.com/DarkChink/p/18598402

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/81429.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/81429.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/81429.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【C++進階篇】C++容器完全指南:掌握set和map的使用,提升編碼效率

C容器的實踐與應用&#xff1a;輕松掌握set、map與multimap的區別與用法 一. 序列式容器與關聯式容器1.1 序列式容器 (Sequential Containers)1.2 關聯式容器 (Associative Containers) 二. set系列使用2.1 set的構造和迭代器2.2 set的增刪查2.2.1 插入2.2.2 查找2.2.3 刪除 2.…

2_Spring【IOC容器中獲取組件Bean】

Spring中IOC容器中獲取組件Bean 實體類 //接口 public interface TestDemo {public void doSomething(); } // 實現類 public class HappyComponent implements TestDemo {public void doSomething() {System.out.println("HappyComponent is doing something...")…

安卓開飯-ScrollView內嵌套了多個RecyclerView,只想與其中一個RecyclerView有聯動

在 Android 開發中&#xff0c;將 RecyclerView 嵌套在 ScrollView 內通常會導致性能問題和滾動沖突&#xff0c;應盡量避免這種設計。以下是原因和替代方案&#xff1a; 為什么不推薦 RecyclerView ScrollView&#xff1f;?? 性能損耗? RecyclerView 本身已自帶高效回收復…

HTTP 請求中 Content-Type 頭部

HTTP 請求中 Content-Type 頭部可以設置的各種不同的傳輸格式。multipart/form-data 只是其中一種,主要用于傳輸包含文件的數據。 以下是一些常見的 HTTP 請求體的 Content-Type 及其用途: 常見的數據傳輸格式 (Content-Type) 列表: application/json: 描述: 用于傳輸 JSO…

【U-boot 命令使用】

文章目錄 1 查詢有哪些命令2 信息查詢命令dbinfo - 查看板子信息printenv- 輸出環境變量信息version - 輸出uboot版本信息 3 環境變量操作命令修改環境變量新建環境變量刪除環境變量 4 內存操作命令md命令nm命令mm命令mv命令cp命令cmp命令 5 網絡操作命令與網絡有關的環境變量p…

初學者如何用 Python 寫第一個爬蟲?

初學者如何用 Python 寫第一個爬蟲&#xff1f; 一、爬蟲的基本概念 &#xff08;一&#xff09;爬蟲的定義 爬蟲&#xff0c;英文名為 Web Crawler&#xff0c;也被叫做網絡蜘蛛、網絡機器人。想象一下&#xff0c;有一個勤勞的小蜘蛛&#xff0c;在互聯網這個巨大的蜘蛛網中…

IDE/IoT/搭建物聯網(LiteOS)集成開發環境,基于 VSCode + IoT Link 插件

文章目錄 概述IDE安裝安裝舊版本VSCode安裝插件安裝問題和解決手動安裝SDK包手動下載依賴工具 IoTLink配置IoTLink Home用戶設置-工具鏈-編譯器用戶設置-工具鏈-構建器用戶設置-工具鏈-燒錄器用戶設置-SDK管理工程設置-SDK配置工程設置-編譯器工程設置-調試器 創建工程Demo 源碼…

深度剖析:Dify+Sanic+Vue+ECharts 搭建 Text2SQL 項目 sanic-web 的 Debug 實戰

目錄 項目背景介紹sanic-web Dify\_service handle\_think\_tag報錯NoneType問題描述debug Dify調用不成功&#xff0c;一直轉圈圈問題描述debug 前端markdown格式只顯示前5頁問題描述debug1. 修改代碼2.重新構建1.1.3鏡像3.更新sanic-web/docker/docker-compose.yaml4. 重新部…

理想AI Talk第二季-重點信息總結

一、TL&#xff1b;DR 理想為什么要做自己的基模&#xff1a;座艙家庭等特殊VLM場景&#xff0c;deepseek/openai沒有解決理想的基模參數量&#xff1a;服務端-300B&#xff0c;VLencoder-32B/3.6B&#xff0c;日常工作使用-300B&#xff0c;VLA-4B為什么自動駕駛可以達成&…

TensorRT

TensorRT 下載 TensorRT 7.1.3.4 TAR壓縮包&#xff0c;解壓到安裝目錄&#xff1a; tar xzvf TensorRT-7.1.3.4.Ubuntu-16.04.x86_64-gnu.cuda-11.0.cudnn8.0.tar.gz 添加 TensorRT lib 到環境變量&#xff1a; gedit ~/.bashrc # 添加 export LD_LIBRARY_PATH$LD_LIBRARY_PAT…

【NGINX】 -9 nginx + tomcat實現的多級反向代理

文章目錄 1、tomcat的安裝 (centos版本)1.1 安裝Java依賴環境1.2 安裝tomcat 2、tomcat的虛擬主機的配置2.1 配置多級目錄 3、利用nginx的反向代理實現將轉發指向一個虛擬機3.1 nginx服務器的配置3.2 客戶端配置 4、 反向多級代理代理服務器操作nginx 1 服務器nginx 2 服務器to…

基于requests_html的python爬蟲

前言&#xff1a;今天介紹一個相對性能更高的爬蟲庫requests_html&#xff0c;會不會感覺和requests有點聯系&#xff1f;是的。為什么開始不直接介紹呢&#xff1f;因為我覺得requests是最基本入門的東西&#xff0c;并且在學習過程中也能學到很多東西。我的python老師在介紹這…

【架構篇】架構類型解釋

架構設計的本質&#xff1a;從模糊概念到系統化思維 摘要 “架構”是系統設計的靈魂&#xff0c;但許多人對它的理解仍停留在抽象層面。本文系統解析架構的8大核心維度&#xff0c;結合設計原則、案例與誤區分析&#xff0c;幫助開發者建立從戰略到落地的完整認知框架。 一、架…

用Python繪制夢幻星空

用Python繪制夢幻星空 在這篇教程中&#xff0c;我們將學習如何使用Python創建一個美麗的星空場景。我們將使用Python的圖形庫Pygame和隨機庫來創建閃爍的星星、流星和月亮&#xff0c;打造一個動態的夜空效果。 項目概述 我們將實現以下功能&#xff1a; 創建深藍色的夜…

PyTorch循環神經網絡(Pytotch)

文章目錄 循環神經網絡&#xff08;RNN&#xff09;簡單的循環神經網絡長短期記憶網絡&#xff08;LSTM&#xff09;門控循環單元&#xff08;GRU&#xff09; 循環神經網絡&#xff08;RNN&#xff09; 循環神經網絡&#xff08;RecurrentNeuralNetwork&#xff0c;RNN&#…

用算術右移實現邏輯右移及用邏輯右移實現算術右移

函數srl()用算術右移實現邏輯右移&#xff0c;函數sra()用邏輯右移實現算術右移。 程序代碼 int sra(int x,int k); unsigned int srl(unsigned int x, int k);void main() {int rx1,k,x1;unsigned int rx2,x2;k3;x10x8777;x20x8777;rx1sra(x1, k);rx2srl(x2, k);while(1); }…

pojo層、dao層、service層、controller層的作用

在Java Web開發中&#xff0c;常見的分層架構&#xff08;如Spring Boot項目&#xff09;通常包含POJO層、DAO層、Service層和Controller層&#xff0c;各層職責明確&#xff0c;協同工作。以下是各層的作用及相互關系&#xff1a; 1. POJO層&#xff08;Model/Entity層&#…

【Linux網絡】五種IO模型與阻塞IO

IO 在Linux網絡環境里&#xff0c;IO&#xff08;Input/Output&#xff09;指的是網絡數據在系統與外部網絡&#xff08;像其他設備、服務器或者客戶端&#xff09;之間進行傳輸的過程。 它是網絡編程和系統性能優化的核心內容。 IO &#xff1a;INPUT和OUTPUT&#xff08;站…

入門OpenTelemetry——應用自動埋點

埋點 什么是埋點 埋點&#xff0c;本質就是在你的應用程序里&#xff0c;在重要位置插入采集代碼&#xff0c;比如&#xff1a; 收集請求開始和結束的時間收集數據庫查詢時間收集函數調用鏈路信息收集異常信息 這些埋點數據&#xff08;Trace、Metrics、Logs&#xff09;被…

大數據場景下數據導出的架構演進與EasyExcel實戰方案

一、引言&#xff1a;數據導出的演進驅動力 在數字化時代&#xff0c;數據導出功能已成為企業數據服務的基礎能力。隨著數據規模從GB級向TB級甚至PB級發展&#xff0c;傳統導出方案面臨三大核心挑戰&#xff1a; ?數據規模爆炸?&#xff1a;單次導出數據量從萬級到億級的增長…