关于我们

质量为本、客户为根、勇于拼搏、务实创新

< 返回新闻公共列表

整机重启后只剩 uptime 归零:内核崩溃转储该怎么提前留好

发布时间:2026-10-14

机器自己重启了。监控上最后一次采样还是绿的,再下一次心跳就是重新上线后的第一条记录;登录进去一看,uptime 从几十天归零到几分钟,系统日志的最后一行只剩一个时间戳,没有堆栈,没有进程名,没有任何「谁干的」的线索。业务侧报的是「那几分钟不可用」,运维侧能给出的解释只有一句:它重启了。

这类事故最难处理的地方在于,现场在重启的那一刻就已经没了。内存里几十 GB 的进程状态、内核数据结构、正在排队的 IO、锁的持有关系、还没落盘的连接上下文,全部随着复位被抹掉,剩下的是一个重新跑起来的、干净得毫无信息量的系统。如果这台机器一个月重启两次,你连「这两次是不是同一个原因」都判断不了,只能凭猜;而猜出来的结论在下次重启时又被清零一次,排查就变成了一个永远停在起点的循环。

于是本篇要回答的问题就很具体了:整机级崩溃的现场,能不能在崩溃发生之后拿回来?答案是能,但前提是崩溃发生之前就把该准备的都准备好。事后才想起来配置,等于什么都没有——这不是操作顺序的问题,而是机制本身决定的,读完下面几节就会明白为什么。

先分清两类现场:进程级 core 与整机级转储

「进程崩了」和「机器崩了」在口语里都叫崩溃,但取证手段是两套完全不同的东西。把它们混在一起讨论,最后往往是两套都配了、两套都拿不到可用文件。

进程级崩溃,指的是某个进程因为非法访问、断言失败、被信号终止等原因退出,内核按既定的输出规则把该进程的用户态内存、寄存器和映射信息写成文件。这件事发生在系统正常运转期间:调度器还在跑,文件系统还在正常服务,其他进程毫无感知,uptime 不会归零。这类取证的成败主要取决于输出规则怎么写、目标目录是否存在且可写、权限与磁盘空间是否足够。此前已有一篇专门讲这条落盘链路的文章,本篇不重复,也不讨论。

整机级崩溃是另一回事。内核自身进入了它认为无法继续安全运行的状态而主动停机(通常表现为 panic),或者硬件、固件层面的故障让整台机器挂死,被看门狗或人工硬重启。这时候没有调度,没有可用的文件系统写入路径,没有 shell,屏幕上可能只留下一行输出,也可能什么都没有。进程级那套「让内核帮忙写个文件」的思路在这里根本不成立,因为负责写文件的那个内核本身已经不能用了,你不能指望一个已经停机的东西去操作磁盘。

本篇只讨论后者,也就是整机内核级崩溃的取证。判断标准很简单:看 uptime 有没有归零,看系统日志里有没有正常关机的记录,看机器是不是在无人操作的情况下重新出现。只要满足其中任意一条,就属于本篇的范围。

还要先说清楚一条边界,免得把转储当成万能药。有些整机故障连本篇讲的机制也覆盖不了:整机完全掉电、固件层挂死、CPU 或内存出现物理故障导致处理器根本走不到崩溃处理路径。这类情况里,机器连「知道自己崩了」这一步都没走到,自然不会有转储。它们只能依靠固件与带外管理侧留下的记录,配置转储并不能替代带外日志与硬件事件记录的作用。

预留内存与第二内核:崩溃那一刻到底是谁在写盘

整机崩溃之后还能写出文件,靠的是一套「提前埋好、崩溃时接管」的机制。整套思路可以拆成三块来看,这三块缺任何一块都跑不通。

