首页 > 数据库 >关于在数据库系统MMAP的使用

关于在数据库系统MMAP的使用

时间:2023-09-05 19:33:24浏览次数:44  
标签:操作系统 MMAP 关于 问题 页表 数据库系统 页面 内存

问题引出

在数据库系统中对于文件I/O管理,通常有两种选择

  • 开发者自己实现buffer bool来管理文件I/O读入内存的数据
  • 使用Linux操作系统实现的MMAP系统调用映射到用户地址空间,并且利用对开发者透明的page cache来实现页面的换入换出

理论介绍

 

  1. 程序调用MMAP返回了指向文件内容的指针
  2. 操作系统保留了一部分虚拟地址空间,但是并没有开始加载文件
  3. 程序开始使用指针获取文件的内容
  4. 操作系统尝试在物理内存获取内存页
  5. 由于内存页此时不存在,因此触发了页错误,开始从物理存储将第3步获取的那部分内容加载到物理内存页中
  6. 操作系统将虚拟地址映射到物理地址的页表项(Page Table Entry)加入到页表中
  7. 上述操作使用的CPU核心会将页表项加载到页表缓存(TLB)中

mmap的问题

问题1 事务安全

由于MMAP中页面写回存储的时机不受程序控制,因此当commit还没有发生时,可能会有一部分脏页面已经写回存储了。此时原子性就会失效,在过程中的查询会看到中间状态。

问题2 I/O停顿

由于MMAP将文件加载到内存的过程是操作系统控制的,所以无法保证将要查询的页面在内存中,这时就会出现page cache的换入换出,导致I/O停顿。

问题3 错误处理

首先是MMAP对文件内容的校验要以单个页面为单位,不能基于多个页面来做,因为有可能要使用的页面会被换出。另外,对于一些使用内存不安全语言写的数据库系统(感觉大部分都是用内存不安全的C++写的),指针错误可能导致页面问题。使用buffer pool可以通过写入前的检查规避这个问题,但是MMAP会默默将错误的页面写到存储中。

还有,MMAP要应对的系统调用会出现的SIGBUS信号报错,相比之下使用其他I/O方式的buffer pool就能比较轻松的处理I/O错误。

问题4 性能问题

业界里面大家普遍认为MMAP比传统read/write更快,这主要基于以下两点原因:
  1. 负责文件映射操作,并且处理page fault的是内核,而不是应用程序
  2. MMAP帮助避免了用户空间中的额外的复制操作,相应的也减少了内存的占用

MMAP相对于传统read/write I/O在目前高带宽的存储设备上是更差的。,原因如下:

  1. 单线程的页面换出: 页面换出是单线程的(使用kswapd),这点与CPU相关
  2. TLB shootdowns 当一个页面失效时,每个核心的TLB都需要一次中断来做刷新操作,这个操作可能会消耗几千个时钟周期,是非常耗时的。

RavenDB的CEO Reply

在构建数据库时,使用 mmap 具有以下优点,操作系统将负责:

  • 从磁盘读取数据
  • 读取相同数据的不同线程之间的并发性
  • 缓存和缓冲区管理
  • 从内存中逐出页
  • 与机器中的其他进程很好地配合
  • 跟踪脏页并写入磁盘

对于 mmap 版本,我们需要计算页面的地址,仅此而已。对于手动缓冲池,我们需要处理的任务列表很长。其中一些要求我们确保线程安全。例如,如果我们将一个页面交给一个事务,我们需要跟踪该页面的状态是否正在使用中。在交易完成之前,我们无法逐出此页面。这意味着我们可能需要进行原子引用计数,这可能会非常高的成本。

实际上,数据库中的数据访问实际上并不是随机的,即使您正在执行随机读取也是如此。有些页面几乎总是会被引用。B+树中的根页面就是一个很好的例子。它总是会被使用。在原子引用计数下,该页面将成为瓶颈。

忽略缓冲池管理的这种开销意味着您实际上并没有比较等效的结构。我还应该指出,我可能忘记了缓冲池还需要管理的其他一些任务,这使它的生命周期大大复杂化。 这一点的原因是那里有一个互斥锁(以及锁下的 I/O),这对于许多缓冲池来说是相当典型的。不考虑缓冲池管理的开销会严重扭曲论文的结果。

解决4个问题

问题1 事务安全

作者并不在乎数据是否在我背后写入内存,而关心的是 MVCC(一个与缓冲区管理完全分开的问题)

当事务提交并且较旧的事务不再需要旧版本的数据时,我可以将数据从修改后的缓冲区推送到 mmap 区域。这往往相当快(考虑到我基本上是在做 memcpy(),它以内存速度运行),除非必须将数据分页

问题2 I/O停顿

作者实际措施是用一个专用线程来处理这种情况。实际上,这与使用异步 I/O 处理它的方式并没有太大区别。

另一个要处理的考虑因素是在内核级别映射的成本。我不是在谈论 I/O 成本,但是如果您有许多线程出错页面,则会遇到页表锁定问题。我们之前遇到过这种情况,这被认为是操作系统级别的错误,但它显然对数据库有影响。但实际上,在大多数情况下,内存管理的开销是相同的。如果您通过 mmap 阅读或直接分配,则需要编排一些事情。请注意,如果您正在大量分配/释放,则相同的页表锁定也会生效,因为您也在修改流程页表。

问题3 错误处理

作者认为对于数据库,处理 I/O 错误只有一个正确答案。崩溃,然后从头开始运行恢复。如果 I/O 系统返回了错误,则不再有任何方法可以知道该错误的状态。恢复的唯一方法是停止,重新加载所有内容(应用 WAL、运行恢复等)并恢复到稳定状态。

