当前位置: 首页 > news >正文

leveldb的Compaction线程

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

1. leveldb的Compaction全局线程

在leveldb中,有一个全局的后台线程BGThread,用于数据库的MinorCompact与MajorCompact。
重点关注“全局线程”:
这个标识着无论一个进程打开多少个leveldb库,该Compact线程只有一个;
如果在一个程序中,打开了许多库在读写,多个库都触发了MinorCompact,那么这些MinorCompact将在Compact线程中依次执行;
也因为是全局线程,所以需要触发minorcompact的db线程,把db的this指针传递给Compact线程中来。

基于此,来看一下代码上的实现:

2. 任务Schedule部分,建立了一个创建一次的全局子线程

通过started_backgroud_thread_来标识是否已创建;
定义了一个std::thread backgroud_thread,并detach掉,形成一个全局的子线程;
把任务函数与参数放入到backgroud_work_queue_中;

void WindowsEnv::Schedule(void (*background_work_function)(void* background_work_arg),void* background_work_arg) {background_work_mutex_.Lock();// Start the background thread, if we haven't done so already.if (!started_background_thread_) {started_background_thread_ = true;std::thread background_thread(WindowsEnv::BackgroundThreadEntryPoint, this);background_thread.detach();}// If the queue is empty, the background thread may be waiting for work.if (background_work_queue_.empty()) {background_work_cv_.Signal();}background_work_queue_.emplace(background_work_function, background_work_arg);background_work_mutex_.Unlock();
}

3. 任务线程执行部分,不断的从队列中取任务函数与参数,并执行任务函数

从backgroud_work_queue_中取出任务函数与参数,执行函数;
其中为了避免queue中一直没有数据一直取的情况,使用了一个backgroupd_work_cv来在为空时等待;

