首页 > 解决方案 > 在 C 中追加或创建文件时如何要求连续块(非碎片)?

问题描述

所以我想了解 DBMS 实现是如何工作的

举个例子:

MySQL 实现每个表都有自己的页面,即 16KB

所以每个表都是一个文件,并且是 16KB 的倍数,考虑到它有多大,因此需要多少页

现在我在某处读到这些页面不会在磁盘映像内存映像中碎片化,所以我的问题是,如何?

DBMS 开发人员如何告诉操作系统“嘿,我刚刚在这个文件中添加了一个 16KB 的数据(页面),但是让这个页面不会碎片化”

是因为内存映像实际上并没有显示字节是如何真正存储在磁盘上的吗?

还是因为这些 DBMS 以某种方式要求操作系统确保这些 16KB 字节的块不会碎片化?

以及如何在 C 中做到这一点?

标签: mysqlcdatabaseoperating-systeminnodb

解决方案


50 年前,您的问题是计算机科学与工程领域的热门话题。但不是今天。

几乎每个硬盘驱动器都有一个 512 字节的分配单元。CD 的 AU 为 2KB。某些 SSD 在针对 MySQL 进行调整时,其 AU 为 16KB。

有许多不同的“文件系统”。Windows (至少)有 FAT-32 和 NTFS。*nix 有很多。每个 FS 都以在某件事上做得更好而自豪。但是自由空间管理与分配单元大小作斗争。还记得当磁盘变得越来越大时 DOS 使用 FAT-16 时遇到的麻烦吗?名称中的“16”是指最多有 2^16 个块的磁盘。这迫使一个 2GB 的磁盘驱动器有一个 32KB 的分配单元!典型的系统有很多小文件,几乎一半的磁盘可能被浪费了!

我说的是“分配单元”,因为这本质上是防止操作系统考虑将块分散在驱动器周围的唯一方法。

让我们从营销的角度来看您的问题。如果碎片化是一件大事,那么

  1. 新的、更好的文件系统将会出现来解决这个问题——尽管不一定以你提到的简单方式。
  2. 操作系统已经知道这个问题,所以他们有办法“尝试”分配块。但他们总是愿意在必要时给你一些小东西。
  3. MySQL 的 InnoDB(大约 2000 年)付出了很多努力来分配 4MB(?)的“范围”,以期获得连续分配的磁盘。但是当它失败时,什么都不会崩溃。
  4. 软件会绕过这个问题,例如使用“原始驱动器访问”。但请注意,这不是“如何优化数据库”的最前沿?如果有的话,它被埋在“哦,顺便说一句”一章中.

几十年前,有一些操作系统可以让你预先分配一个“连续”的文件。我最近没有听说过这样的。

企业系统通过使用带有电池支持写入缓存的硬件 RAID 控制器解决了这个问题。不仅分散聚集对用户隐藏,而且由于崩溃安全缓存,写入变得“即时”。

SSD 没有任何寻道时间(与 HDD 不同),因此块是否被切碎并不重要。当然,有一些代码可以处理它,但与传输、校验和、互斥锁、系统调用等时间相比,这真的微不足道。

我有一个经验法则:如果一个潜在的优化看起来不会有 10% 的帮助,我会放弃它并继续做其他事情。我建议你继续前进。


推荐阅读