系统启动问题

title

系统启动问题是Linux运维中最紧急的问题之一,会导致服务器无法正常提供服务,需要快速诊断和修复。

🚨 问题现象

常见错误信息

# GRUB错误
GRUB rescue>
error: no such partition
error: file '/boot/vmlinuz' not found

# 内核启动错误
Kernel panic - not syncing
Unable to mount root fs
VFS: Cannot open root device

# 系统服务错误
systemd: Failed to start xxx.service
emergency mode: Cannot continue
A start job is running for xxx (timeout)

# 文件系统错误
fsck.ext4: No such file or directory
e2fsck: Attempt to read block from filesystem resulted in short read

系统表现

  • 系统无法启动
  • 启动过程卡住
  • 进入紧急模式
  • 重启循环
  • 黑屏或蓝屏

🔍 问题诊断

1. 检查GRUB启动器

# GRUB救援模式下检查
grub rescue> ls
grub rescue> ls (hd0,1)/
grub rescue> ls (hd0,1)/boot/

# 正常系统中检查GRUB
sudo grub-mkconfig -o /boot/grub/grub.cfg
sudo update-grub

# 查看GRUB配置
cat /boot/grub/grub.cfg
cat /etc/default/grub

2. 检查内核和启动文件

# 查看内核文件
ls -la /boot/vmlinuz*
ls -la /boot/initrd*
ls -la /boot/config*

# 检查内核版本
uname -r
cat /proc/version

# 查看可用内核
dpkg --list | grep linux-image  # Ubuntu/Debian
rpm -qa | grep kernel           # CentOS/RHEL

3. 检查文件系统

# 检查根分区
lsblk
mount | grep " / "
df -h /

# 检查fstab配置
cat /etc/fstab

# 检查文件系统状态
fsck -n /dev/sda1  # 只检查不修复

4. 查看启动日志

# 查看系统启动日志
journalctl -b
journalctl -b -1  # 上一次启动

# 查看内核日志
dmesg
dmesg | grep -i error

# 查看启动时间分析
systemd-analyze
systemd-analyze blame
systemd-analyze critical-chain

5. 检查硬件状态

# 检查内存
memtest86+

# 检查硬盘
smartctl -a /dev/sda
badblocks -v /dev/sda

# 检查CPU温度
sensors

🛠️ 解决方案

GRUB启动问题

1. GRUB救援模式修复

# 在GRUB救援模式下
grub rescue> ls  # 查看可用分区

# 找到Linux分区
grub rescue> ls (hd0,1)/
grub rescue> ls (hd0,1)/boot/

# 设置正确的分区
grub rescue> set root=(hd0,1)
grub rescue> set prefix=(hd0,1)/boot/grub

# 加载normal模块
grub rescue> insmod normal
grub rescue> normal

# 或直接启动Linux
grub rescue> linux (hd0,1)/boot/vmlinuz root=/dev/sda1
grub rescue> initrd (hd0,1)/boot/initrd.img
grub rescue> boot

2. 重新安装GRUB

# 使用Live CD启动后
sudo mount /dev/sda1 /mnt
sudo mount --bind /dev /mnt/dev
sudo mount --bind /proc /mnt/proc
sudo mount --bind /sys /mnt/sys

# 进入chroot环境
sudo chroot /mnt

# 重新安装GRUB
grub-install /dev/sda
update-grub

# 退出chroot
exit
sudo umount /mnt/sys
sudo umount /mnt/proc
sudo umount /mnt/dev
sudo umount /mnt

3. 修复GRUB配置

# 编辑GRUB默认配置
sudo vim /etc/default/grub

# 常用配置项
GRUB_DEFAULT=0
GRUB_TIMEOUT=10
GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
GRUB_CMDLINE_LINUX=""

# 更新GRUB配置
sudo update-grub

内核启动问题

1. 使用旧内核启动

# 在GRUB菜单中选择"Advanced options"
# 选择较旧的内核版本启动

# 启动后移除有问题的内核
sudo apt remove linux-image-x.x.x-x  # Ubuntu/Debian
sudo yum remove kernel-x.x.x-x       # CentOS/RHEL

# 重新生成GRUB配置
sudo update-grub

2. 修复内核参数

# 临时修改内核参数(在GRUB编辑模式)
# 按 'e' 编辑启动项,在linux行添加参数

# 常用修复参数
init=/bin/bash           # 直接进入bash
single                   # 单用户模式
rescue                   # 救援模式
nomodeset               # 禁用显卡驱动
acpi=off                # 禁用ACPI
noapic                  # 禁用APIC

3. 重建initramfs

