凌晨两点半,一条磁盘告警把值班的人叫起来。登上机器一看,根分区还剩一半以上的空间,inode 用量也远没到上限,但业务日志里密密麻麻全是写入失败:新建文件报「只读文件系统」,数据库写不进临时文件,定时任务的每一次落盘都异常退出。更反常的是监控面板——磁盘读写几乎是一条贴着零的直线,IOPS 低到像是这台机器已经闲下来了。
空间明明够,也没有成片的 I/O 错误刷屏,为什么什么都写不进去?答案是文件系统自己进入了只读状态。这不是盘坏了,而是内核在发现元数据处于不确定状态之后主动采取的自保动作。真正麻烦的地方在于:接下来要等多久才能恢复可写,这件事在事发之前几乎没人算过。
本篇只讨论一个问题:异常关机(掉电、强制硬重启、宿主侧被终止)之后,文件系统从「不一致」回到「可写」这段时间由什么决定,以及怎么在事前把它设计进去。它和我们已经单独写过的阵列卡与 NVMe 选型、整机崩溃转储取证、内存可纠正错误判定属于完全不同的几条线,也不涉及备份恢复演练里的指标口径。这几件事在事故现场常常被一起提起,但处置顺序完全不同,混在一起最容易犯的错误是把「等检查跑完」当成「等数据恢复」,从而在错误的地方消耗时间。
同样是异常掉电,现场表现差别很大,先分清形态再谈处置。
第一种,运行中突然变成只读。业务还在跑,进程都在,端口也还监听着,但任何写操作都失败。目录能列、文件能读,只有写被拒。系统日志里通常能找到内核把文件系统重新挂载为只读的记录——ext 系列与 XFS 的措辞不同,XFS 在遇到严重元数据错误时倾向于直接关闭(shutdown)该文件系统,此后这个挂载点上的 I/O 基本失效,必须卸载后再处理。这类现场最容易误判:因为读是通的,很多人第一反应是去查磁盘健康,而真正的线索在内核日志的错误处理动作上。
第二种,重启之后停住。开机过程停在文件系统检查的界面上,或者提示需要手动运行修复工具,甚至直接落到一个维护用的 shell 里,业务进程一个都没起来。这种形态下,时间成本最直观,也最容易被低估:它发生在业务恢复路径的最前面,检查没跑完,后面的应用、缓存预热、数据校验全都要排队。
第三种,看起来正常开机,但业务迟迟起不来。系统起来了,登录也正常,但某个挂载点长时间不可用,依赖它的服务一直在重试。这种情况在把检查挂到后台、或者挂载点较多时很常见,从外部看是「机器起来了但服务没起来」,排查方向却和前两种完全不同。
第四种,什么都没发生。这是最常见却最少被讨论的一种:重启时内核自动回放了日志,几秒内完成,系统正常起来,业务无感知。日志文件系统本来就是为了这件事而存在的——它在绝大多数异常关机场景下都能自己收尾。理解第四种的存在很重要,因为这说明「掉电等于要等很久」并不成立,真正需要关注的是那些少数、但代价极高的情况。
四种结果的差别来自同一个变量:掉电那一刻,有多少元数据处于「已提交但未落盘」或「正在被修改」的状态,以及这些状态是否能被日志完整重放。
要理解只读,先要纠正一个常见的期待:日志文件系统保证的是元数据的一致性,不是「数据一条不丢」。它保证的是目录结构、块分配表、inode 引用这些结构在崩溃后能被恢复到一个自洽的状态,而不保证最后一次写入的用户数据一定完整落盘。
内核在运行过程中会持续校验关键结构的自洽性。一旦发现明显矛盾——比如块位图说某个块已分配,但没有任何 inode 引用它;或者目录项指向一个非法的 inode 号;或者某个结构的校验值对不上——继续写入就有可能把局部问题扩散成大面积损坏。此时内核有三种常见的错误处理策略:忽略继续、重新挂载为只读、直接恐慌(panic)。主流发行版对 ext 系列的默认配置通常倾向于重新挂载为只读,具体取值取决于内核默认值与该挂载点在文件系统表里的显式配置,所以判断前应当先看本机实际生效的参数,而不是凭经验下结论。
值得强调的是:变成只读的是挂载状态,不是磁盘本身。磁盘完全可以是健康的。所以你会看到磁盘剩余空间正常、inode 正常、读操作全部正常,只有写被拒绝。这也解释了那组看似矛盾的现象——监控上 IO 接近零,是因为写请求在进入文件系统层时就被拦下了,根本没有下发到块设备层,自然测不到任何读写量。用 IO 指标去找这类问题的根因,方向本身就是错的。
对于 XFS,行为形态有所不同:它在检测到无法继续安全运行的元数据错误时会关闭文件系统,此后该挂载点上的读写基本全部失效,而不是退化成只读。这带来的操作差异是——XFS 的修复工具通常要求目标处于卸载状态,因此「先卸载再修」几乎是必经步骤,而不能指望在挂载状态下修好。
要估算恢复时间,得先知道要处理的是些什么东西。
第一类,页面缓存里没落盘的脏数据。正常情况下,应用写入先落到内存页缓存,由内核按策略回写。掉电瞬间,这部分内容直接消失。它们在文件系统层面没有留下任何痕迹,也不会进入恢复流程,但会造成业务侧的数据缺失——这部分缺失要靠应用层的确认机制去发现,不是文件系统能告诉你的。
第二类,日志里已经提交、但数据块还没写到最终位置的事务。这是恢复流程要处理的主要对象。挂载时内核读日志,把这些事务重新执行一遍(重做),这就是「日志回放」。回放量取决于掉电前一段时间里元数据更新的密集程度,以及日志本身的大小,与整个文件系统有多大并没有直接关系。
第三类,写了一半的事务。日志以事务为单位写入,并带有校验机制。只写了一半的事务在回放时会被识别为不完整并丢弃。这类内容不需要处理,但它的存在说明掉电发生在写入过程中,同一时刻可能还有其他结构处于中间状态。
第四类,不在日志保护范围内的数据块。在默认的数据模式下,日志保护的是元数据;用户数据块本身的落盘顺序不由日志保证。因此异常关机之后,可能出现「文件存在、大小正确、但内容包含旧数据或部分新数据」的情况。这不是文件系统坏了,而是日志语义的边界。对数据库这类自己维护一致性的应用,这通常可以被自身的恢复机制消化;对普通文件,它表现为内容不完整,需要业务层校验。
把这四类分开看,就能得出一个对估算最有用的结论:恢复流程处理的是元数据状态,不是数据内容。所以恢复时间的量级主要由元数据的规模和位置决定,而不是由「有多少 GB 数据」决定。
挂载流程的第一步是读超级块,检查日志是否被标记为「脏」。如果脏,内核先做日志回放。回放由内核自己完成,通常很快,因为日志是一个连续的、顺序读的区域——这一步的耗时主要取决于日志里未完成事务的量与日志区域的读取速度,是一次顺序读,不是随机读。
回放成功且文件系统没有被标记为需要全面检查时,挂载正常完成,这就是前面说的第四种现场。很多异常关机止步于此。
但有两种情况会进入全面检查:一是文件系统自身被打了「需要检查」的标记(例如挂载次数或距上次检查的时间间隔达到设定阈值,或者上次卸载不干净);二是回放之后仍发现结构不自洽,需要工具介入。以 ext 系列为例,检查工具按多个阶段推进:先核对 inode 表与块位图,再检查目录结构的合法性,再校验目录连接性,再核对引用计数,最后汇总位图信息。这几个阶段里,真正吃时间的主要是遍历 inode 与目录树,也就是大量分散在整块盘上的随机读。
XFS 的路径不同:挂载时由内核做日志回放,如果回放无法完成或结构仍有损坏,需要卸载后用修复工具处理。XFS 修复工具在只检查不修改的模式下可以先把问题看清楚而不做任何改动,这一步常被用来做时间预估和风险评估,但请注意它在大型文件系统上同样要遍历元数据,耗时量级与正式修复的前期阶段接近。
把「等检查跑完」拆开,它实际上是下面几项叠加的结果。每一项都可以单独度量,也都可以单独设计。
日志回放量。由掉电前的元数据更新密集程度和日志区域大小决定。写入密集、长时间不提交、日志区域配置得很大,都会让回放量上升。这一步是顺序读,通常不是瓶颈,但它决定了「最轻量」的那部分时间。
元数据遍历规模。这是主导项:文件数量、目录层级深度、inode 总数。一个存了几千万个小文件的分区,即使总容量只用了很小一部分,遍历起来也会非常耗时;反过来,一个装满少量大文件的分区,容量再大,元数据也相对少。所以「容量大」和「检查慢」之间没有必然关系,中间隔着文件数量这个变量。
底层随机读能力。元数据散布在盘上的各个位置,检查过程基本是随机读模式。机械盘在随机读下的表现与顺序读相差极大,固态盘则好得多。同一个文件系统放在不同介质上,检查时间的差距可以达到数量级水平——具体倍数需以自有环境量测出的基线为准,本篇不给出具体数字,但方向是确定的:元数据密集的业务不应该把元数据放在随机读能力弱的设备上。
检查能否并行。单个文件系统内部的检查阶段基本是串行的,不同文件系统之间则可以同时进行。这意味着挂载点的划分方式直接影响总耗时:一个巨大的单分区只能慢慢跑完,拆成几个较小的分区则有机会并行推进——前提是底层不是同一块盘在争用。
可用内存与临时空间。修复工具在处理大型目录和大量 inode 时需要可观的内存。内存不足时它会退化到临时目录反复读写中间结果,耗时往往显著上升,极端情况下甚至无法完成。这一部分也是最容易被忽略的:大家会算磁盘空间,却很少算修复时要用多少内存。
文件系统特性开关。某些特性可以让检查跳过未使用的区域(例如 ext4 的块组惰性初始化,使检查工具能跳过尚未初始化的 inode 表块)。这类特性在新建文件系统时就已经决定了,事后很难改。用一套陈旧参数做出来的文件系统,可能在检查时间上先天吃亏。
| 影响因素 | 怎么度量 | 设计动作 | 代价 |
|---|---|---|---|
| 日志回放量 | 看日志区域大小与掉电前的元数据更新密度,回放耗时以顺序读为主,可用维护窗口内的模拟关机测一次基线 | 控制日志区域规模,避免长时间不提交的写入模式,日志单独放在随机写能力好的设备上 | 多一块独立设备带来额外成本与故障点,需要一并纳入可靠性设计,而不是单点依赖 |
| 元数据规模(文件数、目录深度) | 查 inode 总数与已用量、统计目录层级分布,用只读检查模式先跑一遍拿耗时基线 | 给单个文件系统设容量与文件数上限,按业务拆分挂载点,控制单目录下文件数量 | 挂载点变多后容量规划与权限管理更碎,跨挂载点的移动操作要按跨设备语义处理 |
| 底层随机读能力 | 用随机小读的方式测底层设备的 IOPS 基线,并记录介质类型与是否共享背板 | 元数据密集的挂载点优先放在固态介质上,冷数据才放到大容量机械盘 | 单位容量成本更高,需要对冷热数据做分层与生命周期管理,运维复杂度上升 |
| 检查能否并行 | 看挂载点数量与底层设备的独立性,共享同一块物理盘时并行收益有限 | 拆分成多个独立挂载点,让不同设备的检查同时进行,并确认启动流程允许并行 | 并行会造成底层争用,多分区共用一块盘时反而可能更慢,需要按设备边界而不是按目录边界拆 |
| 可用内存与临时空间 | 记录修复工具运行时的峰值内存占用,以及是否发生向临时目录的退化读写 | 修复前预留足够内存与临时空间,必要时把盘挂到内存更大的中转机上处理 | 需要一台可临时调配的机器,或接受更长的修复时间,两者都要求事先准备而不是临场找资源 |
| 文件系统特性开关 | 用工具查看超级块特性位,确认是否启用可跳过未使用区域的特性 | 建文件系统时统一参数基线,避免沿用老旧脚本里的默认参数 | 新特性可能要求较新的内核与工具链,需要整体版本对齐,升级窗口本身也要排期 |
这是最有效也是最早就要做的一件事,因为它在建系统时决定,事后改要迁移数据。
拆分的依据不是部门、不是目录名,而是恢复时间的边界:希望最坏情况下每个挂载点能在多长时间内检查完。先定这个时间,再反推每个文件系统允许承载多少 inode、多少文件,最终落到容量上限上。一个实用的做法是按「元数据密度」分区:小文件密集、目录层级深的业务单独一个挂载点,并给它更好的介质;大文件、顺序读写为主的归档数据另放一个挂载点,介质可以便宜一些。
拆分带来的额外好处是故障隔离:一个挂载点进入只读,其他挂载点不受影响;一个挂载点在检查,业务可以先在其余部分拉起来。反过来,如果所有东西都在一个巨大的根分区里,那么任何一次异常关机都是全站级事件。
代价也要说清楚:挂载点变多以后,容量水位要分别监控,跨挂载点的文件移动不再是改名而是真实的数据搬运,某些依赖同一文件系统语义的操作(例如硬链接、某些原子替换写法)会受到限制。这些限制应当在应用设计阶段就确认,而不是在拆分之后才发现。
日志是一个写入极其频繁、且对延迟敏感的区域。把它和数据放在同一块盘上,意味着元数据更新要和业务数据读写争抢同一份 I/O 能力;在高写入压力下,这会同时拖慢业务和恢复。
把日志单独放到延迟更低、随机写能力更好的设备上,收益有两层:平时减少元数据更新的等待,异常时让回放阶段更快结束。代价是这块设备本身成为一个新的关键部件——它的可靠性会直接影响整个文件系统能否挂载,所以它不能是一个「随便找块盘」的角色,其可靠性要求应当不低于数据盘。
更根本的一点:采购和评估存储时,把随机读能力作为元数据密集场景的主要指标,而不是只看顺序吞吐和容量。文件系统检查、目录遍历、海量小文件读写,这些动作全部落在随机读上。用顺序带宽指标选出来的盘,在做这类事情时的表现和标称值可以差很远。
很多环境的做法是「让开机时自动检查」,这在单盘小容量时代没有大问题,但在大容量场景下等于把一段不可控的时间放在了业务恢复的最前面。更可控的做法是把检查从开机关键路径上挪走。
具体可以做的几件事:一是用工具查看并调整强制检查的触发条件——包括按挂载次数触发和按时间间隔触发两类阈值,让全面检查发生在你能安排的时间点,而不是随机地落在某次凌晨重启上。二是确认文件系统表里每个挂载点的检查顺序字段:根文件系统通常排在最前,其余挂载点可以并行;不需要在开机阶段检查的挂载点,应当明确关掉开机自动检查,改由维护流程手动执行。三是给检查留一个明确的维护窗口,窗口长度按前面测出的基线再加上余量来定,而不是按「上次好像十几分钟」来定。
内存也要提前算。修复工具在内存不足时会退化到临时目录,而临时目录如果又落在同一个繁忙的设备上,就会形成二次争用。因此应当为修复预留一块独立的临时空间,并明确「这台机器修复时需要多少内存」,必要时准备一台内存更大的中转机——把盘挂过去修,往往比在本机硬扛更快,也更安全,因为本机已经在故障状态上了。
这是本篇最重要的操作建议:在最危险的时候不要做最激进的操作。
当文件系统处于不一致状态时,任何带修复性质的写入都有可能改变磁盘内容,而且不可逆。因此正确的顺序是:
第一步,取证。先把内核日志、挂载状态、文件系统工具的只读检查结果保存下来。只读检查模式不会修改任何东西,它能告诉你问题的范围,也是后面评估「要不要修、修的风险有多大」的依据。跳过这一步直接修复,等于放弃了对损失范围的判断。
第二步,留副本。优先用快照:如果底层平台支持,对整块盘做一次快照,成本通常远低于完整拷贝,而且回滚路径清晰。没有快照能力时,用镜像工具整盘复制到另一块容量足够的盘上,再在副本上尝试修复。复制过程中如果读到坏块,镜像工具应当具备跳过与重试的能力,而不是一遇到错误就中断。
第三步,才是在副本上验证修复方案、确认损失范围,最后决定是在原盘修还是用副本重建。把这三步反过来做,最常见的后果是:修到一半发现修复本身造成了更大范围的改动,而此时已经没有可回滚的东西了。
第一类危险是无条件自动回答「是」的修复。这类参数会让工具对所有询问都按「修」来处理,包括那些本应人工判断的问题:是否删除无法归位的 inode、是否清空引用异常的目录项、是否重建某个结构。它的好处是不用人守着,代价是损失范围不可控,被处理掉的数据通常会进入一个专门的找回目录,需要人工逐个辨认,而且往往已经失去了原有路径和文件名。
第二类危险是跳过日志直接挂载。技术上确实存在跳过日志回放的挂载选项,某些文件系统的修复流程也把它作为抢救手段之一。但它的语义是「忽略未完成的事务」,这意味着放弃一致性保证。它只在一种场景下有意义:目标是把数据抢救出来,之后这块盘不再继续使用。把它当成「让机器快点起来」的手段,是把一次可恢复的故障变成一次数据事故。
第三类危险是反复重启尝试。每次启动都可能触发一次检查甚至一次部分修复,状态在不断变化,反而让后续判断更难。发现只读或者卡在检查,应当停下来取证,而不是用重启去碰运气。
第四类危险是在只读的原盘上直接做大范围写入测试。想验证盘是否真的健康,应该换一个环境做,而不是在已经处于异常状态的挂载点上写测试文件——这些写入本身就有可能失败,也可能进一步扰动状态。
同样是异常关机,云主机和物理机的处置空间差别很大,而这一点必须在事先确认,不能等到出事才发现。
第一个差别是能否进入救援环境。物理机通常可以通过带外管理挂载安装介质、进入救援模式,把本地盘挂到另一个系统下去处理;云主机则取决于平台是否提供救援环境、是否允许把原盘挂载到另一台实例上作为数据盘,以及控制台是否提供串行输出让你看到开机过程。这三项能力的有无,直接决定了「卡在检查」时你有多少可操作的余地。
第二个差别是快照回滚路径是否可用、回滚粒度有多细。有快照能力时,「回滚到一个可用状态」往往比「原地修复」快得多,而且风险更低,因为修复是在另一条路径上进行的。这里要提前确认的是快照的粒度、保留时长、回滚需要停机多久,以及回滚之后增量数据怎么处理——这些都属于事前要问清楚的能力项。
第三个差别是断电来源不同。云主机的异常关机可能来自宿主侧故障、平台维护迁移,而不是这块盘本身出了问题;本地盘(随实例生命周期存在的临时盘)与独立于实例的网络盘在异常关机后的表现也不同:后者通常由底层多副本保证介质本身的可靠性,前者随实例终止而消失。因此在云上遇到只读,首先要区分的是「文件系统不一致」和「底层设备不可用了」,两者的处置方向完全不同。
第四个差别是谁来执行操作。物理机在机房里,需要有人到现场或依赖带外;云主机则依赖控制台与 API 是否可用。遇到掉电之后要等文件系统检查这类场景,一万网络(深耕 19 年,成立于 2007 年)能提前确认的是能否进救援环境、有没有可用的快照回滚路径,让客户把恢复时间算进可用性,而不是停在机房里干等。
这是一个反直觉但值得记住的结论。原地修复的时间是「日志回放 + 元数据遍历 + 可能的反复尝试」,而且过程中充满不确定性:工具可能在中途退出、可能提示需要人工判断、可能因为内存不足重来。快照回滚的时间则是「把一块盘恢复到某个已知状态」,主要受数据量与底层写入能力影响,路径确定,可预测得多。
两者的目标也不同。修复追求的是「保留尽可能多的最后一次写入」,回滚追求的是「尽快回到一个确定的可用状态」。在业务中断的语境下,后者通常更优先:先回滚恢复服务,把故障盘保留为一份数据盘,在业务恢复之后从容地把增量数据捞回来,比让所有人盯着进度条等一个不确定的结果要好。
当然,回滚不是万能的:它要求快照存在、快照点可接受、并且回滚后能接受快照点之后的写入全部丢失。所以在设计阶段要做的是把快照频率与「能承受丢失多少写入」对齐,而不是事后才发现上一次快照是三天前。同时要注意,快照回滚之后的实例仍然要经历正常的挂载与日志回放,只是起点是一个一致的状态,因此这一步仍然会占用时间,只是量级小得多。
恢复时间之所以难算,是因为大多数环境从来没有测过。测一次的成本很低:找一台同规格的机器,造一个规模相近的文件系统,用强制方式模拟一次异常关机,然后完整记录。
需要记录的数字有这么几类:规模类,包括 inode 总数与已用数、文件总数、目录最大深度、单个目录下最大文件数、日志区域大小;耗时类,包括日志回放耗时、检查各阶段分别耗时、全流程总耗时,以及修复工具是否中途出现过内存不足的提示;资源类,包括修复工具峰值内存占用、临时目录使用量、底层设备随机读基线;结果类,包括是否有文件被移入找回目录、是否有结构被丢弃、修复后业务校验是否通过。
演练的触发条件建议按事件而不是只按日历:每次容量显著扩容、文件数量跨过一个量级、更换存储介质、调整文件系统参数或内核版本、迁移到新的平台之后,都应当重测一次。在此基础上再设一个固定的周期(例如每半年到一年),用来捕捉缓慢增长带来的变化——文件数量是慢慢涨上来的,等到它成为瓶颈时,往往已经很久没人重新测过了。
演练结果要落到文档里,而不只是留在当时那次事故的记录里。因为真正需要它的时刻,是几个月后某次凌晨重启,而当值的人不可能凭印象知道「这块盘检查要多久」。
只读了能不能直接重启解决?不一定。重启会触发日志回放,回放成功且结构自洽的情况下确实能恢复;但如果结构已经不自洽,重启只会把你带进检查流程,甚至直接停在维护界面。更重要的是,重启会丢掉当前的内核日志与挂载状态,而这些正是判断问题范围的第一手材料。正确顺序是先保存日志、做只读检查、留副本,再决定是否重启。
检查要跑多久,能不能提前预估?能,但只能估出量级。做法是在同等规模的环境上用只读检查模式跑一次基线,再按文件数量与底层介质做外推。只读检查不修改任何内容,可以放心跑,它给出的耗时与正式修复的前期阶段接近,是最实用的预估来源。需要强调的是,具体数字需以自有环境为准,不同文件数量、不同介质、不同参数下差距可以非常大。
大容量盘是不是一定更慢?不一定。检查时间的主导项是元数据规模而不是容量:一个装满少量大文件的分区,容量再大,inode 与目录项也相对少;一个只用了少量空间但存了几千万个小文件的分区,反而可能非常慢。同时,某些特性允许检查跳过未使用的区域,这也会削弱容量与耗时之间的关联。真正要盯的指标是文件数量、目录深度和随机读能力。
能不能跳过检查让机器先起来?技术上存在跳过日志回放的挂载选项,某些文件系统也把它列为抢救手段。但它的语义是放弃一致性保证,只适用于「把数据抢救出来然后弃用这块盘」的场景。把它当成加速启动的常规手段,风险远大于收益。常规情况下更合理的做法是调整检查的触发条件,让它在维护窗口里发生,而不是在开机关键路径上发生。
修复会不会丢数据?有可能。修复的目标是把结构恢复自洽,而自洽的代价有时是丢弃无法归位的结构:找不到父目录的文件会被移到找回目录并失去原有路径与名称,损坏的目录项可能被清空,冲突的引用计数会被强行修正。自动回答「是」的修复方式会把这些判断全部交给工具,损失范围因此不可控。这也是必须先做副本的原因。
先修复还是先回滚快照?如果快照可用且快照点可以接受,优先回滚恢复服务,把故障盘留作数据盘后续处理。修复的不确定性高、不可逆、且期间业务一直中断;回滚的路径确定、可预测。等业务恢复之后再从容地从故障盘捞增量,整体代价通常更低。只有在没有快照、或快照点之后的数据无法承受丢失时,才把原地修复作为首选。
云主机能不能自己进救援?取决于平台。需要确认三件事:平台是否提供救援环境或救援镜像、是否允许把原盘卸载后挂载到另一台实例上作为数据盘、控制台是否提供串行输出以查看开机过程。这三项能力的有无,决定了「卡在检查」时你能做什么。它们属于签约与选型阶段就该问清楚的能力项,而不是故障发生后才去查。
多久演练一次合适?按事件触发为主、固定周期为辅。容量跨量级、文件数大幅增长、更换介质、调整文件系统参数或内核版本、平台迁移,这些变化发生后都应当重测一次;在此基础上保留一个半年到一年的固定周期,用来捕捉文件数量缓慢增长带来的变化。
答案不是「写在故障处理手册里」,而是写在容量设计与变更流程这两份文档里。因为等到故障处理手册被翻开时,能做的只剩下等待和取舍,真正决定恢复时间的选择——单文件系统多大、日志放哪、用什么介质、检查在什么时候触发、修复要用多少内存——全部发生在更早的阶段。
具体来说,容量设计文档里应当有每个挂载点的规模上限、介质类型、日志位置,以及对应的检查耗时基线;变更流程文档里应当规定:扩容或更换介质后必须重测基线,调整文件系统参数或内核版本后必须重测基线,并且每一次维护窗口申请都要带上「如果这次重启触发检查,需要预留多久」这一栏。
把恢复时间当成设计变量,和把它当成事故的附带损害,是两种完全不同的工程态度。前者的代价是多了几项事前的准备工作,后者的代价是某天凌晨所有人盯着进度条,谁也说不清还要多久。
本篇涉及的机制均属于可自行核对的公开知识,核对路径如下,便于在自己的环境里验证而不是照抄结论。
挂载与错误处理行为,可以通过内核文档与发行版文档确认:ext 系列的错误处理策略包括继续、只读重挂与恐慌三类取值,实际生效值需要结合文件系统表里的显式配置和内核默认值一起看;XFS 在严重元数据错误时的行为是关闭文件系统,这一点可以在其官方文档的描述中核对。系统日志中出现的相关提示措辞随内核版本变化,核对时应以本机实际输出为准。
日志语义方面,日志文件系统保护的是元数据一致性而非用户数据完整性,这一点在主流文件系统的设计说明中都有明确表述;不同数据模式(是否对数据块也做日志)会影响异常关机后文件内容的完整程度,可用挂载参数确认当前生效的模式。
检查流程方面,ext 系列检查工具的阶段划分与输出格式可以在其手册页中查到;其是否能跳过未使用区域,取决于文件系统创建时启用的特性,可以用查看超级块信息的工具确认特性位。XFS 侧对应的修复工具手册会说明其内存需求、临时目录的使用方式,以及只读检查模式与正式修复模式的区别。
触发条件方面,强制检查的按挂载次数与按时间间隔两类阈值,可用文件系统参数工具查看与调整;开机阶段是否检查、检查顺序如何,由文件系统表的最后一个字段控制,具体语义可在相应手册页中核对。启动流程是由初始化系统负责调度检查服务的,是否并行取决于其实现与配置。
容量与规模数据方面,inode 总数与已用数、块数量、日志区域大小均可通过对应的信息查看工具直接读取,不需要推测。文件数量与目录深度的分布可以用常规统计方式获得,是做耗时外推的基础。
最后说明本篇的边界:只讨论异常关机之后的文件系统一致性恢复,不涉及阵列卡与冗余配置选型,不涉及备份体系与恢复指标演练,也不涉及逻辑卷扩容。若排查后确认文件系统结构自洽而写入仍然失败,应当转向底层设备健康、链路与控制器方向取证,而不是在检查与修复这条路上反复投入。
Copyright © 2013-2020 idc10000.net. All Rights Reserved. 一万网络 科技有限公司 版权所有 深圳市科技有限公司 粤ICP备07026347号
本网站的域名注册业务代理北京新网数码信息技术有限公司的产品