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

这篇具有很好参考价值的文章主要介绍了关于在数据库系统MMAP的使用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

问题引出

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

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

理论介绍

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

 

  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击落的成本,您需要具备:文章来源地址https://www.toymoban.com/news/detail-695054.html

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

到了这里,关于关于在数据库系统MMAP的使用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 关于初识MySQL数据库以及MySQL的基本使用

    数据库一般是指: 在磁盘或者内存中存储的特定结构组织的数据 。 其本质可以理解为: 对数据内容存储的一套解决方案,对数据库提供要求或字段,它会给用户返回结果 MySQL是 一套给用户提供数据存取的服务,是一种网络程序 那么在系统中会存在mysql和mysqld,如何区分两

    2024年02月16日
    浏览(45)
  • MongoDB 数据库数据导入 - 关于如何使用 csv 导入数据的命令方法、图形界面可视化导入方法

    兴趣使然,突发奇想,想到了就写,就当打发时间了。 csv文件路径问题,绝对路径和相对路径都可以 type 没有=号,也是可以的,空格自动识别 将 测试表.csv 文件导入到 mongodatabase 库, mycollection 集合中,导入时必须指定列名称 (如果 csv 文件第一行是列名称,也会被当成数据

    2023年04月22日
    浏览(46)
  • Mysql 数据库时间与系统时间不一致问题排查

    在我们学习中使用到sysdate这个函数时,发现查出来的日期时间与当前的正确时间不一致,相差8个小时左右,为什么会产生这个问题?又该如何解决? – 在数据库中使用sysdate()函数查询系统时间 select sysdate(); 结果显示: 原因分析1:第一时间想到的是数据库所在的云服务器时

    2024年02月06日
    浏览(45)
  • ORACLE 10G版本数据库系统产生大量归档日志问题的分析

    近期接到用户告知 数据库归档暴增,导致生产库归档空间满,手动删除后,归档空间很快就会满。 立即登陆数据库系统,查询发现归档日志异常增长,从以前的每小时产生3 00M ,增长到每小时产生5 9150M 。拉取问题时段的A WR 报告,将问题S QL 提交给应用运维人员,应用修复

    2024年02月03日
    浏览(34)
  • 【Flask 连接数据库,使用Flask-Migrate实现数据库迁移及问题汇总】

    Flask 连接数据库,使用Flask-Migrate实现数据库迁移 安装Flask-Migrate插件 使用Flask-Migrate步骤 app.py主要用于数据库连接 model.py 中导入了 db,作用是存储一个User类 ,用于生成表头。 manager.py用于数据迁移管理,运行后将生成一个文件夹。 Flask-Migrate运行 问题汇总 问题一:flask_mig

    2024年01月16日
    浏览(35)
  • 使用达梦数据库遇到的异常问题

    dm.jdbc.driver.DMException: 数据转换丢失警告 我这里出现问题的SQL语句是: 原因 :是因为list集合中 rz 字段的数据超出的达梦库设置字段类型DEC(7,3)的长度。 dm.jdbc.driver.DMException: 数据未找到 在使用达梦数据库批量插入或更新数据时,给我报了一个从来没有遇到过的错误,当时我

    2024年02月13日
    浏览(33)
  • 解决使用php将excel数据导入数据库报错问题

    今天在用 phpexcel 将数据xlxs数据导入到数据库发现一直报错 Array and string offset access syntax with curly braces is no longer supported 百度下发现PHP7.4后面版本,不再能够使用花括号来访问数组或者字符串的偏移,而我当前php版本是8.1 没办法根据他这个报错 一步一步找到对应的文件将{} 修改

    2024年04月10日
    浏览(45)
  • Spring Boot使用jasypt处理数据库账号密码等数据加密问题

    在我们业务场景中,项目中的application.yml 配置文件比如数据库账号密码,的各种链接的username,password的值都是明文的,存在一定的安全隐患,可以使用jasypt 加密框架的方式进行明文加密,进而使得我们项目更加安全 注意这里排除了mybatis-plus的包可能是项目中有冲突依赖,

    2024年02月06日
    浏览(42)
  • 使用MariaDB数据库管理系统

    初始化MariaDB服务 //再确认mariadb数据库软件程序安装完毕并成功启动后请不要立即使用。为了确保数据库的安全性和正常运转,需要做以下5个操作 1.设置root管理员在数据库中的密码值(该密码并非root管理员在系统中的密码,这里的密码值默认应该为空) 2.设置root管理员在数据

    2024年02月19日
    浏览(38)
  • 关于运维·关于数据库面试题

    目录 一、数据库类型 二、数据库引擎 三、mysql数据库类型 四、mysql的约束添加 五、主从复制原理 六、主从方式有几种 七、mysql主从数据不一致的原因 八、mysql的优化 九、什么是事务的特征 十、数据库读写分离的好处 十一、怎样优化sql语句 十二、mysql的同步方式 十三、m

    2024年01月21日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包