我们有一组安装了 Linux、本地 Web 服务器和 PostgreSQL 的消费者终端。我们收到了机器出现问题的现场报告,经过调查,发现似乎是因为停电,现在磁盘出现了问题。
我原以为问题只是数据库损坏,或者最近更改的文件变得混乱,但还有其他奇怪的报告。
- 具有错误权限的文件
- 已成为目录的文件(例如,
index.php
现在是目录) - 已成为文件的目录
- 含有乱码数据的文件
数据库损坏的问题确实存在,但这也是意料之中的事情。让我更惊讶的是更基本的文件系统问题 - 例如权限或将文件更改为目录。最近没有更改的文件中也会出现问题(例如软件代码和配置)。
对于 SSD 损坏来说,这是“正常”现象吗?最初我们以为这种情况只发生在一些廉价 SSD 上,但我们在名牌(消费级)上也遇到了这种情况。
值得一提的是,我们不会在非干净启动时执行 autofsck(不知道为什么 - 我是新手)。我们在某些地方安装了 UPS,但有时安装不正确,等等。这个问题应该得到解决,但即便如此,人们也可能不干净地关闭终端,等等 - 所以它不是万无一失的。文件系统是 ext4。
问题是:我们可以做些什么来在系统层面缓解这个问题?
我发现一些文章提到关闭硬件缓存或以同步模式安装驱动器,但我不确定这是否会在这种情况下有所帮助(元数据损坏和非近期更改)。我还阅读了有关以只读模式安装文件系统的参考资料。我们不能这样做,因为我们需要写入,但如果有帮助的话,我们可以为代码和配置创建一个只读分区。
这是一个驱动器的示例sudo hdparm -i /dev/sda1
:
Model=KINGSTON RBU-SMS151S364GG, FwRev=S9FM02.5, SerialNo=<deleted>
Config={ Fixed }
RawCHS=16383/16/63, TrkSize=0, SectSize=0, ECCbytes=0
BuffType=unknown, BuffSize=unknown, MaxMultSect=16, MultSect=16
CurCHS=16383/16/63, CurSects=16514064, LBA=yes, LBAsects=125045424
IORDY=on/off, tPIO={min:120,w/IORDY:120}, tDMA={min:120,rec:120}
PIO modes: pio0 pio3 pio4
DMA modes: mdma0 mdma1 mdma2
UDMA modes: udma0 udma1 udma2 udma3 udma4 udma5 *udma6
AdvancedPM=yes: disabled (255) WriteCache=enabled
Drive conforms to: Unspecified: ATA/ATAPI-3,4,5,6,7
答案1
突然断电时,MLC/TLC/QLC SSD 会二故障模式:
- 它们会丢失正在进行的数据和仅在 DRAM 中的写入数据;
- 它们可能会破坏正在编程的 NAND 单元下页中存储的任何静态数据。
第一个故障条件很明显:没有电源保护,任何不在稳定存储(即 NAND 本身)上,而只在易失性缓存(DRAM)上的数据都将丢失。传统机械磁盘也会发生同样的情况(仅这一点就会对无法正确发出 fsync 的文件系统造成严重破坏)。
第二种故障情况是 MLC+ SSD 的问题:在重新编程高页位以存储新数据时,意外断电可能会破坏/改变低位(即:先前的坚定的数据)也是如此。
唯一正确且最明显的解决方案是集成断电保护 DRAM 缓存(通常使用电池/超级电容器),高端 RAID 控制器一直以来都是这样做的;然而,这会增加驱动器成本/价格。消费级驱动器通常没有断电保护缓存;相反,它们使用一系列更经济的解决方案,例如:
- 部分受保护的写入缓存(例如:Crucial M500/M550/M600+);
- NAND 变化日志(即:三星驱动器,参见 SMART PoR 属性);
- 特殊的 SLC/伪 SLC NAND 区域用于吸收新写入,而不会危及以前的数据(例如:Sandisk、Samsung 等)。
回到你的问题:你的 Kingstone 硬盘是超便宜的,使用未指定的控制器,基本上没有公开的规格。突然断电会损坏以前的数据,这并不让我感到惊讶。不幸的是,即使禁用磁盘的 DRAM 缓存(这会导致巨大的性能损失)也会不是解决您的问题,因为以前的数据(即静态数据)可能会因意外断电而损坏。如果它们基于旧的 Sandforce 控制器,在“正确”的情况下,甚至可以预期驱动器完全损坏。
我强烈建议检查您的UPS,并在中期更换这些老化的驱动器。
关于 PostgreSQL 和其他 Linux 数据库的最后一点说明:它们将不是禁用磁盘缓存,并且应该不是预计会这样做。相反,它们会定期/需要 fsyncs/FUA 来将关键数据提交到稳定存储。除非非常存在令人信服的理由(即:驱动器存在有关 ATA FLUSHES/FUA 的信息)。
编辑:如果可能,请考虑迁移到校验和文件系统,如 ZFS 或 BTRFS。至少考虑 XFS,它具有日志校验和,最近甚至还有元数据校验和。如果您被迫使用 EXT4,请考虑在启动时启用自动 fsck(fsck.ext4 非常擅长修复损坏)。
答案2
是的。不要买超级便宜的 SSD - 低端消费市场以外的任何产品都有电容器和全面的断电保护。AMD 的价格确实不会贵那么多。
答案3
首先要做的事情是定义恢复时间和恢复点目标。您需要多长时间才能恢复这些终端之一,以及哪个时间点的数据是可以接受的?也许在几个小时内,您需要能够恢复到上周的备份。
如果在传输过程中丢失了写入,文件可能会发生各种奇怪的事情。文件系统的首要任务是维护自己的元数据一致性,它们可能无法为您的数据提供相同的保证。换句话说,fsck
无法保证恢复您的数据。它的工作是为您提供一个可以挂载的文件系统。
所以,电源。安装、配置并测试 UPS 能否正常关闭系统。这允许文件系统缓存和驱动器本身进行写入。
以及磁盘写入的持久性。阅读PostgreSQL 的可靠性章节。使用diskchecker.pl
此处链接的脚本进行崩溃测试,并确定 SSD 是否在写入非易失性存储时撒谎。如果有丢失,请考虑用已知具有断电保护功能的 SSD 进行替换。
编辑:您添加了已启用写入缓存的详细信息。您可以尝试禁用该缓存:hdparm -W0 /dev/sda
或硬件阵列的相应命令。参考: RHEL 存储管理指南。
文件系统写入屏障强制执行日志提交的顺序。它不能保证数据完好无损,但对于具有易失性缓存的文件系统来说更安全。虽然这是默认设置,但添加“屏障”挂载选项清楚地表明您更看重一致性而不是性能。
最后,最后一道防线。进行恢复测试,以确保您可以将应用程序和数据库恢复到所需的时间点。这对于各种数据丢失都很有用,而不仅仅是电源故障。