# Ubuntu/Debian
sudo update-initramfs -u -k all

# CentOS/RHEL
sudo dracut --force

# 手动指定内核版本
sudo update-initramfs -u -k 5.4.0-42-generic
sudo dracut --force --kver 3.10.0-1127.el7.x86_64

文件系统问题

1. 修复损坏的文件系统

# 进入单用户模式或救援模式
# 卸载根分区(如果可能)
umount /

# 检查并修复文件系统
fsck -y /dev/sda1     # 自动修复
e2fsck -f /dev/sda1   # 强制检查ext系列
xfs_repair /dev/sda1  # 修复XFS

# 如果根分区无法卸载,以只读方式重新挂载
mount -o remount,ro /
fsck -y /dev/sda1
mount -o remount,rw /

2. 修复fstab错误

# 进入紧急模式
systemctl rescue

# 以读写方式重新挂载根分区
mount -o remount,rw /

# 备份并编辑fstab
cp /etc/fstab /etc/fstab.backup
nano /etc/fstab

# 注释或修正错误的条目
# 测试配置
mount -a

系统服务问题

1. 禁用问题服务

# 进入紧急模式
systemctl rescue

# 查看失败的服务
systemctl --failed

# 禁用问题服务
systemctl disable problematic.service
systemctl mask problematic.service

# 重启到正常模式
systemctl default

2. 修复服务配置

# 检查服务配置
systemctl status service_name
journalctl -u service_name

# 重置服务失败状态
systemctl reset-failed service_name

# 重新加载systemd配置
systemctl daemon-reload

🔧 启动问题排查脚本

系统启动诊断脚本

#!/bin/bash
# boot_diagnosis.sh

echo "======== 系统启动诊断报告 ========"
echo "诊断时间: $(date)"
echo

# 1. 检查GRUB配置
echo "=== GRUB配置检查 ==="
if [ -f /boot/grub/grub.cfg ]; then
    echo "✓ GRUB配置文件存在"
    GRUB_ENTRIES=$(grep "menuentry" /boot/grub/grub.cfg | wc -l)
    echo "GRUB启动项数量: $GRUB_ENTRIES"
else
    echo "❌ GRUB配置文件不存在"
fi

# 2. 检查内核文件
echo "=== 内核文件检查 ==="
KERNEL_COUNT=$(ls /boot/vmlinuz* 2>/dev/null | wc -l)
INITRD_COUNT=$(ls /boot/initrd* 2>/dev/null | wc -l)

echo "内核文件数量: $KERNEL_COUNT"
echo "initrd文件数量: $INITRD_COUNT"

if [ $KERNEL_COUNT -gt 0 ] && [ $INITRD_COUNT -gt 0 ]; then
    echo "✓ 内核文件完整"
else
    echo "❌ 内核文件缺失"
fi

# 3. 检查fstab配置
echo "=== fstab配置检查 ==="
if mount -a -v 2>/dev/null; then
    echo "✓ fstab配置正确"
else
    echo "❌ fstab配置有错误"
    echo "错误详情:"
    mount -a -v
fi

# 4. 检查文件系统
echo "=== 文件系统检查 ==="
ROOT_DEVICE=$(mount | grep " / " | awk '{print $1}')
echo "根分区设备: $ROOT_DEVICE"

if [ -n "$ROOT_DEVICE" ]; then
    FS_TYPE=$(mount | grep " / " | awk '{print $5}')
    echo "文件系统类型: $FS_TYPE"

    # 检查文件系统状态(只读检查)
    if fsck -n "$ROOT_DEVICE" >/dev/null 2>&1; then
        echo "✓ 根分区文件系统正常"
    else
        echo "⚠️  根分区文件系统可能有问题"
    fi
fi

# 5. 检查系统服务
echo "=== 系统服务检查 ==="
FAILED_SERVICES=$(systemctl --failed --no-legend | wc -l)
echo "失败的服务数量: $FAILED_SERVICES"

if [ $FAILED_SERVICES -gt 0 ]; then
    echo "失败的服务:"
    systemctl --failed --no-legend | awk '{print "  " $1}'
fi

# 6. 检查启动时间
echo "=== 启动性能检查 ==="
if command -v systemd-analyze &> /dev/null; then
    BOOT_TIME=$(systemd-analyze | head -1)
    echo "启动时间: $BOOT_TIME"

    echo "启动耗时TOP 5服务:"
    systemd-analyze blame | head -5 | while read line; do
        echo "  $line"
    done
fi

