Linux 服务器运维指令流程大全:从零开始掌握磁盘、内存与备份
这是一份专门为新手小白准备的 Linux 运维速查手册。
只要跟着敲一遍命令,你就能看懂服务器的磁盘、内存、目录占用,还会清理日志、挂载磁盘、扩容,甚至自己写一个带日期的数据库自动备份脚本。

1. 服务器基础信息一览
登录服务器后,先摸清家底。
bash
# 系统内核版本
uname -a
# 发行版信息
cat /etc/os-release
# 或
lsb_release -a
# CPU 信息
lscpu
# 只看型号和核心数
cat /proc/cpuinfo | grep "model name" | head -1
nproc # 查看逻辑 CPU 数量
# 内存总量
free -h
# 磁盘与挂载概览
lsblk
df -hT
这些命令不会改动任何配置,放心敲。
2. 查看磁盘空间与挂载情况
2.1 df -- 文件系统整体占用
df 最常用,能告诉你每个挂载点的总大小、已用、可用、使用率。
bash
df -h
-
-h: 人类可读的格式(G、M、K) -
输出示例:
Filesystem Size Used Avail Use% Mounted on
/dev/vda1 40G 12G 26G 32% /
/dev/vdb1 100G 60G 40G 60% /data -
注意:
Use%达到 100% 时需要清理或扩容。
加 -T 还能看到文件系统类型(ext4、xfs 等):
bash
df -hT
查看 inode 使用(小文件过多可能耗尽 inode,导致磁盘有空间却写不进去):
bash
df -i
2.2 lsblk -- 磁盘与分区树
bash
lsblk
以树形结构列出所有块设备(磁盘、分区):
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
vda 252:0 0 40G 0 disk
└─vda1 252:1 0 40G 0 part /
vdb 252:16 0 100G 0 disk
└─vdb1 252:17 0 100G 0 part /data
- 如果某块磁盘没有
MOUNTPOINT,说明它虽然连上了,但还没挂载使用。
更详细的分区 UUID 和文件系统:
bash
lsblk -f
2.3 mount 与 /etc/fstab -- 挂载状态
查看当前所有挂载点及挂载参数:
bash
mount | column -t
查看系统启动时自动挂载的配置(修改前一定要备份):
bash
cat /etc/fstab
每一行格式:
设备/UUID 挂载点 文件系统类型 挂载选项 0 0
3. 查看单个文件夹大小与目录占用排行
3.1 du -- 目录空间占用
du(disk usage)用来统计文件/目录占用多少磁盘空间。
查看 当前目录下每个子目录的大小(最常用):
bash
du -sh *
-s: 只显示总计(summary)-h: 人类可读*: 当前目录下所有文件和目录
查看 指定文件夹的总大小:
bash
du -sh /var/log
输出:
1.2G /var/log
如果想看该目录下第一层子目录的各自大小:
bash
du -sh /var/log/*
3.2 找出磁盘空间都被谁吃了
从根目录开始,用 --max-depth 控制层级,并排序:
bash
du -h --max-depth=1 / 2>/dev/null | sort -hr | head -20
--max-depth=1: 只统计第一层子目录2>/dev/null: 忽略无权限的错误信息sort -hr: 按人类可读的数字倒序排列(h 支持 1K、200M 这样的单位排序)head -20: 只看前 20 大
这样一下子就能看出是 /var、/home 还是 /opt 占用巨大。
更现代的工具:ncdu
如果可以联网安装,ncdu 提供交互式界面,直接进入目录浏览,按大小排序:
bash
# 安装(Ubuntu/Debian)
sudo apt install ncdu
# CentOS/RHEL
sudo yum install ncdu # 可能需要 EPEL
# 使用
ncdu /
4. 物理磁盘占用的那些坑
有时候你会遇到诡异现象:df 显示磁盘快满了,但 du 统计出来的目录大小总和远小于已用空间。这通常是因为 删除了文件,但进程还在写,导致磁盘空间没有真正释放。
- 文件删除后,如果仍有进程持有文件句柄,空间不会回收。
- 用
lsof查找这些"幽灵"文件:
bash
lsof | grep deleted
或者更精确:
bash
lsof -nP | grep '(deleted)'
输出会显示进程名、PID 和文件路径。重启对应进程即可释放空间。
此外,du 默认统计的是 文件实际占用磁盘块大小(通常比文件大小稍大)。如果想看文件本身的尺寸(apparent size),使用:
bash
du -sh --apparent-size /var/log
日常排查空间不用太纠结这个,知道 du 按块统计即可。
5. 内存与 CPU 快速查看
内存
bash
free -h
输出:
total used free shared buff/cache available
Mem: 3.8G 1.2G 800M 100M 1.8G 2.3G
Swap: 2.0G 0B 2.0G
available才是应用程序真正还能用的内存,包含了可回收的 buffer/cache。- 如果
Swap使用了很大比例,说明内存不太够。
动态监控:
bash
top
# 或更美观的
htop # 需安装
按 q 退出。
CPU
在 top 中可以看到各个进程 CPU 占用,按 1 显示每个核心负载。
查看 CPU 基本信息:
bash
lscpu
查看系统负载(最近1、5、15分钟平均负载):
bash
uptime
一般来说负载不超过 CPU 核心数就算正常。
6. 磁盘挂载实战(含卸载、查看完整流程)
磁盘挂载和卸载是运维中出现频率最高的操作之一。下面以一个独立的新磁盘为例,走完"识别设备 → 分区格式化 → 临时挂载 → 永久挂载 → 验证 → 卸载 → 故障排查"的完整闭环。
6.1 识别新磁盘
加装硬盘后(或云平台挂载云盘后),让系统重新扫描(物理机可重启,云服务器一般自动识别):
bash
# 查看所有块设备
lsblk
# 查看内核识别到的磁盘信息
sudo fdisk -l
# 持续监控磁盘事件(拔插测试时常用)
dmesg | tail -20
如果磁盘已识别但未显示容量,可能需要重新扫描 SCSI 总线:
bash
# 扫描所有 SCSI 主机(云服务器适用)
for host in /sys/class/scsi_host/*; do echo "- - -" | sudo tee $host/scan; done
再次 lsblk 就能看到新盘(例如 /dev/vdc)。
6.2 分区
如果磁盘已有分区且不需要重新分区,可跳过此步。
bash
# 使用 fdisk 对 /dev/vdc 进行分区
sudo fdisk /dev/vdc
# 交互步骤:
# n → 新建分区
# p → 主分区(回车默认编号1)
# 回车 → 默认起始扇区
# 回车 → 默认结束扇区(使用全部空间)
# w → 保存并退出
验证分区:
bash
lsblk /dev/vdc
# 应出现 /dev/vdc1
6.3 格式化文件系统
bash
# 格式化为 ext4(最通用)
sudo mkfs.ext4 /dev/vdc1
# 或 xfs(CentOS 7+ 默认)
sudo mkfs.xfs /dev/vdc1
注意:格式化会清空磁盘上所有数据,请三思而行。
检查文件系统类型:
bash
lsblk -f /dev/vdc1
# 或
sudo blkid /dev/vdc1
6.4 临时挂载
bash
# 创建挂载点
sudo mkdir -p /mnt/mydata
# 临时挂载
sudo mount /dev/vdc1 /mnt/mydata
# 验证挂载结果
df -hT /mnt/mydata
6.5 永久挂载(写入 /etc/fstab)
先获取分区的 UUID(通用唯一标识,比设备名更稳定):
bash
sudo blkid /dev/vdc1
# 输出示例:
# /dev/vdc1: UUID="a1b2c3d4-..." TYPE="ext4"
备份 fstab,然后编辑:
bash
sudo cp /etc/fstab /etc/fstab.bak.$(date +%Y%m%d)
sudo vim /etc/fstab
在文件末尾添加一行:
UUID=a1b2c3d4-... /mnt/mydata ext4 defaults 0 2
字段含义:
UUID=...:设备标识(也可用/dev/vdc1,但 UUID 更可靠)/mnt/mydata:挂载点ext4:文件系统类型defaults:挂载选项(rw, suid, dev, exec, auto, nouser, async)- 第一个
0:dump 备份标记(0 表示不备份) - 第二个
2:fsck 检查顺序(0 不检查,1 根分区,2 其他分区)
测试 fstab 配置是否无误(不会真正重启):
bash
sudo mount -a
若无错误信息,则说明配置正确,重启后会自动挂载。
6.6 查看挂载详情
bash
# 查看当前所有挂载点及参数
mount | grep /mnt/mydata
# 查看某个挂载点的文件系统类型与空间
df -hT /mnt/mydata
# 用 findmnt 查看树形挂载关系(推荐)
findmnt /mnt/mydata
6.7 卸载磁盘
bash
# 卸载挂载点
sudo umount /mnt/mydata
# 如果提示"target is busy",说明有进程在使用该目录
# 查找占用进程
sudo lsof /mnt/mydata
# 或
sudo fuser -m /mnt/mydata
# 强制结束占用进程后卸载(谨慎)
sudo fuser -km /mnt/mydata
sudo umount /mnt/mydata
# 如果仍然无法卸载,尝试懒卸载(立即断开文件系统,使用结束后彻底卸载)
sudo umount -l /mnt/mydata
卸载后,如果不再需要自动挂载,记得从 /etc/fstab 中删除或注释掉对应行。
6.8 常见排查命令
bash
# 查看某个设备是否挂载
mount | grep /dev/vdc1
# 查看所有 ext4 类型的分区
df -t ext4 -h
# 查看挂载失败的日志
dmesg | tail -30
# 模拟 fstab 挂载并显示详细过程
sudo mount -av
7. 磁盘扩容流程(新手稳妥版)
⚠️ 任何扩容操作前,请先备份重要数据!
如果不确定,联系云服务商或专业运维。
7.1 云磁盘在线扩容(最简单)
阿里云、腾讯云、AWS 等支持在线扩容云盘。
大致流程:
-
在控制台对云盘进行扩容(例如从 40G 调到 100G)。
-
登录服务器,让系统识别新容量:
bash# 查看磁盘和分区容量是否已变大 lsblk -
扩展分区(如果用了分区表)和文件系统。
- 如果磁盘直接作为文件系统(没有分区,如 /dev/vdb),直接扩展文件系统:
bash# ext4 文件系统 sudo resize2fs /dev/vdb # xfs 文件系统 sudo xfs_growfs /data # 注意:xfs_growfs 后面跟挂载点- 如果磁盘有分区(如 /dev/vdb1),可能需要先扩展分区。推荐使用
growpart:
bash# 安装 growpart(通常已内置) sudo growpart /dev/vdb 1 # 扩展第一个分区 # 然后 resize 文件系统 sudo resize2fs /dev/vdb1 -
验证:
bashdf -h /data
7.2 LVM 逻辑卷扩容
LVM 的好处是可以在线扩容,无需重启。
基本命令速览:
bash
# 查看卷组和逻辑卷
sudo vgdisplay
sudo lvdisplay
# 1. 创建物理卷(新磁盘 /dev/vdc)
sudo pvcreate /dev/vdc
# 2. 加入卷组(假设卷组名叫 vg_data)
sudo vgextend vg_data /dev/vdc
# 3. 扩展逻辑卷(假设 LV 路径 /dev/vg_data/lv_data,增加 10G)
sudo lvextend -L +10G /dev/vg_data/lv_data
# 4. 扩展文件系统
# ext4:
sudo resize2fs /dev/vg_data/lv_data
# xfs:
sudo xfs_growfs /data # /data 是挂载点
每一步操作前后都可以用 df -h、lsblk、vgs、lvs 查看变化。
8. 日志删除与清理
8.1 查找大日志文件
bash
# 在 /var/log 下找大于 100M 的文件
find /var/log -type f -size +100M -exec ls -lh {} \;
8.2 安全清空日志内容
不要直接 rm 掉还在被写入的日志文件(可能导致进程无法写入,需重启服务)。
最安全的方法是清空内容,但保留 inode:
bash
# 方式1:重定向空内容
sudo > /var/log/syslog
# 方式2:truncate 截断
sudo truncate -s 0 /var/log/syslog
# 方式3:使用 tee(配合 /dev/null)
sudo tee /var/log/syslog < /dev/null
这三个效果相同,文件大小变为 0,服务依旧可以正常写入。
8.3 用 logrotate 自动轮转
很多系统日志都已配置了 logrotate,它会自动切割、压缩、删除旧日志。
配置文件:
- 主配置:
/etc/logrotate.conf - 子配置:
/etc/logrotate.d/目录下
例如查看 nginx 日志的轮转配置:
bash
cat /etc/logrotate.d/nginx
对于自定义的应用日志,可以自己添加配置,例如 /etc/logrotate.d/myapp:
/var/log/myapp/*.log {
daily
rotate 7
compress
missingok
notifempty
copytruncate
}
daily: 每天轮转rotate 7: 保留 7 份compress: 压缩旧日志copytruncate: 复制并清空,避免服务中断
测试配置是否生效:
bash
sudo logrotate -d /etc/logrotate.conf # 调试模式,不做实际操作
sudo logrotate -f /etc/logrotate.conf # 强制执行一次
8.4 清理 systemd 日志
如果 journald 日志占满 /var/log/journal,可以用以下方式清理:
bash
# 查看占用大小
journalctl --disk-usage
# 只保留最近 2 天日志
sudo journalctl --vacuum-time=2d
# 只保留 500M 大小
sudo journalctl --vacuum-size=500M
# 保留最近 1000 条
sudo journalctl --vacuum-lines=1000
9. 数据库自动备份脚本(通用模板版)
生产环境中最常用的两种场景:Windows 上用 mysqldump 的批处理,以及 Linux 上通用的 Shell 脚本。以下模板直接指定数据库参数,备份时会自动在指定目录下创建当天日期文件夹,所有备份文件按日期归档,简洁可靠。
9.1 Windows 批处理版(.bat)
适用环境:Windows Server,已安装 MySQL 客户端工具且 mysqldump 可在命令行直接执行。
backup_mysql.bat
bat
@echo off
chcp 65001 >nul
setlocal enabledelayedexpansion
REM ========== 配置区域(按实际修改) ==========
set DB_USER=root
set DB_PASS=your_password
set DB_HOST=localhost
set DB_PORT=3306
set BACKUP_ROOT=D:\backup\mysql
REM ========== 自动日期目录 ==========
set DATE_DIR=%date:~0,4%-%date:~5,2%-%date:~8,2%
set BACKUP_PATH=%BACKUP_ROOT%\%DATE_DIR%
if not exist "%BACKUP_PATH%" mkdir "%BACKUP_PATH%"
REM 需要备份的数据库,空格分隔
set DATABASES=db1 db2 db3
REM 日志文件
set LOGFILE=%BACKUP_PATH%\backup.log
echo [%date% %time%] 备份开始 >> "%LOGFILE%"
for %%d in (%DATABASES%) do (
set OUT_FILE=%BACKUP_PATH%\%%d_%DATE_DIR%.sql.gz
echo 正在备份 %%d ...
mysqldump -u%DB_USER% -p%DB_PASS% -h%DB_HOST% -P%DB_PORT% --single-transaction --routines --triggers %%d | gzip > "!OUT_FILE!"
if errorlevel 1 (
echo [%date% %time%] %%d 备份失败! >> "%LOGFILE%"
) else (
echo [%date% %time%] %%d 备份成功 → !OUT_FILE! >> "%LOGFILE%"
)
)
REM 清理7天前备份文件夹
forfiles /p "%BACKUP_ROOT%" /d -7 /c "cmd /c if @isdir==TRUE rd /s /q @file" 2>nul
echo [%date% %time%] 清理7天前旧备份完成 >> "%LOGFILE%"
echo [%date% %time%] 备份结束 >> "%LOGFILE%"
使用说明:
- 将上述内容保存为
backup_mysql.bat。 - 修改配置区域的数据库账号、密码、主机、端口和要备份的数据库列表。
- 在 Windows 任务计划程序中创建定时任务,触发器设置为每天凌晨执行该脚本。
- 需要安装
gzip工具(可用 GnuWin32 或 7-Zip 替换)。如果不想压缩,可将| gzip及.gz后缀去掉,输出纯 SQL 文件。
9.2 Linux Shell 版(通用,适用于所有发行版)
mysql_backup.sh
bash
#!/bin/bash
# ========== 配置区域 ==========
DB_USER="root"
DB_PASS="your_password"
DB_HOST="localhost"
DB_PORT="3306"
BACKUP_ROOT="/data/backup/mysql"
# 空格分隔的数据库列表
DATABASES="db1 db2 db3"
KEEP_DAYS=7
# ========== 自动日期目录 ==========
DATE_DIR=$(date +%Y-%m-%d)
BACKUP_PATH="$BACKUP_ROOT/$DATE_DIR"
mkdir -p "$BACKUP_PATH"
# 日志
LOG_FILE="$BACKUP_PATH/backup.log"
echo "[$(date '+%F %T')] 备份开始" >> "$LOG_FILE"
for db in $DATABASES; do
OUT_FILE="$BACKUP_PATH/${db}_${DATE_DIR}.sql.gz"
echo "正在备份 $db ..."
if mysqldump -u"$DB_USER" -p"$DB_PASS" -h"$DB_HOST" -P"$DB_PORT" \
--single-transaction --routines --triggers "$db" | gzip > "$OUT_FILE"; then
echo "[$(date '+%F %T')] $db 备份成功 → $OUT_FILE" >> "$LOG_FILE"
else
echo "[$(date '+%F %T')] $db 备份失败!" >> "$LOG_FILE"
fi
done
# 清理旧备份
find "$BACKUP_ROOT" -maxdepth 1 -type d -mtime +$KEEP_DAYS -exec rm -rf {} \;
echo "[$(date '+%F %T')] 清理 ${KEEP_DAYS} 天前目录完成" >> "$LOG_FILE"
echo "[$(date '+%F %T')] 备份结束" >> "$LOG_FILE"
使用说明:
-
将脚本保存为
/opt/scripts/mysql_backup.sh。 -
修改配置区域的数据库连接信息与数据库列表。
-
赋予执行权限:
chmod +x /opt/scripts/mysql_backup.sh -
加入 crontab 定时执行:
bashcrontab -e # 添加一行,每天凌晨2点执行 0 2 * * * /opt/scripts/mysql_backup.sh
两个模板的特点:
- 日期文件夹全自动,无需手动干预。
- 备份文件命名包含数据库名和日期,可读性好。
- 自动清理旧备份,防止磁盘写满。
- 参数明确定义在最前面,修改成本极低,任何项目都能直接复制使用。
如果需要备份所有数据库(排除系统库),只需将 DATABASES 变量的赋值逻辑改为动态获取,但通用模板为了简洁可靠,建议显式列出需要备份的库名。
10. 总结与建议
- 日常巡检 :建议每天快速执行
df -h、free -h、uptime,看看服务器是否健康。 - 空间排查 :用
du --max-depth配合sort定位大目录,用lsof查 deleted 文件。 - 日志处理 :优先使用
logrotate实现自动清理,避免手动rm。 - 扩容操作 :先在测试环境演练,生产操作前备份数据和
/etc/fstab。 - 数据库备份 :一定要定期验证备份文件能否正常恢复(解压后用
mysql < xxx.sql做一次模拟恢复)。
掌握这些命令和脚本,你已经具备了服务器日常运维的"救命"能力。遇到问题别慌,先看占用、查日志、确认备份,再动手操作。
参考资料与延伸阅读
man df、man du、man lsof、man logrotate- Linux 磁盘管理官方文档
- MySQL 官方备份文档
希望这篇指南能帮助你轻松驾驭 Linux 服务器的日常运维。
如果觉得有用,欢迎收藏和分享!