第一块是预留内存。系统正常启动时,通过内核启动参数(这类参数通常写作 crashkernel 一类的形式,具体语法与取值以所用发行版文档为准)从物理内存中划出一段专门区域。这段区域在正常运行期间不参与普通的内存分配,业务进程看不到也用不到,它唯一的用途就是留给崩溃后的备用内核。正因为正常运行期没人碰它,崩溃发生时这段内存的内容与布局才是确定的、可预期的——这一点很关键,一个随时可能被业务数据覆盖的区域是没法当落脚点的。

第二块是第二内核,常被称为捕获内核或转储内核。在系统启动阶段,就通过 kexec 类机制把第二个内核映像和它配套的内存盘预先加载到预留区域里,并把加载地址、启动入口等信息登记给主内核。这个第二内核不需要完整的设备枚举,也不需要业务用的那一整套驱动,它只需要做一件事:把转储目标跑起来,把主内核的内存读出来写下去。

第三块是崩溃后的接管。主内核在 panic 或其他触发条件下进入崩溃处理路径,它不会走正常关机流程,也不会让固件重新上电自检,而是直接跳转到已经预加载好的第二内核。这一步是整个机制的核心——因为跳过了固件重启与硬件复位,DRAM 里的内容没有被清空,主内核的内存数据结构仍然完整地留在原地。第二内核启动之后,把主内核的内存以只读视图的形式暴露出来(通常以 /proc/vmcore 这类接口呈现,接口名与路径以所用发行版文档为准),随后由一个用户态工具(makedumpfile 一类)读取这个视图,按规则过滤、压缩,写到事先配置好的目标里去。

理解这条链路,就能理解为什么「事后配置」没有任何意义:预留内存要在启动时划走,第二内核映像要在启动时加载,目标所依赖的驱动要在内存盘里备好。这三件事全部发生在正常运行期,崩溃那一刻只负责执行,不负责准备。任何一项在崩溃前没做完,崩溃后就只能得到一个空的或者不存在的文件。

那么什么情况会触发这套机制?常见入口包括内核 panic、不可屏蔽中断、硬锁定与软锁定检测、机器检查异常类的硬件错误、看门狗超时,以及人为通过系统请求键或调试接口触发的强制崩溃。不同内核版本与发行版对这些入口的支持程度、默认开关都不一样,是否需要显式开启也各不相同,一律以所用发行版文档为准,不要照抄别的环境的配置。

三个必答问题:预留多少、写哪里、写什么级别

把 kdump 类机制真正配起来,本质上就是回答三个问题。这三个问题只要有一个回答得含糊,配置就只是「看起来配了」。

第一个问题:预留多少内存。预留区域要装下的东西包括第二内核映像本身、它挂载目标所必需的内存盘、页表以及各类工作区。需求随主内存容量增大而增大(要管理的页表更多),也随设备与驱动数量增加而增大。常见做法是按内存规模分档:小内存的机器给一个较小的固定值,大内存的机器给更大的固定值或按一定比例计算;不同架构、不同发行版、不同内核版本的分档规则并不一致,所以这里不给具体数字,以所用发行版文档为准。预留过小的典型表现是第二内核根本起不来,或者转储写到一半因内存不足中断,最后落下一个残缺文件——这种残缺文件比没有文件更麻烦,因为它看起来像是成功了。预留过大则长期占用业务可用内存,属于纯粹的浪费。还有一类隐蔽问题:某些平台对预留区域的地址范围有要求,参数数值写对了但位置没写对,同样起不来。

第二个问题:写哪里。目标必须在第二内核那个精简环境里可用,而第二内核只有内存盘里带着的那点驱动和工具。这意味着,一个在你眼里「明明就插在本机上」的磁盘,如果它的控制器驱动、文件系统模块,或者卷管理、多路径、加密这类中间层没有打包进第二内核的内存盘,那它在崩溃那一刻就是不可见的。目标的每一种依赖都必须显式复刻到内存盘里,这是最容易被忽略、也是失败率最高的一步。很多转储失败不是参数写错,而是这条依赖链上某一层在内存盘里根本不存在。