# 7. 检查磁盘空间
echo "=== 磁盘空间检查 ==="
ROOT_USAGE=$(df / | tail -1 | awk '{print $5}' | cut -d'%' -f1)
BOOT_USAGE=$(df /boot 2>/dev/null | tail -1 | awk '{print $5}' | cut -d'%' -f1)

echo "根分区使用率: ${ROOT_USAGE}%"
if [ -n "$BOOT_USAGE" ]; then
    echo "/boot分区使用率: ${BOOT_USAGE}%"
fi

if [ $ROOT_USAGE -gt 95 ]; then
    echo "⚠️  根分区空间不足"
fi

if [ -n "$BOOT_USAGE" ] && [ $BOOT_USAGE -gt 90 ]; then
    echo "⚠️  /boot分区空间不足"
fi

# 8. 建议操作
echo "=== 建议操作 ==="
if [ $FAILED_SERVICES -gt 0 ]; then
    echo "1. 检查失败的服务: systemctl status <service_name>"
    echo "2. 查看服务日志: journalctl -u <service_name>"
fi

if [ $ROOT_USAGE -gt 90 ]; then
    echo "3. 清理磁盘空间: sudo apt autoremove && sudo apt autoclean"
fi

echo "4. 查看详细启动日志: journalctl -b"
echo "5. 分析启动性能: systemd-analyze critical-chain"

自动修复脚本

#!/bin/bash
# boot_auto_fix.sh

echo "启动问题自动修复脚本"
echo "===================="

# 1. 修复GRUB
echo "检查并修复GRUB..."
if [ ! -f /boot/grub/grub.cfg ]; then
    echo "重新生成GRUB配置..."
    sudo update-grub
fi

# 2. 清理/boot空间
echo "检查/boot分区空间..."
BOOT_USAGE=$(df /boot 2>/dev/null | tail -1 | awk '{print $5}' | cut -d'%' -f1)
if [ -n "$BOOT_USAGE" ] && [ $BOOT_USAGE -gt 90 ]; then
    echo "清理旧内核文件..."
    # 保留当前和最新的两个内核
    sudo apt autoremove --purge
fi

# 3. 修复失败的服务
echo "修复失败的服务..."
FAILED_SERVICES=$(systemctl --failed --no-legend | awk '{print $1}')
for service in $FAILED_SERVICES; do
    echo "尝试重启服务: $service"
    sudo systemctl reset-failed "$service"
    sudo systemctl restart "$service" 2>/dev/null || {
        echo "禁用问题服务: $service"
        sudo systemctl disable "$service"
    }
done

# 4. 检查fstab
echo "检查fstab配置..."
if ! mount -a -v >/dev/null 2>&1; then
    echo "fstab配置有问题,请手动检查 /etc/fstab"
fi

# 5. 更新initramfs
echo "更新initramfs..."
sudo update-initramfs -u

echo "自动修复完成!"
echo "如果问题仍然存在,请查看系统日志: journalctl -b"

📊 启动性能优化

1. 分析启动性能

# 查看启动时间
systemd-analyze

# 查看服务启动耗时
systemd-analyze blame

# 查看关键路径
systemd-analyze critical-chain

# 生成启动图表
systemd-analyze plot > bootchart.svg

2. 优化启动速度

# 禁用不必要的服务
sudo systemctl disable bluetooth
sudo systemctl disable cups
sudo systemctl disable ModemManager

# 设置并行启动
sudo systemctl edit some.service
[Service]
Type=forking

🚨 应急处理

系统完全无法启动时

  1. 使用Live CD/USB启动
  2. 挂载系统分区

    sudo mount /dev/sda1 /mnt
    sudo mount --bind /dev /mnt/dev
    sudo mount --bind /proc /mnt/proc
    sudo mount --bind /sys /mnt/sys
    
  3. 进入chroot环境修复

    sudo chroot /mnt
    # 在这里执行修复操作
    
  4. 数据救援

    # 如果无法修复,至少救援重要数据
    sudo mount /dev/sda1 /mnt
    cp -r /mnt/home/user/important_data /backup/
    

📚 相关工具

  • grub-rescue - GRUB救援工具
  • systemd-analyze - 启动分析工具
  • journalctl - 系统日志查看
  • fsck - 文件系统检查
  • chroot - 根目录切换
  • memtest86+ - 内存测试工具

通过系统的诊断和正确的修复步骤,大多数启动问题都可以得到解决,确保系统能够正常启动和运行。

系统启动故障排查是运维的高级技能,掌握这些方法可以有效应对各种启动问题。


powered by Gitbook© 2025 编外计划 | 最后修改: 2025-07-28 12:47:16

results matching ""

    No results matching ""