Linux Swap 文件创建脚本 2025 - 自动配置虚拟内存完整教程

Linux Swap 文件创建脚本使用文档

前言

对于我们玩 1c1g 小鸡(VPS)的站长来说,小鸡也有小鸡的价值,小鸡也要让它能跑 MySQL,但 1c/1g 小鸡部署了 MySQL 之后马上卡住了人生,SSH 都动不了,怎么办?别欺负小鸡!!!

RackNerd Image RackNerd Image

只要你按照以下方法创建了 Swap (虚拟内存)你的小鸡一样可以跑 MySQL。

概述

这个脚本用于在 Linux 系统上创建和配置 Swap 交换文件。Swap 是硬盘上的一块空间,当物理内存不足时,系统会将不常用的内存数据移到 Swap 中,从而避免系统因内存不足而崩溃。1c1g的小机器(VPS)强烈建议配置 Swap

脚本功能

  • 自动检测系统兼容性
  • 创建指定大小的 Swap 文件
  • 自动配置系统启动时挂载
  • 支持自定义 Swap 大小和路径
  • 提供详细的操作日志
  • 包含错误处理和回滚机制

完整脚本

#!/bin/bash

# Swap 文件创建和配置脚本
# 作者: Afffun.com
# 版本: 1.0
# 更新日期: 2025-05-26

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 默认配置
DEFAULT_SWAP_SIZE="4G"
DEFAULT_SWAP_PATH="/swapfile"
DEFAULT_SWAPPINESS=60

# 日志函数
log_info() {
    echo -e "${BLUE}[INFO]${NC} $1"
}

log_success() {
    echo -e "${GREEN}[SUCCESS]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

log_warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1"
}

# 检查是否以 root 权限运行
check_root() {
    if [[ $EUID -ne 0 ]]; then
        log_error "此脚本必须以 root 权限运行"
        log_info "请使用: sudo $0"
        exit 1
    fi
}

# 检查系统兼容性
check_system() {
    log_info "检查系统兼容性..."
    
    # 检查操作系统
    if [[ ! -f /etc/os-release ]]; then
        log_error "无法确定操作系统类型"
        exit 1
    fi
    
    # 检查必要的命令
    local required_commands=("fallocate" "mkswap" "swapon" "free")
    for cmd in "${required_commands[@]}"; do
        if ! command -v "$cmd" &> /dev/null; then
            log_error "缺少必要的命令: $cmd"
            exit 1
        fi
    done
    
    log_success "系统兼容性检查通过"
}

# 显示当前内存和 Swap 使用情况
show_memory_info() {
    log_info "当前系统内存信息:"
    free -h
    echo ""
}

# 检查现有的 Swap
check_existing_swap() {
    log_info "检查现有的 Swap 配置..."
    
    local swap_count=$(swapon --show | grep -v NAME | wc -l)
    if [[ $swap_count -gt 0 ]]; then
        log_warning "系统已存在 $swap_count 个 Swap 分区/文件:"
        swapon --show
        echo ""
        read -p "是否继续创建新的 Swap 文件? (y/N): " -n 1 -r
        echo ""
        if [[ ! $REPLY =~ ^[Yy]$ ]]; then
            log_info "操作已取消"
            exit 0
        fi
    fi
}

# 获取用户输入
get_user_input() {
    # Swap 大小
    read -p "请输入 Swap 文件大小 (例如: 1G, 2G, 4G, 8G) [默认: $DEFAULT_SWAP_SIZE]: " swap_size
    SWAP_SIZE=${swap_size:-$DEFAULT_SWAP_SIZE}
    
    # 验证输入格式
    if ! [[ $SWAP_SIZE =~ ^[0-9]+[GM]$ ]]; then
        log_error "无效的大小格式。请使用如 '4G' 或 '1024M' 的格式"
        exit 1
    fi
    
    # Swap 文件路径
    read -p "请输入 Swap 文件路径 [默认: $DEFAULT_SWAP_PATH]: " swap_path
    SWAP_PATH=${swap_path:-$DEFAULT_SWAP_PATH}
    
    # Swappiness 值
    read -p "请输入 Swappiness 值 (0-100) [默认: $DEFAULT_SWAPPINESS]: " swappiness
    SWAPPINESS=${swappiness:-$DEFAULT_SWAPPINESS}
    
    # 验证 Swappiness 值
    if ! [[ $SWAPPINESS =~ ^[0-9]+$ ]] || [[ $SWAPPINESS -lt 0 ]] || [[ $SWAPPINESS -gt 100 ]]; then
        log_error "无效的 Swappiness 值。必须在 0-100 之间"
        exit 1
    fi
    
    # 显示配置确认
    echo ""
    log_info "即将创建的 Swap 配置:"
    echo "  - 大小: $SWAP_SIZE"
    echo "  - 路径: $SWAP_PATH"
    echo "  - Swappiness: $SWAPPINESS"
    echo ""
    read -p "确认以上配置? (y/N): " -n 1 -r
    echo ""
    if [[ ! $REPLY =~ ^[Yy]$ ]]; then
        log_info "操作已取消"
        exit 0
    fi
}