第三个问题:写什么级别、过滤掉什么。全量转储把整份内存视图原样写下,信息最全、体积最大、耗时最长。过滤转储则按页面类型做取舍:零页和空闲页几乎不携带诊断信息却占据大量空间,通常第一批被排除,这一档的性价比最高;再往上可以排除用户态进程页与页缓存,只保留内核态数据结构,体积会大幅下降,代价是失去分析用户态进程状态的能力;某些实现还支持更细的按进程或按地址区间过滤。选哪一档,取决于你要回答的是「内核哪里出错了」还是「那个进程当时正在干什么」。过滤规则由 makedumpfile 一类工具的级别参数控制,级别编号与具体含义因版本而异,以所用发行版文档为准。

关于预留内存的「浪费」问题,值得单独说一句。预留区在正常运行期确实不能被业务使用,代价是可用内存减少,这一点必须承认。但把它和整机崩溃无法取证的风险放在一起权衡,多数场景下是划算的:一次说不清原因的重启,往往要花掉远多于这点内存价值的排查工时。真正需要注意的是不要过度预留,以及在内存容量发生变化(加内存、换机型、迁移到不同实例规格)之后重新核对预留值是否仍然合适。

本地盘、网络与专用设备:谁会在关键时刻掉链子

转储目标的选择,本质上是在选一条「第二内核启动后到达目标所必须经过的依赖链」。链越短越可靠。下面这张表按三类目标分别列出成功条件、典型失败原因和适用场景。

转储目标 成功条件 典型失败原因 适用
本地盘(独立分区或目录) 控制器驱动与文件系统模块已在第二内核内存盘中;目标可挂载且可写;剩余空间大于转储量级 驱动未打进内存盘;目标位于卷管理、多路径或加密层之下而第二内核未装配;日志型文件系统在崩溃后状态不一致;空间不足导致写入中途失败 物理机单机取证,不依赖网络,最常见也最稳妥
网络目标(文件共享或加密传输类) 网卡驱动与网络配置在内存盘中;地址与路由可达;认证凭据已内置且有效;对端服务在崩溃时段在线 网卡驱动缺失;虚拟网卡、聚合、虚拟局域网等拓扑未在内存盘复刻;链路刚起来时未就绪;对端不可达或认证失败;大内存导致传输时间过长被中断 无冗余本地盘位、需要集中收集分析、盘位受限的机型
专用设备(独立块设备或裸分区) 第二内核能按偏移量直写;设备路径稳定;该设备不与其他用途冲突;容量充足 设备路径在重启后发生变化;偏移量与实际布局不符;设备被误挂载为文件系统;容量不足 要求确定性写入、希望绕开文件系统与网络依赖的场景
带外与固件侧记录(非转储) 带外管理可用;事件日志与串行输出已开启;日志缓冲区未被后续启动覆盖 带外未配置或网管口不通;日志缓冲区被新记录覆盖;虚拟机形态不向客户提供这一层 作为转储失效时的兜底证据,不替代转储

关于本地盘还要补充一点容易被误解的地方:第二内核挂载目标时,通常不会执行完整的文件系统检查与日志重放,因为在这个阶段做任何写修复都可能破坏主内核留在内存里的现场。这就带来一个实际问题——如果目标文件系统在崩溃时正处于不一致状态,挂载可能失败或只能以受限方式挂载。因此为转储单独准备一个结构简单、用途单一、平时不被业务写入的分区,比把转储丢进业务数据盘要可靠得多。

关于网络目标,常见的提问是「要不要把转储传到别的机器」。这个问题的答案取决于两件事:本地有没有可靠的独立盘位,以及你是否需要把多台机器的转储集中到一处分析。集中收集的好处是分析环境统一、便于保留与审计;代价是引入了一整条新的依赖链,且这条链恰恰是在最不稳定的时刻被使用。如果本地盘位充足,优先本地;如果必须走网络,就把网络配置做减法——固定地址、简单拓扑、最少中间设备。

