磁盘不是万无一失的,可能会发生故障和损坏。磁盘故障是灾难性的。如果存储介质损坏,如果在没有备份的情况下100%丢失数据,则比rm -rf更严重。那么磁盘故障是那么多?
间歇性失败
媒体损坏
写失败
磁盘崩溃
处理这些失败的策略和方法是什么?我们来看看这一章。
间歇性失败
当我们尝试从磁盘读取块时,此块的内容可能无法正确发送到磁盘控制器。这是间歇性的失败。控制器将以某种方式判断磁盘块的质量。读取数据不好,控制器将尝试再次读取启动请求,直到数据被正确读取,或发送N个请求然后停止。
类似地,我们尝试编写一个扇区,可能写入的内容不是我们最初想写的内容,唯一的方法是读取磁盘的内容并将其与磁盘控制器的内容进行比较。但是,与磁盘控制器相比,您实际上可以读取写入的扇区并检查状态是否“良好”。如果状态为“坏”然后重写,这个状态是如何产生的?这导致了校验和的概念。
校验
在我们说校验和之前,让我们玩一个小游戏:
桌子上摆放着七个黑白棋子,魔术师蒙着眼睛看不到碎片。在观看了7件之后,魔术师学徒在右侧添加了一块,与其他部分一起。此时有8件,魔术师仍然被蒙上眼睛。此时,观看者可以翻转其中一个或不翻转一个。观众和学徒都没有说一句话,魔术师也不知道观众是否翻过了碎片。
现在,魔术师摘下眼罩,观察八件,然后可以判断这件作品是否被翻转,观众的行为是否被看到。那么魔术师是如何看透的呢?
校验和:在磁盘的每个扇区中有几个附加位。这称为校验和。读取数据时,如果校验和与数据位不匹配,则判断读取错误。但是,如果校验和正确,则数据可能是错误的。这种可能性与校验位的长度负相关。校验位越长,判断错误的概率就越小。
校验和基于扇区中所有位的奇偶校验。如果该组位中存在奇数个1,则数据位具有奇校验并且将奇偶校验加1。类似地,如果偶数为1,则数据位具有偶数奇偶校验并添加具有零值的奇数位。如果我们使用一个字节(8位)来确定奇偶校验并且检测到错误的概率是50%,那么错误的概率是1/2 ^ 8。如果使用4个字节,则错误率为1/2 ^ 32。在40亿次中只有一次未被发现。
通常,在数据库中,CRC或FNV用于校验和。在PostgreSQL中,使用了FNV-1a。让我们看看PG是如何实现的。
PostgreSQL的校验和
Postgres默认情况下不启用校验和。初始化数据库时,可以使用-k选项启动它。
-k, - data-checksums使用数据页校验和
使用的算法是FNV-1a。以下地址是该算法的详细描述。:http://www.isthe.com/chongo/tech/comp/fnv/
核心代码位于: src/include/storage/checksum_impl.h
功能输入: pg_checksum_block
官方说明:
PG的实施与官方实施不同。官方实施是:
在PG乘以之前,它向右移动17位,然后是xor。
计算结果存储在页眉标题PageHeaderData->中
Pd_checksum
需要从shared_buffer画笔和从磁盘读取的块计算数据。如果只更改内存中的数据页,则无需计算校验和。
对gdb感兴趣可以看看。
回到上面的游戏,魔术师只需要同意学徒之前,甚至有白色或黑色,问题解决了,这也是一个奇偶校验实施。
媒体损坏
磁盘也有长寿。当磁盘损坏时,损坏是物理的,数据无法完全恢复。在上面我们介绍了如何有效地检测介质故障或读写故障,但没有解释如何解决这个问题。
在磁盘扇区损坏问题上,您可以使用2个或更多磁盘来存储数据。例如,我们写内容X,通常是扇区配对。我们将写入X的扇区称为(左侧副本)Xl和(右侧副本)Xr。 read函数可以读取Xl或Xr并返回结果w,然后w是X的实际内容。前提是我们通过CheckSum检查Xl和Xr扇区的完整性。 (这有点情况,实际上是将2个数据副本写入不同的磁盘扇区,然后您可以从其中一个读取到您想要的内容)。编写策略是相同的,例如,编写Xl,检查返回状态是否“良好”,如果不是,则需要继续编写。经过几次,如果不成功,可以表明该部门是坏的。您可以用Xr替换损坏的Xl。相反,Xr和X1是相同的逻辑,并且可以重复X1的动作。
读取策略是交互式的,交替读取Xl和Xr,预先设置一个大数字,如果您尝试超过此数据,则可以确定X是不可读的。
袭击
上面讨论的内容实际上是RAID(独立磁盘冗余阵列)。磁盘崩溃率通常由平均到期时间来衡量。如果平均磁盘到期时间为10年,则每年磁盘的1/10将失败。为避免此故障,在使用数据磁盘时使用此策略。或者当冗余磁盘崩溃时,可以使用其他磁盘来恢复故障磁盘,以免丢失任何数据。 RAID分为多个级别,让我们来看看不同级别的计算和使用。