我正在开发 manjaro KDE,它的整个/
分区(当然 /boot/efi 分区除外)已格式化为 btrfs 文件系统,并且其写入时复制功能仍然是默认的。刚才,我正在按照 Arch wiki 安装 postgres,我注意到一些我不太明白的事情:
#https://wiki.archlinux.org/title/PostgreSQL
Warning:
If the database resides on a Btrfs file system, you should consider disabling Copy-on-Write for the directory before creating any database.
我在 Google 中搜索过,但我所看到的似乎告诉我 COW 会降低数据库的性能。但这是怎么发生的呢? COW 应该减少 I/O 延迟,不是吗?
PS 英语不是我的母语。可能存在一些语法错误。请原谅我。
祝你一切顺利。
答案1
有些人坚持认为 Btrfs 执行“写入时重定向”而不是“写入时复制”,因为 Btrfs 基于 Ohad Rodeh 提出的基于重定向的 B 树更新方案,并且因为使用以下命令更容易理解代码那种心态。
这样做的结果是写时复制将新数据写入其他地方并留下重定向。这会导致磁盘上的文件碎片。这个答案中有一个关于它的讨论:https://unix.stackexchange.com/a/395013/20140
当你将其与 postgresql 的行为(像大多数现代 DBMS 一样)结合起来时,结果是非常不可取的,因为 postgresql 会对非常大的文件进行大量“随机”写入。 btrfs 会使这些文件严重碎片化。
更糟糕的是 postgresql 已经非常优化了。它尝试计划其读取以引起最少量的磁盘寻道。在写入行时,它还尝试将收集的表数据保留在磁盘上的同一位置。如果将其文件分散在磁盘上,则会干扰其将读取数据收集在一起的能力,并最终减慢速度。
在postgresql中有一个进程叫做真空。 Vacuum 的工作之一是尝试将同一个表的数据大致收集在一起。如果您打开写时复制,此过程实际上可能会产生完全相反的效果,将数据广泛分布在磁盘上。
我还要指出的是,如果您使用非常快的 SSD 驱动器,碎片成本会有所降低,但仍然存在。
磁存储的成本是巨大的。磁盘可以通过微小的运动一次性读取许多MB。但如果数据碎片化,磁盘头必须“寻找”新位置,这需要很长时间(从计算角度来说)。