内存越大转储越难:容量、压缩与重启时长的三角关系

这里有一个反直觉但必须接受的结论:机器的内存越大,成功拿到转储的难度越高,而不是越低。

原因很直接。转储文件的上限就是物理内存的大小——不做过滤、不做压缩时,输出量级就接近内存容量(加上页结构等元数据,实际会略有出入,具体以工具实现为准)。内存从几十 GB 涨到几百 GB、再到 TB 级,需要写出的字节数是线性上涨的,而这会带来四个同步上涨的后果:目标空间要求上涨、写入耗时上涨、传输耗时上涨(如果走网络)、以及写到中途失败的概率上涨。换句话说,一台内存很大的机器,恰恰是最难取证的那台机器。做容量规划时如果只盯着「内存大性能好」,就会在这里吃亏。

压缩是应对这个反向关系的主要手段,但它本身也是一场取舍。压缩级别越高,最终文件越小,对磁盘空间和网络传输的压力越小;代价是压缩消耗的 CPU 时间越长,写盘的有效速度越慢,而且在第二内核那种内存受限、核心未必能全部用上的环境里,压缩本身还要额外占用内存。所以「把压缩开到最高」并不总是最优解:如果目标是本地大容量盘,且首要诉求是尽快恢复服务,那么较低压缩甚至不压缩反而能让业务更快回来;如果目标是网络,或者本地空间确实紧张,那么用 CPU 时间换体积就是划算的。部分工具支持并行压缩以利用多核,是否可用、如何开启同样以所用发行版文档为准。至于实际吞吐,它受本地盘顺序写能力、CPU 核数与压缩算法共同影响,需要以自有环境评估,不要照搬别人给的数字。

第三边是重启时长。整机崩溃之后,服务不可用的时长大致由几段相加:固件与引导时间、第二内核启动时间、转储的读取/过滤/压缩/写入时间、第二次重启到系统就绪的时间、以及业务自身的恢复时间(数据库的崩溃恢复、缓存预热、副本追赶)。转储写入是其中唯一一段纯粹为取证而付出的停机,它的长度直接决定了你为这次取证付了多少业务代价。这也是为什么在内存很大的机器上,降低转储级别往往不再是「省磁盘」的问题,而是「能不能接受这么长的停机」的问题。一个更实用的做法是反过来推:先给停机时长设一个业务可接受的上限,再倒推该选什么过滤级别、什么压缩级别、什么目标。

还有一个常被忽略的细节:转储写入期间机器是不能提供服务的,而这段时间的长短在平时完全看不到。只有在演练时真正触发一次,才能知道那台几百 GB 内存的机器到底会让业务停多久。把「多久能恢复服务」写进预案,靠估算是不行的。

云主机与虚拟机的三处差异

在物理机上讨论转储,默认前提是这台机器归你管到底:从固件到驱动到磁盘,每一层你都能碰。到了云主机和虚拟机,这个前提被切成了几段,每一段都可能让方案落空。

第一处差异是预留内存。客户机内能不能真正划出并使用预留区域,取决于虚拟化平台向客户机呈现的内存与固件形态,以及客户机内的第二内核能否在该实例类型上正常加载。有些镜像默认就没有启用这套机制,有些实例类型或引导方式会限制 kexec 类机制的使用。结论不是「云上不能用」,而是「必须在该实例类型上真正验证一次才能确定」,不能因为参数写进配置文件就认为它一定生效。

第二处差异是带外手段。物理机通常配有基板管理控制器一类的带外管理能力,即便客户机完全无响应,也能从带外拿到串行日志、屏幕画面、硬件事件记录和远程控制能力,这些在转储失败时是最后一道证据来源。虚拟机一般不向客户提供这一层,能拿到的通常是平台侧提供的串行控制台输出、实例事件记录或截图类功能,具体有什么、保留多久、能不能导出,因平台而异,需要逐项确认。