# 检查磁盘空间
check_disk_space() {
    log_info "检查磁盘空间..."
    
    # 获取 Swap 文件所在分区的可用空间
    local swap_dir=$(dirname "$SWAP_PATH")
    local available_space=$(df -BG "$swap_dir" | awk 'NR==2 {print $4}' | sed 's/G//')
    local required_space=$(echo "$SWAP_SIZE" | sed 's/G//')
    
    if [[ "$SWAP_SIZE" =~ M$ ]]; then
        required_space=$(echo "$SWAP_SIZE" | sed 's/M//')
        required_space=$((required_space / 1024 + 1))
    fi
    
    if [[ $available_space -lt $required_space ]]; then
        log_error "磁盘空间不足。需要 ${required_space}G,但只有 ${available_space}G 可用"
        exit 1
    fi
    
    log_success "磁盘空间检查通过"
}

# 创建 Swap 文件
create_swap_file() {
    log_info "创建 Swap 文件..."
    
    # 如果文件已存在,先删除
    if [[ -f "$SWAP_PATH" ]]; then
        log_warning "Swap 文件已存在,将删除旧文件"
        swapoff "$SWAP_PATH" 2>/dev/null
        rm -f "$SWAP_PATH"
    fi
    
    # 创建 Swap 文件
    if ! fallocate -l "$SWAP_SIZE" "$SWAP_PATH"; then
        log_warning "fallocate 失败,尝试使用 dd 命令..."
        
        # 计算块数
        local count
        if [[ "$SWAP_SIZE" =~ G$ ]]; then
            count=$(echo "$SWAP_SIZE" | sed 's/G//')
            count=$((count * 1024))
        else
            count=$(echo "$SWAP_SIZE" | sed 's/M//')
        fi
        
        if ! dd if=/dev/zero of="$SWAP_PATH" bs=1M count="$count" status=progress; then
            log_error "创建 Swap 文件失败"
            exit 1
        fi
    fi
    
    log_success "Swap 文件创建成功"
}

# 配置 Swap 文件
configure_swap() {
    log_info "配置 Swap 文件..."
    
    # 设置权限
    chmod 600 "$SWAP_PATH"
    log_success "权限设置完成"
    
    # 设置为 Swap 空间
    if ! mkswap "$SWAP_PATH"; then
        log_error "mkswap 失败"
        rm -f "$SWAP_PATH"
        exit 1
    fi
    log_success "Swap 空间设置完成"
    
    # 启用 Swap
    if ! swapon "$SWAP_PATH"; then
        log_error "启用 Swap 失败"
        rm -f "$SWAP_PATH"
        exit 1
    fi
    log_success "Swap 已启用"
}

# 配置系统启动时自动挂载
configure_fstab() {
    log_info "配置系统启动时自动挂载..."
    
    # 备份 fstab
    cp /etc/fstab /etc/fstab.bak.$(date +%Y%m%d_%H%M%S)
    log_success "fstab 备份完成"
    
    # 检查是否已存在该条目
    if grep -q "$SWAP_PATH" /etc/fstab; then
        log_warning "fstab 中已存在该 Swap 文件的条目"
    else
        # 添加到 fstab
        echo "$SWAP_PATH none swap sw 0 0" >> /etc/fstab
        log_success "已添加到 fstab"
    fi
}

# 配置 Swappiness
configure_swappiness() {
    log_info "配置 Swappiness..."
    
    # 临时设置
    sysctl vm.swappiness="$SWAPPINESS"
    
    # 永久设置
    if grep -q "vm.swappiness" /etc/sysctl.conf; then
        sed -i "s/vm.swappiness.*/vm.swappiness=$SWAPPINESS/" /etc/sysctl.conf
    else
        echo "vm.swappiness=$SWAPPINESS" >> /etc/sysctl.conf
    fi
    
    log_success "Swappiness 设置为 $SWAPPINESS"
}

