当前位置:  开发笔记 > 编程语言 > 正文

磁盘扇区是否写入原子?

如何解决《磁盘扇区是否写入原子?》经验,为你挑选了5个好方法。

澄清问题:

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

老问题:

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

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

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



1> Wayne Conrad..:

我认为撕裂的页面不是问题.据我所知,所有驱动器都有足够的电量存储,以便在电源故障时完成当前扇区的写入.

问题是每个人都撒谎.

至少当数据库知道事务何时被提交到磁盘时,每个人都会撒谎.数据库发出fsync,操作系统仅在所有未完成的写入已提交到磁盘时返回,对吧?也许不吧.通常,特别是对于RAID卡和/或SATA驱动器,您的程序会被告知所有已提交的内容(即fsync返回),但驱动器上尚未存在数据.

您可以尝试使用Brad的磁盘检查程序来确定您要用于数据库的平台是否能够在不丢失数据的情况下继续使用插件.底线:如果diskchecker失败,则该平台对于运行数据库是不安全的.具有ACID的数据库依赖于知道何时将事务提交到后备存储以及何时尚未提交.无论数据库是否使用预写登录,都是如此(如果数据库在没有完成fsync的情况下返回给用户,则在发生故障时可能会丢失事务,因此它不应声称它提供了ACID语义).

Postgresql邮件列表上有一个讨论持久性的长线程.它开始谈论SSD,但随后它进入了SATA驱动器,SCSI驱动器和文件系统.您可能会惊讶地发现您的数据可能会丢失.对于拥有需要持久性的数据库的人来说,这是一个很好的线程,而不仅仅是那些运行Postgresql的人.



2> Eloff..:

似乎没有人同意这个问题.所以我花了很多时间尝试不同的Google查询,直到我终于找到答案.

来自Stephen Tweedie博士,RedHat员工和Linux内核文件系统以及虚拟内存开发人员在这里谈论ext3(他开发的)成绩单.如果有人知道,那就是他.

"仅仅将这些东西写入期刊是不够的,因为期刊中必须有一些标记说:嗯,(实际上有这个期刊记录)这个期刊记录实际上代表了磁盘的完全一致性吗?这样做的方法是通过一些原子操作来标记事务在磁盘上完成"[23m,14s]

"现在,磁盘这些天实际上已经做出了这些保证.如果你开始对磁盘进行写操作,那么即使电源在该扇区写入中间失败,磁盘也有足够的可用功率,它实际上可以从磁盘中窃取电源.主轴的旋转能量;它有足够的功率来完成正在写入的扇区的写入.在所有情况下,磁盘都能保证." [23m,41s]



3> BobMcGee..:

不,他们不是.更糟糕的是,在默认设置下,磁盘可能会说谎,并且说数据实际上是在磁盘缓存中写入的.出于性能原因,这可能是合乎需要的(实际耐用性要慢一个数量级),但这意味着如果断电并且磁盘缓存没有物理写入,则数据将消失.

不幸的是,真正的持久性既困难缓慢,因为每次写入需要至少进行一次完整旋转,或者使用日志/撤消进行2次以上.这限制了您每秒几百个数据库事务,并且需要在相当低的级别禁用写入缓存.

因为尽管实际的目的,不同的是不在于在大多数情况下,大的交易.

看到:

如何(不)实现耐久性.

FSync()可能不会刷新到磁盘



4> Eloff..:

如果断电,人们似乎不同意扇区写入期间发生的事情.也许是因为它取决于所使用的硬件,甚至是文件系统.

来自维基百科(http://en.wikipedia.org/wiki/Journaling_file_system):

某些磁盘驱动器可确保在电源故障期间写入原子性.然而,其他人可能会在电源丢失后停止在扇区中途写入,从而使其与错误纠正码不匹配.因此该部门腐败,其内容丢失.物理日志可以防止这种腐败,因为它拥有该部门的完整副本,它可以重播下次装载时的腐败.

似乎暗示某些硬盘驱动器无法完成该扇区的编写,但是日志文件系统可以像xlog保护数据库一样保护您免受数据丢失.

从linux内核邮件列表中讨论ext3日志文件系统:

在任何情况下,坏扇区校验和都是硬件错误.扇区写入应该是原子的,它发生与否.

我倾向于相信维基评论.实际上,没有xlog的数据库(firebird)的存在意味着扇区写入是原子的,它不能破坏你不想改变的数据.

有相当多的讨论,这里大约部门的原子写入,再没有达成协议.但是那些不同意的人似乎在谈论多扇区写入(在许多现代硬盘驱动器上并不是原子的.)那些说扇区写入是原子的人似乎更多地了解他们所谈论的内容.



5> Jerry Coffin..:

第一个问题的答案取决于所涉及的硬件.至少对于一些较旧的硬件,答案是肯定的 - 电源故障可能导致垃圾被写入磁盘.然而,大多数当前的磁盘都有一些内置于磁盘本身的"UPS" - 一个足够大的电容器足以为磁盘供电足够长的时间,以便将磁盘缓存中的数据写入磁盘盘片.它们还具有检测电源是否仍然良好的电路,因此当电源变得不稳定时,它们将缓存中的数据写入盘片,并忽略它们可能接收到的垃圾.

就"撕裂的页面"而言,典型的磁盘只接受命令来一次写入整个扇区,因此您将获得的内容通常是正确写入的整数扇区,而其他扇区保持不变.但是,如果您使用的逻辑页大小大于单个扇区,那么您最终可能会得到一个部分写入的页面.

然而,这主要适用于直接连接到普通移动盘式硬盘.几乎所有其他事情,规则可以而且往往会有所不同.仅举一个明显的例子,如果您是通过网络编写的,那么您将主要使用正在使用的网络协议.如果通过TCP传输数据,则将拒绝与CRC不匹配的数据,但可能会接受通过UDP传输的具有相同损坏的相同数据.

推荐阅读
大大炮
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有