资讯动态

Linux服务器重启记录排查:从last、uptime到journalctl的完整诊断指南

发布时间:2026/8/16 19:38:16 来源:尧图企业网站定制
1. 从一次线上故障说起为什么我们需要查看重启记录那天下午我正在处理一个线上服务的性能优化突然接到告警提示某台核心服务器的CPU使用率在几分钟内从平稳的20%飙升至90%以上随后又迅速回落。登录服务器一看uptime显示的系统运行时间只有不到10分钟。我心里咯噔一下服务器重启了。是硬件故障内核崩溃还是运维同学误操作在分布式系统里一次非计划内的重启背后可能隐藏着硬件老化、内核Bug、内存泄漏、甚至是安全入侵的痕迹。如果不能快速定位重启的原因和时间排查工作就像在黑暗中摸索。这就是掌握查看Linux重启历史记录这项“基本功”的价值所在。它不仅仅是执行一两条命令而是系统管理员进行故障诊断、安全审计、性能分析和合规检查的起点。无论是排查半夜的莫名宕机还是验证变更操作后的重启是否生效亦或是追溯安全事件的时间线清晰的重启日志都是最可靠的“时间证人”。对于运维、开发乃至任何需要与Linux服务器打交道的工程师来说这都是必须烂熟于心的技能。本文将带你深入Linux系统不只看“怎么查”更要弄明白“为什么能查到”、“记录存在哪里”以及“如何从这些记录里读出故事”。我们会从最常用的命令入手逐步拆解其原理并探讨在不同发行版和场景下的最佳实践让你下次面对“服务器是不是重启过”这个问题时能够自信、准确、全面地给出答案。2. 核心命令深度解析last与uptime的里里外外提到查看重启记录绝大部分资料和第一反应都是last命令。这个命令确实强大但它显示的信息远不止重启。理解它的输出是精准解读历史的第一步。2.1last命令不只是看重启直接运行last你会看到一长串列表包含了所有用户的登录、注销记录。重启记录混杂其中其典型特征是以reboot作为“用户名”并且始终从系统启动system boot开始。reboot system boot 5.4.0-42-generic Tue Aug 15 14:23 - 15:10 (00:47) reboot system boot 5.4.0-42-generic Mon Aug 14 03:15 - 14:23 (111:08) reboot system boot 5.4.0-40-generic Fri Aug 11 09:00 - 03:15 (218:15)关键字段拆解第一列 (reboot): 表示这是一个系统重启事件。第二列 (system boot): 表示事件类型为系统引导。第三列 (内核版本):这是极其重要的信息它告诉你这次重启后系统是以哪个内核版本启动的。例如从第三行到第二行内核从5.4.0-40-generic升级到了5.4.0-42-generic这很可能是一次计划内的系统更新重启。时间范围:Tue Aug 15 14:23 - 15:10 (00:47)表示系统在8月15日14:23启动并在15:10结束了该会话即发生了下一次重启或关机本次持续了47分钟。这个“结束时间”就是下一次重启发生的时间。因此要查看最近一次重启是什么时候发生的你需要看第一条reboot记录的开始时间14:23。last命令的“数据仓库”/var/log/wtmplast命令并非魔法它读取的是一个特殊的二进制日志文件/var/log/wtmp。这个文件由系统内核和登录服务如login,sshd共同维护持续记录所有成功的登录、注销、重启和关机事件。它的二进制格式保证了高效存储和查询但也意味着你不能直接用cat或vim查看其内容必须通过last这类工具来解析。注意/var/log/wtmp文件会滚动。当它增长到一定大小时会被重命名为wtmp.1然后创建新的wtmp。更旧的日志会被依次重命名为wtmp.2,wtmp.3等直到被删除。last命令默认只读取当前的wtmp如果你想查看更早的历史需要指定文件如last -f /var/log/wtmp.1。常用参数点睛last reboot: 这是最直接的用法只筛选出重启记录让输出更清晰。last -x: 这个参数非常有用它会额外显示runlevel changes运行级别变更和system shutdown系统关机事件。有时候服务器并非“重启”而是先“关机”再手动开机。last -x能帮你还原完整的过程。shutdown system down 5.4.0-42-generic Tue Aug 15 15:10 reboot system boot 5.4.0-42-generic Tue Aug 15 14:23 - 15:10 (00:47)上面这条记录结合-x参数就看到在14:23重启后系统在15:10被正常关闭了。last -n 5: 只显示最近5条记录在日志很多时便于查看。last -F: 显示完整的日期和时间年-月-日 时:分:秒对于精确的时间线分析至关重要。2.2uptime命令系统稳定性的“体温计”如果说last是查看历史病历那么uptime就是测量当前体温。它的输出简洁明了15:20:30 up 1 day, 2:30, 3 users, load average: 0.08, 0.03, 0.01up 1 day, 2:30: 这直接告诉你系统自最后一次启动以来已经连续运行了1天2小时30分钟。这是判断系统近期是否重启过的最快方法。如果这个时间很短比如几分钟、几小时那近期肯定有重启。load average: 三个负载均值1分钟、5分钟、15分钟。结合重启时间看负载可以判断重启后服务的恢复情况。例如重启后负载立刻飙升可能意味着有开机自启动的服务异常重启后负载一直很低可能有些关键服务没起来。uptime的数据来源/proc/uptimeuptime命令的信息来源于/proc/uptime这个虚拟文件。这个文件里有两个数字123456.78 987654.32第一个数字123456.78系统自启动以来的总运行时间秒。第二个数字987654.32所有CPU核心的总空闲时间秒。这个值通常用于更深入的系统性能计算uptime命令主要用第一个值。/proc是内存文件系统这里的值断电即失这也印证了uptime只能反映本次启动后的时间。实操心得不要孤立地看uptime。我习惯将uptime与last reboot | head -1结合使用。先用uptime快速感知“系统跑了多久”如果时间短再用last reboot查看具体的重启时间点并核对是否与预期的维护窗口一致。这是一种高效的“筛查-确认”工作流。3. 进阶溯源挖掘重启背后的“元凶”知道了何时重启接下来就是最关键的为什么重启这需要我们把目光投向Linux系统的“黑匣子”——系统日志。重启的原因通常就记录在这里面。3.1 系统日志 (journalctl与/var/log/messages)现代Linux发行版主要使用systemd作为初始化系统其日志由journald管理通过journalctl命令查看。使用journalctl定位重启相关日志查看本次启动以来的所有日志journalctl -b查看上一次启动的日志journalctl -b -1-2代表上上次以此类推查看特定时间段的日志journalctl --since 2023-08-15 14:20 --until 2023-08-15 14:25这对于锁定重启瞬间的日志非常有效。查看内核日志经常包含崩溃信息journalctl -k或journalctl -p kern。内核恐慌Kernel Panic、硬件错误如CPU、内存通常最先在这里体现。在重启时间点附近搜索“罪证”假设我们通过last reboot得知最近一次重启发生在2023-08-15 14:23。搜索关机/重启命令journalctl --since “2023-08-15 14:00” --until “2023-08-15 14:30” | grep -E “(reboot|shutdown|poweroff|halt)”这可能会找到由root用户执行的shutdown -r now或reboot命令的记录。搜索系统服务异常journalctl --since “2023-08-15 14:00” --until “2023-08-15 14:30” -p err查看该时间段内的所有错误级别日志。可能是某个关键服务如数据库、存储服务崩溃触发了系统的异常行为。搜索硬件和内核信息journalctl --since “2023-08-15 14:00” --until “2023-08-15 14:30” | grep -E “(panic|Oops|BUG|CPU|Memory|Hardware Error)”。这是诊断硬件故障或内核Bug的关键。对于仍使用 SysVinit 或查看传统日志的系统可以查看/var/log/messages、/var/log/syslog或/var/log/kern.log。使用grep配合时间戳进行过滤思路与journalctl类似。grep “Aug 15 14:2[0-5]” /var/log/messages | tail -503.2 谁动了我的服务器lastb与安全审计非计划重启有时与安全事件相关。攻击者获取权限后可能会重启服务器以加载恶意的内核模块或清除痕迹。除了last我们还需要关注失败的登录尝试。lastb命令查看所有失败的登录尝试。它读取/var/log/btmp文件。在重启前后一段时间内如果出现大量针对root或其他用户的失败登录记录这可能是一次暴力破解尝试需要提高警惕。last -x命令再次强调它可以帮你区分是reboot还是shutdown。一个攻击者更可能使用poweroff或halt命令而不是reboot。安全审计小技巧我会将重启审计纳入日常安全检查清单。脚本大致逻辑如下获取最近一次重启时间LAST_REBOOT_TIME。检查LAST_REBOOT_TIME前后各10分钟内的lastb记录和journalctl认证日志(journalctl _COMMsshd)统计失败次数和来源IP。检查是否有非root用户执行了sudo reboot或sudo shutdown通过journalctl _COMMsudo或/var/log/auth.log查看。将异常结果如非维护时段重启、伴随大量失败登录标记为告警。3.3 电源与硬件日志被忽视的角落如果系统日志里没有任何软件层面的异常记录那就要怀疑硬件或电源问题了。查看内核环缓冲区历史dmesg -T可以显示带时间戳的内核消息。但dmesg缓冲区容量有限重启后会丢失。更可靠的方法是查看journalctl -k。检查硬件日志如有对于服务器尤其是品牌服务器如Dell iDRAC, HP iLO, IBM IMM它们有独立的硬件管理控制器会记录更详细的硬件事件如电源状态变化、温度超标、内存ECC错误等。这些日志需要通过特定的管理工具或Web界面查看是诊断硬件引起无故重启的黄金标准。查看ACPI事件journalctl | grep -i acpi。系统因电源按钮按下、过热保护等引起的重启可能会产生ACPI事件日志。4. 实战场景与自动化运维脚本理论说再多不如实际操练一遍。下面我们通过几个真实场景串联起上述命令并分享如何用脚本实现自动化监控。4.1 场景一诊断一次莫名其妙的深夜重启背景监控显示一台数据库服务器在凌晨3点自动重启导致业务中断。没有安排维护。排查步骤确认重启事实与时间uptime # 查看运行时间确认近期重启过 last reboot | head -5 # 确认具体的重启时间点发现最近一次是 Aug 16 03:01聚焦重启瞬间的系统日志journalctl --since “2023-08-16 02:55” --until “2023-08-16 03:05”在输出中你可能会发现类似这样的关键行Aug 16 03:00:45 db-server kernel: Out of memory: Kill process 12345 (mysqld) score xxx ... Aug 16 03:00:50 db-server kernel: systemd[1]: Started User Manager for UID 1000. Aug 16 03:01:02 db-server systemd[1]: systemd-update-utmp-runlevel.service: Succeeded.“Out of memory” (OOM) 赫然在目。系统因为内存耗尽内核的OOM Killer被触发杀死了最重要的mysqld进程。在某些系统配置下关键服务崩溃可能导致系统进入不稳定状态甚至触发自动重启如果配置了kernel.panic_on_oops或kernel.panic参数。深入挖掘检查内存使用历史如果配置了监控如Prometheus查看该时间段内存使用图表。检查数据库日志/var/log/mysql/error.log可能在OOM前就有慢查询或内存泄漏的迹象。检查系统配置sysctl -a | grep panic看是否配置了kernel.panic 55秒后重启之类的参数。结论根本原因是数据库内存泄漏或异常查询导致内存耗尽触发OOM Killer进而可能因系统配置导致重启。解决方案是优化数据库配置、增加内存或排查内存泄漏的代码。4.2 场景二验证计划内重启是否成功背景你通过自动化工具如Ansible对一批服务器执行了内核升级和重启指令。需要快速验证所有服务器是否都成功重启并进入了新内核。验证脚本思路#!/bin/bash # check_reboot_status.sh TARGET_KERNEL5.4.0-100-generic # 期望升级到的内核版本 # 获取当前运行的内核版本 CURRENT_KERNEL$(uname -r) # 获取最后一次重启的时间 LAST_REBOOT_TIME$(last reboot | head -1 | awk ‘{print $5, $6, $7, $8}’) # 获取系统运行时间 UPTIME$(uptime -p | cut -d ‘ ‘ -f2-) echo “服务器: $(hostname)” echo “当前内核: $CURRENT_KERNEL” echo “期望内核: $TARGET_KERNEL” echo “最近重启时间: $LAST_REBOOT_TIME” echo “本次运行时长: $UPTIME” if [[ “$CURRENT_KERNEL” “$TARGET_KERNEL” ]]; then echo “状态: ✅ 内核升级成功” else echo “状态: ❌ 内核未升级成功仍运行旧内核” fi # 如果运行时间小于10分钟则认为是近期重启 if [[ $(echo “$UPTIME” | grep -oE ‘[0-9]’ | head -1) -lt 10 ]] [[ $(echo “$UPTIME” | grep -c ‘day’) -eq 0 ]] [[ $(echo “$UPTIME” | grep -c ‘hour’) -eq 0 ]]; then echo “提示: 系统近期已重启运行时间$UPTIME” else echo “提示: 系统运行时间较长可能未按计划重启” fi通过Ansible等工具在多台服务器上运行此脚本可以快速生成一份清晰的验证报告。4.3 自动化监控非计划重启告警对于生产环境我们需要主动发现非计划重启。可以编写一个简单的监控脚本定期检查并告警。Zabbix Agent自定义监控项示例创建监控项监控系统运行时间。UserParametersystem.uptime.seconds,cat /proc/uptime | awk ‘{print $1}’在Zabbix Server端配置触发器如果system.uptime.seconds在短时间内如2个监控周期急剧下降例如从几万秒变成几百秒则触发告警。表达式{your_host:system.uptime.seconds.delta(5m)} -300 含义5分钟内运行时间减少超过300秒5分钟极有可能发生了重启。简易Shell脚本监控示例#!/bin/bash # monitor_reboot.sh LOG_FILE“/var/log/reboot_monitor.log” UPTIME_FILE“/tmp/last_uptime.txt” current_uptime$(cat /proc/uptime | awk ‘{print $1}’) last_uptime$(cat $UPTIME_FILE 2/dev/null || echo “0”) # 将当前运行时间写入文件供下次比较 echo $current_uptime $UPTIME_FILE if [[ $(echo “$last_uptime $current_uptime” | bc) -eq 1 ]]; then # 如果上次记录的运行时间比当前大说明发生了重启 reboot_time$(date “%Y-%m-%d %H:%M:%S”) echo “[$reboot_time] 检测到系统重启当前运行时间: $current_uptime 秒” $LOG_FILE # 这里可以添加发送告警邮件的命令例如 # echo “主机 $(hostname) 于 $reboot_time 发生重启” | mail -s “非计划重启告警” adminexample.com # 或者调用Webhook fi将此脚本加入crontab每分钟执行一次。它通过比较前后两次记录的/proc/uptime值来判断是否发生了重启。这种方法比解析last命令更直接延迟更低。5. 疑难杂症与最佳实践在实际操作中你可能会遇到一些棘手的情况。这里分享几个常见问题和处理经验。5.1 日志被清空或轮转了怎么办/var/log/wtmp为空或很小这可能是因为日志轮转策略激进如logrotate配置为每天轮转并只保留1天或者被人为清空 /var/log/wtmp。如果文件存在但last没输出可以用file命令检查它是否是二进制格式或者用last -f /var/log/wtmp强制指定文件。检查/var/log/wtmp.1,wtmp.2.gz等归档文件。journalctl看不到历史启动日志默认情况下journald将日志存储在/run/log/journal内存中重启即失。要持久化需要创建/var/log/journal目录并设置正确的权限。检查/etc/systemd/journald.conf中的Storage选项确保其值为persistent或auto且/var/log/journal存在。时间不对所有日志分析的前提是系统时间准确。务必确保服务器已启用并正确同步NTP使用chronyd或ntpd。如果日志时间与真实时间有偏差会给排查带来巨大困扰。5.2 容器环境下的“重启”查看在Docker容器或Kubernetes Pod中情况有所不同。容器内容器内的进程通常看不到宿主机的重启历史。容器内的uptime显示的是容器进程的启动时间而非宿主机。last命令在大多数基础镜像中不可用因为容器内没有/var/log/wtmp文件。正确姿势要查看宿主机是否重启以及重启对容器的影响需要从宿主机层面或容器编排平台层面查看。宿主机在宿主机上执行last reboot和journalctl。Dockerdocker events命令可以查看Docker守护进程的事件流其中可能包含因宿主机重启导致的容器停止、启动事件。检查容器的重启策略docker inspect container_id | grep -A 10 RestartPolicy。Kubernetes使用kubectl describe pod pod-name查看 Pod 的Events部分。如果节点重启Pod会被重新调度事件中会有NodeLost、Scheduled、Pulling、Started等一系列记录。使用kubectl get nodes查看节点的AGE如果时间很短可能重启过。5.3 最佳实践总结日志持久化是第一要务确保journald使用持久化存储并合理配置logrotate以保留足够时长的wtmp、btmp、syslog等关键日志建议至少30天。时间同步是基石部署可靠的NTP服务这是所有日志分析具有可信度的前提。建立重启审计基线明确所有服务器的计划维护窗口。任何非窗口期的重启都应视为异常事件触发告警和排查流程。关联分析不要只看重启记录。将重启时间点与监控系统CPU、内存、磁盘、网络、应用日志、数据库日志、安全日志进行关联分析才能拼出完整的真相。善用自动化像场景三那样通过简单的脚本将重启监控纳入你的运维监控体系变被动为主动。理解上下文区分计划内重启内核升级、硬件维护和计划外重启故障、攻击。对于计划外重启要形成标准的排查SOP标准作业程序按照日志类型逐层深入。查看Linux重启历史远不止是输入一个命令。它是一个从现象系统运行时间短出发通过层层日志last,uptime,journalctl抽丝剥茧最终定位到根本原因OOM、内核Bug、硬件故障、人为操作的完整侦探过程。掌握这套方法和工具链你就能在服务器出现异常时快速稳住阵脚找到问题的源头。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价