相关疑难解决方法(0)

磁盘扇区是否写入原子?

澄清问题:

当OS发送命令将扇区写入磁盘时它是原子的吗?即,如果电源在写入命令之后立即失败,则新数据的写入将完全成功或旧数据保持不变.我不关心多扇区写入会发生什么 - 撕裂的页面是可以接受的.

老问题:

假设您在磁盘上有旧数据X,您在其上写入新数据Y,并且在写入期间树落在电源线上.如果没有花哨的UPS或备用电池的磁盘控制器,最终可能会出现页面撕裂的情况,磁盘上的数据是X部分和Y部分.您是否最终会遇到磁盘上的数据是X部分,Y部分的情况和部分垃圾?

我一直在努力理解像数据库这样的ACID系统的设计,而且我的天真想法似乎是firebird,它不使用预写日志,依赖于给定的写入不会破坏旧数据(X) - 只能完全写入新数据(Y).这意味着如果要覆盖X的一部分,则只能更改被覆盖的X部分,而不是我们打算保留的部分X.

为了澄清,这意味着如果你有一个页面大小的缓冲区,说4096个字节,充满了一半Y,一半X,我们要保持 - 我们告诉OS编写过X该缓冲区,有严重的磁盘的任何事都不短在写入期间我们想要保留的半X被破坏的失败.

crash database-design acid

39
推荐指数
6
解决办法
7418
查看次数

内存映射文件和单个块的原子写入

如果我使用普通IO API读取和写入单个文件,则保证写入是基于每个块的原子.也就是说,如果我的write只修改了一个块,那么操作系统会保证写入整个块,或者根本不写入.

如何在内存映射文件上实现相同的效果?

内存映射文件只是字节数组,所以如果我修改字节数组,操作系统无法知道何时我认为写"完成",所以它可能(即使不太可能)在内存中交换内存我的块写操作的中间,实际上我写了半个块.

我需要某种形式的"进入/离开临界区",或"钉住"文件的页面到内存中,而我写它的一些方法.这样的事情存在吗?如果是这样,那可移植到常见的POSIX系统和Windows吗?

mmap acid atomic fwrite

13
推荐指数
1
解决办法
3168
查看次数

POSIX 方式执行 O_DIRECT?

直接 I/O 是复制较大文件的最高效方法,因此我想将这种功能添加到程序中。

WindowsFILE_FLAG_WRITE_THROUGHFILE_FLAG_NO_BUFFERINGWin32 的CreateFileA(). Linux 从 2.4.10 开始,.open()

有没有办法在 POSIX 中实现相同的可移植结果?就像 Win32 API 从 Windows XP 到 Windows 11 的工作方式一样,如果能够以一种可靠的可移植方式跨所有类 UNIX 系统进行直接 IO,那就太好了。

c linux io file-io posix

7
推荐指数
1
解决办法
973
查看次数

Linux:写入分为 512K 块

我有一个生成大 SCSI 写入的用户空间应用程序(详细信息如下)。然而,当我查看到达 SCSI 目标(即存储,由 FC 连接)的 SCSI 命令时,某些东西将这些写入拆分为 512K 块。

该应用程序基本上会直接向设备进行 1M 大小的直接写入:

fd = open("/dev/sdab", ..|O_DIRECT);
write(fd, ..., 1024 * 1024);
Run Code Online (Sandbox Code Playgroud)

此代码导致发送两个 SCSI WRITE,每个 512K。

但是,如果我发出直接 SCSI 命令,而没有块层,则不会拆分写入。我从命令行发出以下命令:

sg_dd bs=1M count=1 blk_sgio=1 if=/dev/urandom of=/dev/sdab oflag=direct
Run Code Online (Sandbox Code Playgroud)

我可以看到一个 1M 大小的 SCSI WRITE。

问题是,什么是拆分写入,更重要的是,它是否可配置?Linux 块层似乎是有罪的(因为 SG_IO 不通过它)并且 512K 似乎太随意了,不能成为某种可配置的参数。

linux kernel scsi block linux-kernel

5
推荐指数
1
解决办法
2202
查看次数

Linux/FreeBSD上的O_DIRECT与O_SYNC

我正在编写一个在Linux和FreeBSD上运行的程序,我想确保每次write()返回时数据实际写入物理设备上的文件,这样我的数据就不会意外丢失(例如,电力丢失,过程意外中断等).

根据OPEN(2)手册页,在Linux(高于2.6)上,O_DIRECT是同步但可能有性能问题; 在FreeBSD上,O_DIRECT不能保证同步,也可能有问题.

所以,在Linux上,无论是O_DIRECTO_SYNC保证同步写入,但哪一个具有更好的性能?

在FreeBSD上,为保证同步写入,哪个选项具有最佳性能:(1)O_DIRECT+ fsync()(2)O_DIRECT | O_SYNC或(3)O_SYNC单独?

c linux freebsd

5
推荐指数
1
解决办法
3774
查看次数

是“mmap教程”不正确,还是GCC错误编译了它?

这个15 年前的mmap 教程在 Google 搜索中排名很高,但实际上它在我的 Linux 系统上运行时出现了微妙的错误。

mmap_write.c:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>

#define FILEPATH "/tmp/mmapped.bin"
#define NUMINTS  (1000)
#define FILESIZE (NUMINTS * sizeof(int))

int main(int argc, char *argv[])
{
    int i;
    int fd;
    int result;
    int *map;  /* mmapped array of int's */

    /* Open a file for writing.
     *  - Creating the file if it doesn't exist.
     *  - Truncating it to 0 size if it already …
Run Code Online (Sandbox Code Playgroud)

c linux gcc mmap

1
推荐指数
1
解决办法
329
查看次数

标签 统计

linux ×4

c ×3

acid ×2

mmap ×2

atomic ×1

block ×1

crash ×1

database-design ×1

file-io ×1

freebsd ×1

fwrite ×1

gcc ×1

io ×1

kernel ×1

linux-kernel ×1

posix ×1

scsi ×1