fstrim命令用于通知固态硬盘(SSD)哪些数据块已经不再使用,可以被安全擦除。这个过程称为TRIM操作,是SSD维护的重要部分。
TRIM的工作原理:
为什么需要TRIM:
fstrim [选项] 挂载点
fstrim [选项] -a
| 选项 | 说明 |
|---|---|
-a, --all |
对所有支持TRIM的挂载文件系统执行操作 |
-o, --offset 偏移量 |
从指定偏移量开始(字节) |
-l, --length 长度 |
只处理指定长度的范围(字节) |
-m, --minimum 最小值 |
最小可释放块大小(默认1个块) |
-v, --verbose |
详细模式,显示详细信息 |
-n, --dry-run |
模拟运行,不实际执行TRIM操作 |
-V, --version |
显示版本信息 |
-h, --help |
显示帮助信息 |
# 对根分区执行TRIM操作
sudo fstrim /
# 对/home分区执行TRIM操作
sudo fstrim /home
# 对/boot分区执行TRIM操作(如果/boot在SSD上)
sudo fstrim /boot
# 显示TRIM操作的详细信息
sudo fstrim -v /
sudo fstrim -v /home
# 输出示例:
# /: 23.4 GiB (25165824000 bytes) trimmed
# /home: 15.2 GiB (16320839680 bytes) trimmed
# 对所有支持TRIM的挂载文件系统执行操作
sudo fstrim -a
# 详细模式显示所有挂载点的TRIM结果
sudo fstrim -av
# 输出示例:
# /boot/efi: 580.5 MiB (608829440 bytes) trimmed
# /boot: 95.7 MiB (100335616 bytes) trimmed
# /: 23.4 GiB (25165824000 bytes) trimmed
# /home: 15.2 GiB (16320839680 bytes) trimmed
# 模拟TRIM操作,不实际执行
sudo fstrim -n /
sudo fstrim -nv /
# 模拟所有挂载点
sudo fstrim -anv
# 输出示例(模拟运行):
# /: 23.4 GiB (25165824000 bytes) would be trimmed
# /home: 15.2 GiB (16320839680 bytes) would be trimmed
# 指定偏移量和长度(高级用法)
sudo fstrim -o 0 -l 1073741824 / # 处理前1GB范围
# 设置最小可释放块大小(默认为1个块)
sudo fstrim -m 4096 / # 最小4KB块
# 组合使用
sudo fstrim -v -m 8192 /home
# 检查SSD是否支持TRIM
sudo hdparm -I /dev/sda | grep -i trim
# 或者使用lsblk检查
lsblk --discard
# 检查特定分区的TRIM支持
sudo fstrim -n / # 如果支持,会显示可以TRIM的大小
# 检查文件系统是否支持TRIM
sudo tune2fs -l /dev/sda1 | grep discard
# 查看当前的TRIM服务状态
sudo systemctl status fstrim.timer
sudo systemctl status fstrim.service
# 启用每周自动TRIM
sudo systemctl enable fstrim.timer
sudo systemctl start fstrim.timer
# 立即运行一次TRIM服务
sudo systemctl start fstrim.service
# 查看TRIM计时器配置
sudo systemctl list-timers | grep fstrim
sudo cat /usr/lib/systemd/system/fstrim.timer
# 场景1:大量文件删除后手动TRIM
sudo rm -rf /tmp/large_directory/*
sudo fstrim /
# 场景2:虚拟机磁盘优化
# 在虚拟机内部执行TRIM
sudo fstrim -av
# 场景3:数据库服务器维护
# 在数据库维护期间执行TRIM
sudo systemctl stop mysql
sudo fstrim /
sudo systemctl start mysql
# 场景4:定期维护脚本
#!/bin/bash
# weekly_trim.sh
LOGFILE="/var/log/fstrim.log"
echo "=== TRIM操作开始: $(date) ===" >> "$LOGFILE"
fstrim -av >> "$LOGFILE" 2>&1
echo "=== TRIM操作结束: $(date) ===" >> "$LOGFILE"
| 文件系统 | TRIM支持 | 说明 |
|---|---|---|
| ext4 | 完全支持 | Linux最常用的文件系统,支持discard挂载选项和fstrim |
| Btrfs | 完全支持 | 支持异步TRIM,性能较好 |
| XFS | 完全支持 | 从Linux 3.8开始支持,需要内核3.8+ |
| F2FS | 完全支持 | 专为闪存设计的文件系统,TRIM支持最好 |
| ext3 | 有限支持 | 需要内核2.6.33+,不建议在SSD上使用 |
| ext2 | 不支持 | 不建议在SSD上使用 |
| NTFS | 通过ntfs-3g支持 | 需要ntfs-3g 2015.3.14+版本 |
| FAT32/exFAT | 有限支持 | 需要内核和驱动支持 |
#!/bin/bash
# configure_trim.sh - 自动配置TRIM优化
echo "=== SSD TRIM 配置工具 ==="
# 1. 检查系统是否使用SSD
echo "1. 检查存储设备..."
if lsblk -d -o name,rota | grep -q "0$"; then
echo " ✓ 检测到SSD设备"
else
echo " ✗ 未检测到SSD,退出"
exit 0
fi
# 2. 检查当前TRIM服务状态
echo "2. 检查TRIM服务状态..."
if systemctl is-enabled fstrim.timer >/dev/null 2>&1; then
echo " ✓ TRIM服务已启用"
else
echo " ✗ TRIM服务未启用"
read -p " 是否启用每周自动TRIM? (y/n): " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
sudo systemctl enable fstrim.timer
sudo systemctl start fstrim.timer
echo " ✓ TRIM服务已启用"
fi
fi
# 3. 检查fstab中的discard选项
echo "3. 检查fstab配置..."
if grep -q "discard" /etc/fstab; then
echo " ⚠ fstab中包含discard选项(实时TRIM)"
echo " 注意:实时TRIM可能影响性能,建议使用定期fstrim"
else
echo " ✓ fstab中未使用discard选项(推荐)"
fi
# 4. 立即执行一次TRIM
echo "4. 执行TRIM操作..."
read -p " 是否立即执行TRIM? (y/n): " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
echo " 正在执行TRIM,请稍候..."
sudo fstrim -av
echo " ✓ TRIM操作完成"
fi
echo "=== 配置完成 ==="
#!/bin/bash
# ssd_health_monitor.sh - SSD健康监控
LOG_FILE="/var/log/ssd_health.log"
SMARTCTL=$(which smartctl 2>/dev/null)
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}
check_ssd_health() {
log "=== SSD健康检查开始 ==="
# 查找所有SSD设备
SSDS=$(lsblk -d -o name,rota | awk '$2==0 {print $1}')
if [ -z "$SSDS" ]; then
log "未找到SSD设备"
return 1
fi
for SSD in $SSDS; do
DEVICE="/dev/$SSD"
log "检查设备: $DEVICE"
# 检查TRIM支持
if sudo hdparm -I "$DEVICE" 2>/dev/null | grep -q "TRIM supported"; then
log " ✓ 支持TRIM"
else
log " ✗ 不支持TRIM"
fi
# 使用smartctl检查健康状态(如果可用)
if [ -n "$SMARTCTL" ]; then
if sudo "$SMARTCTL" -H "$DEVICE" 2>/dev/null | grep -q "PASSED"; then
log " ✓ SMART健康检测通过"
else
ERROR=$(sudo "$SMARTCTL" -H "$DEVICE" 2>/dev/null | grep -i "failed\|error")
log " ⚠ SMART检测问题: $ERROR"
fi
# 检查剩余寿命
WEAR_LEVEL=$(sudo "$SMARTCTL" -A "$DEVICE" 2>/dev/null | grep -i "wear leveling\|percent_lifetime_remaining" | head -1)
if [ -n "$WEAR_LEVEL" ]; then
log " 📊 $WEAR_LEVEL"
fi
fi
# 检查已使用空间
USED_SPACE=$(df -h | grep "$DEVICE" | awk '{print $5}' | head -1)
log " 💾 已使用空间: $USED_SPACE"
# 检查最后一次TRIM时间
LAST_TRIM=$(sudo tune2fs -l "$DEVICE"1 2>/dev/null | grep "Last trimmed" | head -1)
if [ -n "$LAST_TRIM" ]; then
log " ⏰ $LAST_TRIM"
fi
done
# 检查TRIM服务状态
if systemctl is-active fstrim.timer >/dev/null 2>&1; then
log "✓ TRIM服务运行中"
else
log "⚠ TRIM服务未运行"
fi
log "=== SSD健康检查结束 ==="
}
# 执行检查
check_ssd_health
#!/bin/bash
# trim_perf_test.sh - TRIM性能测试
TEST_DIR="/tmp/trim_test"
TEST_FILE="$TEST_DIR/large_file.bin"
SIZE="1G" # 测试文件大小
echo "=== TRIM性能测试 ==="
# 1. 准备工作
echo "1. 创建测试目录..."
sudo mkdir -p "$TEST_DIR"
sudo chmod 777 "$TEST_DIR"
# 2. 测试写入性能(TRIM前)
echo "2. 测试TRIM前写入性能..."
sync
echo 3 | sudo tee /proc/sys/vm/drop_caches > /dev/null
echo " 写入测试文件..."
START_TIME=$(date +%s.%N)
dd if=/dev/zero of="$TEST_FILE" bs=1M count=1024 status=progress 2>&1 | tail -1
END_TIME=$(date +%s.%N)
WRITE_TIME=$(echo "$END_TIME - $START_TIME" | bc)
WRITE_SPEED=$(echo "1024 / $WRITE_TIME" | bc)
echo " 写入速度: $WRITE_SPEED MB/s"
# 3. 删除文件并执行TRIM
echo "3. 删除文件并执行TRIM..."
sudo rm -f "$TEST_FILE"
sync
echo " 执行TRIM操作..."
TRIM_START=$(date +%s.%N)
sudo fstrim /
TRIM_END=$(date +%s.%N)
TRIM_TIME=$(echo "$TRIM_END - $TRIM_START" | bc)
echo " TRIM耗时: $TRIM_TIME 秒"
# 4. 测试写入性能(TRIM后)
echo "4. 测试TRIM后写入性能..."
sync
echo 3 | sudo tee /proc/sys/vm/drop_caches > /dev/null
echo " 再次写入测试文件..."
START_TIME=$(date +%s.%N)
dd if=/dev/zero of="$TEST_FILE" bs=1M count=1024 status=progress 2>&1 | tail -1
END_TIME=$(date +%s.%N)
WRITE_TIME2=$(echo "$END_TIME - $START_TIME" | bc)
WRITE_SPEED2=$(echo "1024 / $WRITE_TIME2" | bc)
echo " 写入速度: $WRITE_SPEED2 MB/s"
# 5. 清理和结果
sudo rm -rf "$TEST_DIR"
echo "=== 测试结果 ==="
echo "TRIM前写入速度: $WRITE_SPEED MB/s"
echo "TRIM后写入速度: $WRITE_SPEED2 MB/s"
IMPROVEMENT=$(echo "scale=2; ($WRITE_SPEED2 - $WRITE_SPEED) * 100 / $WRITE_SPEED" | bc)
echo "性能变化: $IMPROVEMENT%"
if (( $(echo "$IMPROVEMENT > 0" | bc -l) )); then
echo "✓ TRIM带来性能提升"
else
echo "⚠ TRIM未显示明显性能提升"
fi
#!/bin/bash
# lvm_raid_trim.sh - LVM和RAID上的TRIM配置
echo "=== LVM/RAID TRIM配置 ==="
# 1. 检查LVM配置
echo "1. 检查LVM配置..."
if command -v lvs >/dev/null 2>&1; then
echo " LVM卷列表:"
sudo lvs -o lv_name,vg_name,lv_size,lv_attr --units g
# 检查LVM是否支持TRIM
if sudo lvs -o lv_attr | grep -q "t"; then
echo " ✓ LVM支持TRIM"
else
echo " ⚠ LVM可能不支持TRIM"
echo " 在/etc/lvm/lvm.conf中设置:"
echo " issue_discards = 1"
echo " discard = 1"
fi
fi
# 2. 检查RAID配置
echo "2. 检查RAID配置..."
if [ -f /proc/mdstat ]; then
echo " RAID状态:"
cat /proc/mdstat
# 检查RAID是否支持TRIM
MD_DEVICES=$(grep "^md" /proc/mdstat | awk '{print $1}')
for MD in $MD_DEVICES; do
if sudo mdadm --detail /dev/"$MD" | grep -q "Consistency Policy.*resync"; then
echo " /dev/$MD: 支持TRIM (需要内核4.4+)"
else
echo " /dev/$MD: 可能不支持TRIM"
fi
done
fi
# 3. 执行TRIM
echo "3. 在LVM/RAID上执行TRIM..."
read -p " 是否执行TRIM? (y/n): " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
# 查找所有文件系统挂载点
MOUNTS=$(findmnt -lo target -n | grep -vE '^/(sys|proc|dev)')
for MOUNT in $MOUNTS; do
if [ -d "$MOUNT" ]; then
echo " 处理: $MOUNT"
sudo fstrim -v "$MOUNT" 2>/dev/null || echo " 跳过: 不支持TRIM"
fi
done
fi
echo "=== 操作完成 ==="
| 方法 | 配置方式 | 优点 | 缺点 | 推荐度 |
|---|---|---|---|---|
| systemd定时器 | systemctl enable fstrim.timer |
系统集成,默认每周执行,安全可靠 | 可能需要手动启用 | ★★★★★ |
| fstab discard选项 | /etc/fstab中添加discard |
实时TRIM,无需额外配置 | 可能影响性能,增加写入延迟 | ★★☆☆☆ |
| crontab定时任务 | crontab -e添加定时任务 |
灵活控制执行时间 | 需要手动配置 | ★★★☆☆ |
| 手动执行 | sudo fstrim -av |
完全控制,按需执行 | 容易忘记,不自动 | ★☆☆☆☆ |
| anacron任务 | /etc/anacrontab |
适合不总是开机的系统 | 配置复杂 | ★★★☆☆ |
discard挂载选项:
/etc/fstab中添加discardfstrim命令:
推荐做法:
# 不推荐:使用discard挂载选项(实时TRIM)
# /etc/fstab 示例(不推荐):
# UUID=xxx / ext4 defaults,discard 0 1
# 推荐:使用fstrim定期执行
# 启用每周自动TRIM
sudo systemctl enable fstrim.timer
sudo systemctl start fstrim.timer
# 或者手动执行
sudo fstrim -av
有多种方法可以检查SSD是否支持TRIM:
# 方法1: 使用hdparm检查
sudo hdparm -I /dev/sda | grep -i "TRIM supported"
# 方法2: 使用lsblk检查
lsblk --discard
# 方法3: 查看/sys文件系统
cat /sys/block/sda/queue/discard_max_bytes
# 如果输出大于0,则支持TRIM
if [ $(cat /sys/block/sda/queue/discard_max_bytes) -gt 0 ]; then
echo "支持TRIM"
else
echo "不支持TRIM"
fi
# 方法4: 使用fstrim测试
sudo fstrim -n /
# 如果显示可以TRIM的大小,则支持
# 方法5: 检查SSD型号和规格
sudo lshw -class disk
# 方法6: 检查内核消息
dmesg | grep -i trim
# 完整的检查脚本
#!/bin/bash
DEVICE="/dev/sda"
echo "检查 $DEVICE 的TRIM支持..."
echo "1. 通过hdparm:"
if sudo hdparm -I "$DEVICE" 2>/dev/null | grep -q "TRIM supported"; then
echo " ✓ 支持TRIM"
else
echo " ✗ 不支持TRIM"
fi
echo "2. 通过/sys文件系统:"
DISCARD_BYTES=$(cat /sys/block/${DEVICE#/dev/}/queue/discard_max_bytes 2>/dev/null)
if [ -n "$DISCARD_BYTES" ] && [ "$DISCARD_BYTES" -gt 0 ]; then
echo " ✓ 支持TRIM (discard_max_bytes: $DISCARD_BYTES)"
else
echo " ✗ 不支持TRIM"
fi
fstrim的执行频率取决于使用场景:
# 查看当前的自动TRIM频率
sudo systemctl cat fstrim.timer
# 通常配置(大多数Linux发行版默认):
# OnCalendar=weekly
# 不同场景的建议频率:
# 1. 桌面用户:每周一次
sudo systemctl edit fstrim.timer
# 添加:
# [Timer]
# OnCalendar=weekly
# RandomizedDelaySec=1h
# 2. 服务器:每天一次(在低峰时段)
# OnCalendar=daily
# AccuracySec=1h
# 3. 高写入负载:每天多次
# OnCalendar=*-*-* 02:00:00
# OnCalendar=*-*-* 14:00:00
# 4. 笔记本用户:每次唤醒时
# OnCalendar=daily
# Persistent=true
# 5. 手动控制(通过cron)
# crontab -e
# 每天凌晨3点执行
# 0 3 * * * /usr/sbin/fstrim -av
# 检查是否需要更频繁的TRIM:
# 查看文件系统碎片程度
sudo debugfs -R "stat <8>" /dev/sda1 2>/dev/null | grep -i free
# 监控TRIM效果
sudo fstrim -v / # 记录每次TRIM的大小
# 如果经常TRIM大量数据,考虑更频繁执行
# 如果TRIM数据很少,可以减少频率
一般建议:
在LUKS加密磁盘上使用TRIM需要额外配置:
# 1. 检查当前LUKS配置
sudo cryptsetup status /dev/mapper/luks-xxx
# 2. 启用LUKS的discard支持(在加密层传递TRIM命令)
# 方法A:创建LUKS时启用
sudo cryptsetup luksFormat --allow-discards /dev/sdaX
# 方法B:已存在的LUKS启用
# 编辑 /etc/crypttab,在选项中添加 discard
# 示例:
# luks-xxx /dev/sdaX none discard
# 3. 重新打开LUKS设备(如果已修改crypttab)
sudo cryptsetup luksOpen /dev/sdaX luks-xxx --allow-discards
# 4. 检查是否生效
sudo dmsetup table /dev/mapper/luks-xxx | grep -o discard
# 5. 在LUKS设备上执行fstrim
sudo fstrim /mnt/encrypted
# 完整的配置脚本
#!/bin/bash
# configure_luks_trim.sh
LUKS_DEVICE="/dev/sda2"
MAPPER_NAME="cryptroot"
MOUNT_POINT="/"
echo "配置LUKS加密磁盘的TRIM支持..."
# 1. 备份crypttab
sudo cp /etc/crypttab /etc/crypttab.backup
# 2. 修改crypttab
if grep -q "^$MAPPER_NAME" /etc/crypttab; then
# 如果已存在,添加discard选项
sudo sed -i "/^$MAPPER_NAME/s/\([^ ]*\) *\([^ ]*\) *\([^ ]*\) *\(.*\)/\1 \2 \3 discard,\4/" /etc/crypttab
else
echo "未找到 $MAPPER_NAME 在crypttab中"
fi
# 3. 更新initramfs(如果根文件系统加密)
if mount | grep -q "/dev/mapper/$MAPPER_NAME on / "; then
echo "更新initramfs..."
sudo update-initramfs -u -k all
fi
# 4. 重启或重新打开设备
echo "需要重启系统使配置生效"
echo "或者手动重新打开设备:"
echo "sudo cryptsetup luksClose $MAPPER_NAME"
echo "sudo cryptsetup luksOpen $LUKS_DEVICE $MAPPER_NAME --allow-discards"
echo "sudo mount /dev/mapper/$MAPPER_NAME $MOUNT_POINT"
# 5. 测试TRIM
echo "测试TRIM支持:"
sudo fstrim -n $MOUNT_POINT
注意事项:
systemctl enable fstrim.timer启用每周自动TRIMdiscard选项,可能影响性能fstrim -v查看每次TRIM的大小smartctl检查SSD健康状态