第三处差异是宿主侧取证。虚拟机的物理内存本质上是宿主的资源,客户机内的崩溃在宿主侧可能存在另一种记录形式,比如虚拟化层的日志、宿主自身的异常、实例生命周期事件。问题在于客户通常没有权限自行获取这些内容。于是这件事应当在选型或签约阶段就问清楚:当一台虚拟机突然消失或重启时,服务商能提供哪些宿主侧证据、以什么形式提供、多长时间内可查、是否需要提前申请。这四个问题如果有明确答案,取证方案的完整性会好很多。

还必须说清一种情形:如果崩溃实际发生在宿主层,比如宿主内核故障、宿主内存或 CPU 硬件故障、宿主被计划内运维操作重启,那么客户机只会表现为毫无征兆地消失或重启,客户机内部无论怎么配置都拿不到现场,因为它根本没有进入自己的崩溃处理路径。这时唯一的证据来源就是服务商侧的通报与宿主日志。理解这一点,可以避免在虚拟机里投入大量精力配置一套在本场景下注定用不上的机制——不是说不该配,而是说配完之后仍要明确哪一类情况只能靠服务商。

需要提前预留内存和确认带外手段这类底层能力的场景,一万网络(深耕 19 年,成立于 2007 年)可以在交付前把物理机与虚拟机的差异讲清楚,避免客户把取证方案建在拿不到的能力上。在按内存容量与本地盘配比挑选整机方案时,也可以顺带确认预留内存与带外能力这两项是否具备,省得事后返工。

转储里躺着内存里的敏感数据:期限与访问控制

转储文件是物理内存的快照,这一点决定了它的密级。内存里有什么,转储里就有什么:明文口令、会话令牌、密钥材料、数据库连接串、正在处理的请求内容、缓存中的文件片段、用户数据。其中相当一部分在磁盘上并不存在,或者说以加密或分片的形式存在,却在内存里以明文形态被完整保留下来。因此转储文件的密级应当按「内存中的最高密级」来定,而不是按它所在磁盘分区的密级来定。

保存期限要有明确上限。转储的价值集中在事件处置窗口内:定位根因、向厂商提交分析、内部复盘。一旦结案,这份文件的分析价值迅速衰减,而泄露风险长期存在。合理的做法是为转储目录设定一个明确的保留期,结案后按既定流程删除,并且不要让它长期堆积在业务盘上——堆积的转储既占空间,又会在某次磁盘空间告警时被慌乱地批量清理,反而留下不可控的删除行为。

访问控制要按最小权限设计:单独的存放位置,独立于业务数据目录;只有需要参与分析的人员可以访问;每一次访问有记录可查;跨机器传输时使用加密通道。如果转储里包含个人信息,把它从一个地域传到另一个地域之前,需要按适用的数据与个人信息保护要求判断能否这样做、需要什么前置手续,这一步不要凭直觉处理。

需要把转储交给第三方(例如软硬件厂商的支持团队)分析时,有两条降低风险的路:一是提高过滤级别,排除用户态页面与页缓存,只保留内核态数据结构——这既能大幅缩小体积,也顺带显著降低了敏感数据的含量,但代价是失去用户态分析能力;二是对文件本身做加密并签署保密约定,同时保留交付记录。两条路可以并用,但要在配置阶段就决定,不要在崩溃之后临时讨论。

加密写入也是一种选择,通过在目标侧使用加密卷或在写出链路上做加密实现。但要注意它会给第二内核环境增加新的依赖,配置复杂度上升,而在崩溃那一刻,依赖越多失败概率越高。是否引入加密,取决于合规要求与可靠性之间的权衡,没有统一答案。

演练一次崩溃,才知道配置有没有生效