问题4 性能问题

  1. 页表争用
  2. 单线程页面逐出
  3. TLB击落

第一个问题是我过去遇到过的问题。这是操作系统中的一个错误,已修复。在Windows和Linux中不再有单页表。

另一方面,单线程驱逐是我们从未遇到过的事情。使用 Voron,我们使用MAP_SHARED映射内存,大多数时候,内存并不脏。如果系统需要内存,则只需丢弃未修改的共享页面的内存即可在分配页面时执行此操作。在此模型中,我们通常将大部分内存视为共享的、干净的。因此,驱逐事物的压力并不大,可以根据需要进行。

TLB击落问题不是我们曾经遇到过的问题。我们已经在具有4GB RAM的Raspberry PI上运行TB范围数据库,并在基准测试中对其进行了测试(远远超过内存容量)。有趣的是,B+Tree 性质意味着树的上层已经在内存中,所以我们最终每个请求都有一个页面错误。为了以显着的方式实际观察TLS击落的成本,您需要具备:

  • 非常快的 I/O
  • 显著超出内存的工作集
  • 无需执行其他处理请求的工作

标签:操作系统,MMAP,关于,问题,页表,数据库系统,页面,内存
From: https://www.cnblogs.com/sulnyann/p/17680604.html

相关文章

  • 关于博客园最近情况的一些思考
    今天回到家,我在犇犇中偶然得知博客园要倒了,原因是资金不足。博客园作为一个没有广告的网址,我觉得很赞,但是这也直接导致了博客园的收益很小。博客园能走到现在都是一个奇迹,它能不能接续走下去,取决于大家的支持,所以,充会员吧!这是对博客园的唯一支持。博客园的唯一收入来源好像就是......
  • 关于Hystrix
    在使用Hystrix来实现断路器模式时,可以通过自定义隔离策略来定制隔离行为。Hystrix提供了默认的线程隔离和信号量隔离两种策略,但你可以根据自己的需求来定义自己的隔离策略。以下是一个简单的示例,演示如何自定义Hystrix的隔离策略。在这个示例中,我们将创建一个自定义的隔离策略,该......
  • 微信小程序关于用户隐私政策调整相关的开发配置流程
    前言:最近,微信小程序的开放内容调整属于是比较频繁的,先前有授权微信手机号不在免费转为收费,而在2023年9月15日前,获取一些隐私信息需要弹框请求用户授权;在此日期之后,微信的隐私政策进行了调整,需要在用户授权的同时要求用户先同意《用户隐私协议》内容后方可进行微信隐私内容获取......
  • 4分布数据库系统
    全局外模式全局概念模式分片模式分布模式局部概念模式局部内模式局部数据库 分布透明性分片透明性:分不分片,用户感受不到:水平分片、垂直分片、混合分片位置透明性:数据存放在哪里,用户不用管局部数据模型透明性(逻辑透明):用户不用关系局部数据模型分布式数据库管理系统组......
  • 关于前后端交互,取header的尴尬
    背景:最近在写一个接口的时候,需求是这样的,上传excel,匹配项目有多少个字段匹配上了,如果匹配上了在单元格上标注绿色背景,然后返回excel文件和匹配的详细。首先这个excel文件,后端是不会去保存的,所以无法直接返回文件链接,然后需要返回一个json,告诉前端有多少行是匹配上了的,中匹配多少......
  • 关于exgcd的总结
    关于exgcd的总结我们主要讨论的是\(ax+by=c\)1.exgcd算法1.1关于解的存在性有裴蜀定理知,对于方程\(ax+by=c\)存在解的充分必要条件是:\((a,b)|c\)tips:裴蜀定理如果\(a,b\)均为整数,则有整数\(x,y\)使得\(ax+by=\gcd(a,b)\),这个等式称为裴蜀等式。1.2exgcd算法介绍要求\(a......
  • 关于synchronized
    关于synchronizedsynchronized是java中的关键字,可以在需要线程安全的业务场景中进行使用,保证线程安全,它是利用锁机制来实现同步的。synchronized锁对象和锁类对象锁:每个实例都会有一个monitor对象,即Java对象的锁,类的对象可以有多个,所以每个对象有其独立的对象锁,互不干扰......
  • 关于使用new Integer还是Integer.valueOf的研究
    作者:fbysss前言:最近看到这样的说法:使用Integer.valueOf代替newInteger更有效率,原因是研究了Integer源码,发现有一个缓存可以利用。对此我也一探究竟。发现这其实与Java的自动装箱拆箱有关,直接使用Integeri=数值的方式即可。通过字节码研究是比较有效的方式。那我们来看看吧:-----......
  • 关于NFC、谷歌钱包的理解
    NFC:NearFieldCommunication即近距离通讯技术RFID(RadioFrequencyIDentification)技术,又称电子标签、无线射频识别,公交卡就是使用这种技术。NFC传输范围较小,安全、低功耗RFID是一种识别技术,而NFC是一种交互的通信方式。有人说,NFC是RFID的一种改良版本。目前智能手机将支持NFC,也......
  • 关于JVM的server/client版本
     区别:Client启动快些,Server版进行了优化,运行会快一些,但启动会慢些。查看当前JVM版本:java-version位置:jre/bin/server  jre/bin/client两个jvm文件大小都不一样。如果没有指定JVM版本,会自动根据OS和硬件环境进行识别。windows下默认是client,Unix下,会进行Server-ClassMachine......