# 显示最终结果
show_result() {
    echo ""
    log_success "Swap 文件创建和配置完成!"
    echo ""
    log_info "新的内存和 Swap 信息:"
    free -h
    echo ""
    log_info "Swap 详细信息:"
    swapon --show
    echo ""
    log_info "当前 Swappiness 值:"
    cat /proc/sys/vm/swappiness
}

# 主函数
main() {
    clear
    echo "========================================"
    echo "    Linux Swap 文件创建和配置脚本"
    echo "========================================"
    echo ""
    
    # 执行步骤
    check_root
    check_system
    show_memory_info
    check_existing_swap
    get_user_input
    check_disk_space
    create_swap_file
    configure_swap
    configure_fstab
    configure_swappiness
    show_result
    
    log_success "所有操作完成!"
}

# 错误处理
trap 'log_error "脚本执行被中断"; exit 1' INT TERM

# 执行主函数
main "$@"

使用方法

1. 下载脚本

# 创建脚本文件
sudo nano /usr/local/bin/create_swap.sh

# 将上面的脚本内容复制粘贴到文件中
# 保存并退出 (Ctrl+X, Y, Enter)

2. 赋予执行权限

sudo chmod +x /usr/local/bin/create_swap.sh

3. 运行脚本

sudo /usr/local/bin/create_swap.sh

4. 按照提示操作

脚本会引导你完成以下步骤:

  • 检查系统兼容性
  • 显示当前内存使用情况
  • 询问 Swap 文件大小(如 4G)
  • 询问 Swap 文件路径(默认 /swapfile)
  • 询问 Swappiness 值(默认 60)
  • 确认配置并创建 Swap

参数说明

Swap 大小

  • 建议设置为物理内存的 1-2 倍
  • 对于现代系统(8GB 以上内存),通常 4-8GB 足够
  • 格式:数字+单位(G 或 M),如 4G2048M

Swappiness 值

  • 范围:0-100
  • 默认值:60
  • 较低值(10-30):减少 Swap 使用,适合 SSD
  • 较高值(60-80):更积极使用 Swap,适合内存紧张的系统

建议配置

物理内存 建议 Swap 大小 使用场景
≤ 2GB 2倍内存 基础服务器
2-8GB 等于内存 一般用途
8-64GB 至少 4GB 生产服务器
> 64GB 至少 4GB 高性能服务器

常用命令

查看 Swap 状态

# 查看内存和 Swap 使用情况
free -h

# 查看 Swap 详细信息
swapon --show

# 查看所有 Swap 分区
cat /proc/swaps

临时禁用/启用 Swap

# 禁用特定 Swap 文件
sudo swapoff /swapfile

# 启用特定 Swap 文件
sudo swapon /swapfile

# 禁用所有 Swap
sudo swapoff -a

# 启用所有 Swap
sudo swapon -a

调整 Swappiness

# 查看当前值
cat /proc/sys/vm/swappiness

# 临时修改
sudo sysctl vm.swappiness=10

# 永久修改
echo "vm.swappiness=10" | sudo tee -a /etc/sysctl.conf

删除 Swap 文件

# 1. 禁用 Swap
sudo swapoff /swapfile

# 2. 从 fstab 中删除条目
sudo sed -i '/swapfile/d' /etc/fstab

# 3. 删除文件
sudo rm /swapfile

故障排除

问题 1:fallocate 命令失败

某些文件系统(如 ZFS)不支持 fallocate,脚本会自动切换到 dd 命令。

问题 2:权限错误

确保使用 sudo 运行脚本:

sudo ./create_swap.sh

问题 3:磁盘空间不足

检查可用空间:

df -h

问题 4:Swap 未在重启后启用

检查 /etc/fstab 配置:

grep swap /etc/fstab

性能优化建议

  1. SSD 用户:设置较低的 swappiness(10-30)以减少写入
  2. 数据库服务器:可能需要禁用 Swap 以获得可预测的性能
  3. 桌面系统:默认值 60 通常是合适的
  4. 内存密集型应用:增加 Swap 大小并调整 swappiness

安全建议

  1. Swap 文件权限必须是 600(仅 root 可读写)
  2. 定期检查 Swap 使用情况,过度使用可能表明需要增加物理内存
  3. 对于敏感数据,考虑加密 Swap 分区

版本历史

  • v1.0 (2025-05-26)
    • 添加完整的错误处理
    • 支持自定义配置
    • 添加系统兼容性检查
    • 改进用户交互界面
    • 基本的 Swap 创建功能