static void BackgroundThreadEntryPoint(WindowsEnv* env) {env->BackgroundThreadMain();
}
void WindowsEnv::BackgroundThreadMain() {while (true) {background_work_mutex_.Lock();// Wait until there is work to be done.while (background_work_queue_.empty()) {background_work_cv_.Wait();}assert(!background_work_queue_.empty());auto background_work_function = background_work_queue_.front().function;void* background_work_arg = background_work_queue_.front().arg;background_work_queue_.pop();background_work_mutex_.Unlock();background_work_function(background_work_arg);}
}

4. 在需要触发Compact的地方,传入任务函数BGWork与当前库的指针

调用MaybeScheduleCompaction,在其中判定一个需要Compact的场景,排除掉一些不需要发起Compact的场景:

  • 已经在执行Compact的场景除外;
  • 已经关闭完毕的场景除外;
  • 该数据库后台已经有问题的场景除外;
  • 没有需要Compact的场景除外:没有待执行的Minorcompact+也没有待执行的手动Compaction+没有待执行的size-compaction/file-compaction;
void DBImpl::MaybeScheduleCompaction() {mutex_.AssertHeld();if (background_compaction_scheduled_) {// Already scheduled}else if (shutting_down_.load(std::memory_order_acquire)) {// DB is being deleted; no more background compactions}else if (!bg_error_.ok()) {// Already got an error; no more changes}else if (imm_ == nullptr && manual_compaction_ == nullptr &&!versions_->NeedsCompaction()) {// No work to be done}else {background_compaction_scheduled_ = true;env_->Schedule(&DBImpl::BGWork, this);}
}

4. 任务函数BGWork又做了什么呢?

BGWork是一层包装,直接调用数据db参数的方法BackgroundCall;

  • 里面又检查了一次数据库已经关闭的场景和数据库任务出错情况,因为从任务排到队列中,到排到任务执行,可能是要等一段时间的,在这个过程中,也可能条件改变了。
  • 接着执行BackgroundCompaction来做该db的Compaction;
  • 做完Compaction之后,把background_compaction_scheduled设定为false,以允许MaybeScheduleCompaction再次进入;
  • 接着就调用MaybeScheduleCompaction函数,再检查一边这个数据有没有待compaction内容未做完,例如这一次只做了MinorCompact,还有MajorCompact要做,再次去排队等执行;
  • 然后再来标识库的db后台任务项当前执行完了,发送一个信号background_work_finished_signal_;
    background_work_finished_signal_这个信号量通常用来通知写线程或关闭线程,通知该db的后台一项任务做完了,通知等待线程可以继续向后执行了。
void DBImpl::BGWork(void* db) {reinterpret_cast<DBImpl*>(db)->BackgroundCall();
}void DBImpl::BackgroundCall() {MutexLock l(&mutex_);assert(background_compaction_scheduled_);if (shutting_down_.load(std::memory_order_acquire)) {// No more background work when shutting down.}else if (!bg_error_.ok()) {// No more background work after a background error.}else {BackgroundCompaction();}background_compaction_scheduled_ = false;// Previous compaction may have produced too many files in a level,// so reschedule another compaction if needed.MaybeScheduleCompaction();background_work_finished_signal_.SignalAll();
}

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

相关文章:

leveldb的Compaction线程

个人随笔 (Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu) 1. leveldb的Compaction全局线程 在leveldb中&#xff0c;有一个全局的后台线程BGThread&#xff0c;用于数据库的MinorCompact与MajorCompact。 重点关注“全局线程”&#xff1a; 这个标识着无论一个进程打开…...

邪恶的想法冒出,立马启动python实现美女通通下

前言 嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! 完整源码、python资料: 点击此处跳转文末名片获取 当我在首页刷到这些的时候~ 我的心里逐渐浮现一个邪念&#xff1a;我把这些小姐姐全都采集&#xff0c;可以嘛&#xff1f; 答案当然是可以的~毕竟就我这技术&#xff0c…...

蓝桥杯刷题冲刺 | 倒计时18天

作者&#xff1a;指针不指南吗 专栏&#xff1a;蓝桥杯倒计时冲刺 &#x1f43e;马上就要蓝桥杯了&#xff0c;最后的这几天尤为重要&#xff0c;不可懈怠哦&#x1f43e; 文章目录0.知识点1.乳草的入侵今天写 搜索题 0.知识点 DFS 设计步骤 确定该题目的状态&#xff08;包括边…...

经典算法面试题——Java篇-附带赠书活动,评论区随机选取一人赠书

目录 一.图书推荐 二.说一下什么是二分法&#xff1f;使用二分法时需要注意什么&#xff1f;如何用代码实现&#xff1f; 三.什么是插入排序&#xff1f;用代码如何实现&#xff1f; 四.什么是冒泡排序&#xff1f;用代码如何实现&#xff1f; 五.什么是斐波那契数列&#…...

支持RT-Thread最新版本的瑞萨RA2E1开发板终于要大展身手了

支持RT-Thread最新版本的瑞萨RA2E1开发板终于要大展身手了 熟悉RT-Thread和瑞萨MCU的朋友都知道&#xff0c;当前RT-Thread仓库的主线代码是不支持RA2E1这个BSP的。刚好&#xff0c;最近我在联合瑞萨推广一个叫《致敬未来的攻城狮计划》&#xff0c;使用的就是RA2E1开发板&…...

【C语言进阶】 12. 假期测评①

day01 1. 转义字符的判断 以下不正确的定义语句是&#xff08; &#xff09; A: double x[5] {2.0, 4.0, 6.0, 8.0, 10.0}; B: char c2[] {‘\x10’, ‘\xa’, ‘\8’}; C: char c1[] {‘1’,‘2’,‘3’,‘4’,‘5’}; D: int y[53]{0, 1, 3, 5, 7, 9}; 【答案解析】 B 本…...

给程序加个进度条吧,1行Python代码,快速添加~

大家好&#xff0c;这里是程序员晚枫。 你在写代码的过程中&#xff0c;有没有遇到过以下问题&#xff1f; 已经写好的程序&#xff0c;想看看程序执行的进度&#xff1f; 在写代码批量处理文件的时候&#xff0c;如何显示现在处理到第几个文件了&#xff1f; &#x1f446…...

常见的Keil5编译报错及其原因和解决方法

以下是几种常见的Keil5编译报错及其原因和解决方法&#xff1a; "Error: L6218E: Undefined symbol"&#xff08;未定义符号错误&#xff09; 这通常是由于缺少对应的库文件或者代码中有未声明的变量或函数引起的。解决方法是检查相应的库文件是否已正确添加到工程中…...

Django 实现瀑布流

需求分析 现在是 "图片为王"的时代&#xff0c;在浏览一些网站时&#xff0c;经常会看到类似于这种满屏都是图片。图片大小不一&#xff0c;却按空间排列&#xff0c;就这是瀑布流布局。 以瀑布流形式布局&#xff0c;从数据库中取出图片每次取出等量&#xff08;7 …...

传输层协议----UDP/TCP

文章目录前言一、再谈端口号端口号的划分认识知名端口号(Well-Know Port Number)两个问题nestatpidof二、UDP协议UDP协议端格式UDP的特点面向数据报UDP的缓冲区UDP使用注意事项基于UDP的应用层协议二、TCP协议TCP协议段格式可靠性问题确认应答(ACK)机制流量控制六个标志位PSHUG…...

教你如何快速在Linux中找到某个目录中最大的文件

工作中经常会有查看某个目录下最大的文件的需求&#xff0c;比如在运维工作中&#xff0c;发现某个系统或功能不工作了&#xff0c;经排查发现是服务器空间满了…那么接下来就需要清理一下临时文件或者日志文件&#xff0c;或者其他不需要的文件&#xff0c;那么就会想要查看一…...

Java二叉树面试题讲解

Java二叉树面试题讲解&#x1f697;1.检查两颗树是否相同&#x1f695;2.另一颗树的子树&#x1f699;3.二叉树最大深度&#x1f68c;4.判断一颗二叉树是否是平衡二叉树&#x1f68e;5.对称二叉树&#x1f693;6.获取树中结点个数&#x1f691;7.判断一个树是不是完全二叉树&am…...

rancher2.6进阶之nfs动态创建pv配置

添加NFS client provisioner 动态提供K8s后端存储卷 1.1.前提说明 1.1.1.说明 NFS client provisioner 利用 NFS Server 给 Kubernetes 作为持久存储的后端,并且动态提供PV。 默认 rancher 2 的存储类中的提供者不包含NFS,需要手动添加;添加方式有两种: 1)从应用商店直接安…...

快速上手vue elementUI好看的登录界面

这是一个非常非常适合新手的vue登录界面&#xff0c;总体来说美观大气&#xff0c;axios那部分没有发&#xff0c;有需要的大家可以自己进行二次开发&#xff0c;继续编写。 用到了技术栈有 vue/cli 5.07 element-ui 2.15.9 适合入门级新手&#xff0c;展示下页面 emmm验证码…...

Vue趣味【Vue3+Element Plus+Canvas实现一个简易画板;支持导出为图片】

目录&#x1f31f;前言&#x1f31f;粉丝先看&#x1f31f;创建Vue3项目&#x1f31f;引入Element Plus&#x1f31f;实现代码&#xff08;详细注释&#xff09;&#x1f31f;写在最后&#x1f31f;JSON包里写函数&#xff0c;关注博主不迷路&#x1f31f;前言 哈喽小伙伴们&a…...

【Spring Cloud Alibaba】2.服务注册与发现(Nacos安装)

文章目录环境要求简介安装Nacos源码安装Docker安装数据库配置访问服务我们要搭建一个Spring Cloud Alibaba项目就绕不开Nacos&#xff0c;阿里巴巴提供的Nacos组件&#xff0c;可以提供服务注册与发现和分布式配置服务&#xff0c;拥有着淘宝双十一十几年的流量经验&#xff0c…...

深度学习 Day28——利用Pytorch实现好莱坞明星识别

深度学习 Day28——利用Pytorch实现好莱坞明星识别 文章目录深度学习 Day28——利用Pytorch实现好莱坞明星识别一、前言二、我的环境三、前期工作1、导入依赖项设置GPU2、导入数据集3、划分数据集四、调用官方的VGG16模型五、训练模型1、编写训练函数2、编写测试函数3、设置动态…...

Android中使用FCM进行消息推送

Firebase Cloud Message 的介绍 Firebase Cloud Message(FCM)是由Google推出的一种云端消息推送服务,它是由Google推出的Google Cloud Messaging(GCM)服务的升级版。在2016年5月,Google宣布将Google Cloud Messaging重命名为Firebase Cloud Message,作为Firebase的一部…...

从 X 入门Pytorch——BN、LN、IN、GN 四种归一化层的代码使用和原理

Pytorch中四种归一化层的原理和代码使用前言1 Batch Normalization&#xff08;2015年提出&#xff09;Pytorch官网解释原理Pytorch代码示例2 Layer Normalization&#xff08;2016年提出&#xff09;Pytorch官网解释原理Pytorch代码示例3 Instance Normalization&#xff08;2…...

Windows环境下实施域名访问的一些小知识

文章目录 前言一、windows域名访问流程二、网络域名访问配置设置DNS未正确设置DNS的结果三、本地hosts设置本地hosts本地hosts的优先机制本地hosts的内部访问次序示例一示例二总结前言 作为一种常见的操作系统,windows系统具有其特殊的域名访问管理机制。了解其访问机制,将有…...

地震勘探——干扰波识别、井中地震时距曲线特点

目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波&#xff1a;可以用来解决所提出的地质任务的波&#xff1b;干扰波&#xff1a;所有妨碍辨认、追踪有效波的其他波。 地震勘探中&#xff0c;有效波和干扰波是相对的。例如&#xff0c;在反射波…...

C++_核心编程_多态案例二-制作饮品

#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为&#xff1a;煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例&#xff0c;提供抽象制作饮品基类&#xff0c;提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

Spring Boot 实现流式响应(兼容 2.7.x)

在实际开发中&#xff0c;我们可能会遇到一些流式数据处理的场景&#xff0c;比如接收来自上游接口的 Server-Sent Events&#xff08;SSE&#xff09; 或 流式 JSON 内容&#xff0c;并将其原样中转给前端页面或客户端。这种情况下&#xff0c;传统的 RestTemplate 缓存机制会…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件&#xff1a; 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

AI Agent与Agentic AI:原理、应用、挑战与未来展望

文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例&#xff1a;使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例&#xff1a;使用OpenAI GPT-3进…...

论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)

笔记整理&#xff1a;刘治强&#xff0c;浙江大学硕士生&#xff0c;研究方向为知识图谱表示学习&#xff0c;大语言模型 论文链接&#xff1a;http://arxiv.org/abs/2407.16127 发表会议&#xff1a;ISWC 2024 1. 动机 传统的知识图谱补全&#xff08;KGC&#xff09;模型通过…...

什么是EULA和DPA

文章目录 EULA&#xff08;End User License Agreement&#xff09;DPA&#xff08;Data Protection Agreement&#xff09;一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA&#xff08;End User License Agreement&#xff09; 定义&#xff1a; EULA即…...

工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配

AI3D视觉的工业赋能者 迁移科技成立于2017年&#xff0c;作为行业领先的3D工业相机及视觉系统供应商&#xff0c;累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成&#xff0c;通过稳定、易用、高回报的AI3D视觉系统&#xff0c;为汽车、新能源、金属制造等行…...

Java + Spring Boot + Mybatis 实现批量插入

在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法&#xff1a;使用 MyBatis 的 <foreach> 标签和批处理模式&#xff08;ExecutorType.BATCH&#xff09;。 方法一&#xff1a;使用 XML 的 <foreach> 标签&#xff…...

LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf

FTP 客服管理系统 实现kefu123登录&#xff0c;不允许匿名访问&#xff0c;kefu只能访问/data/kefu目录&#xff0c;不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...