配置写进文件,和崩溃时真的能拿到现场,是两件完全不同的事。区分它们的唯一办法是主动触发一次崩溃,在受控环境下把整条链路跑一遍。

验证可以分为两层。第一层是静态检查:确认启动参数里确实带有预留内存的设定,并且系统启动日志中能看到预留区域被成功划出;确认第二内核映像的加载状态是正常的;确认内存盘里包含了目标所需的所有驱动与工具。静态检查能发现「忘了更新引导项」「改了参数没重建内存盘」这类最常见的疏漏,但它发现不了「挂载时才发现文件系统状态不对」这种运行期问题。

第二层是实际触发。主流内核提供了通过系统请求键或调试接口强制触发崩溃的方式,也支持通过不可屏蔽中断触发,具体开关名称与操作路径以所用发行版文档为准。触发前必须做好三件事:选在维护窗口、业务负载已经切走、提前通知机房与上联方,避免被误判成真实事故或被监控自动执行故障切换。

一次合格的演练要验证四件事,少一件都不算通过。第一,能否真正进入第二内核——如果卡住或直接重启了,说明预留或加载有问题。第二,能否成功写入目标——写入失败是最常见的失败形态,且失败原因往往在内存盘的依赖链上。第三,写入耗时多久——记下从触发到转储完成的秒数,这个数字是容量规划和停机预案的直接输入。第四,重启之后文件是否完整可读——不能只看文件大小,要用内核调试分析类工具真正打开它、跑几个基本命令,确认里面确实有可用的数据结构。

演练的频率不能只按日历排。以下情况每一次都要重新验证:内核升级之后;更换主板、内存、存储或网卡之后;内存容量发生变化之后;迁移机房或基于镜像重建实例之后;转储目标的位置或类型调整之后。例行验证可以按季度或半年安排一次,关键系统可以随变更窗口一起做。另外还有一类容易被忽略的失效:过滤级别配置错误,导致文件写出来了、大小也正常,但里面没有你需要的那部分内容——这种问题只有在演练后真正打开文件才能发现。

最后把演练结果落到文档上:记录该机型的预留值、目标、过滤与压缩级别、演练中记录的写入耗时、以及从触发到业务可用的总时长。这份记录既是下次排查的参照,也是回答「崩溃后多久能恢复服务」这个问题的唯一可靠依据。

本篇事实来源:转储机制与容量判断怎么核对

本篇涉及的机制描述均为主流 Linux 内核崩溃转储机制的通用思路:启动期预留内存、预加载第二内核、崩溃时跳转并由第二内核读取内存视图写出转储、由用户态工具完成过滤与压缩。这条思路在不同发行版上的落地方式不同,参数名与默认值也有差异。

需要自行核对的部分主要有三类。第一类是参数与默认值:预留内存的启动参数写法与分档规则、内存视图的接口路径、过滤级别编号与含义、压缩与并行压缩的开关,这些一律以所用发行版与内核版本的官方文档为准,本篇不提供具体数值,也不建议跨版本照抄。第二类是容量与时间:转储文件的量级、压缩后的体积、写入耗时、以及由它们决定的停机时长,这些都强烈依赖具体硬件、内存容量、目标类型与压缩算法,需要在自有环境里实际跑一遍才能确定,任何来自外部的数字都只能当作量级参考。第三类是平台能力:实例类型是否支持预留内存与第二内核、平台提供哪些崩溃时可见的外部证据、宿主侧故障是否会通报以及以什么形式通报,这些只能向服务商逐项确认。

本篇没有引用任何具体客户场景或性能数字,所有结论都是机制层面的推理与工程取舍。如果你的环境与上述假设不同,以你的环境为准;如果某项能力在你的平台上不存在,应当换一条取证路径,而不是在拿不到的能力上继续投入。


上一篇:2026 巴基斯坦云服务器租用首月价与档位断层避雷手册

下一篇:2026 波哥大云服务器租用不限流量端口速率对比避坑全攻略