Linux + SSD 上的交换分区后台丢弃

Linux + SSD 上的交换分区后台丢弃

问题

我想启用背景在 Linux 上对 SSD 磁盘中的交换分区进行 TRIM 操作。根据几篇文章,例如这个,内核检测到此配置并自动执行丢弃操作,但在我的测试中似乎它不起作用,虽然使用“丢弃”挂载选项来强制此行为。

设想

  • Debian Wheezy 运行 Linux 3.2.0
  • SSD 磁盘:1 x 120GB OCZ Vertex 3 MI
  • 2GB 交换“普通”分区,不含其他层(LVM、RAID 等)

背景

以下是我检查后台 TRIM 是否在交换分区上运行的步骤:

  1. TRIM 支持:检查 SSD 磁盘是否支持 TRIM 命令并且内核将该设备标记为非旋转:

    # hdparm -I /dev/sda | grep TRIM
     * Data Set Management TRIM supported (limit 1 block)
     * Deterministic read data after TRIM
    
    # cat /sys/block/sda/queue/rotational
    0
    
  2. 掉期填补:挂载分区,清理所有 VM 缓存,并配置 Linux 以积极交换,将 vm.swappiness 设置为 100。然后,运行分配所有可用内存的脚本并强制内核开始交换:

    # swapon [--discard] /dev/sda2
    # echo 3 > /proc/sys/vm/drop_caches
    # echo 100 > /proc/sys/vm/swappiness
    # ./fill-up-memory.up
    

    该脚本在具有 32GB 物理内存 + 2GB 交换分区的服务器上运行,并在内存中创建一个 ~33.8GB 的​​对象,这足以填满所有内存并开始交换。这是一个实现此行为的脚本示例:

    #!/usr/bin/python
    
    mem = 33.8
    testing = 'A' * int(1024 * 1024 * 1024 * mem)
    raw_input()
    
  3. 检查交换内容:“swapon -s”显示交换内存的使用率为 100%。使用“hdparm --read-sector”,我检查了交换分区扇区的原始内容,所有字节都设置为“4141”,即“A”字符对应的十六进制表示法,一切正常。这是一个逐扇区读取交换分区内容的示例脚本:

    #!/bin/bash
    
    for sector in `seq 194560 4100095` ; do
        hdparm --read-sector $sector /dev/sda
    done
    

注意:您可以使用 parted、cfdisk 等获取交换分区的起始/结束扇区。

当我停止脚本时,它会释放所有内存,包括交换分配,“swapon -s”返回系统中没有交换使用情况。此时,预计 Linux 会在后台开始丢弃交换分区的内容,但实际上并没有起作用,即使过了几个小时,扇区的内容仍然是“4141”。

我进行了几次测试,似乎 Linux 仅在使用swapon()系统调用启用分区时执行完全丢弃,而从不在后台执行,尽管在 /etc/fstab 上启用了“丢弃”挂载选项。

进一步研究:blkdev_issue_discard() 是负责向底层 SSD 设备发送 TRIM 命令的内核函数,有两个对该函数的唯一引用mm/swapfile.c

  • discard_swap()它在 swapon() 过程中被调用,如果启用了“discard”挂载选项,它会丢弃所有内容,这会按预期工作。
  • discard_swap_cluster()它应该丢弃集群交换的内容,但似乎它从未执行 TRIM 命令。

问题:Linux 在交换 + SSD 设备上的预期行为是什么?它应该丢弃所有空闲扇区/页面,还是仅在启动过程中启用分区时发出初始完全丢弃?谢谢。

答案1

看起来丢弃_swap_cluster仅从调用扫描_交换_映射而这又被称为获取交换页或者获取交换页的类型。因此,如果我是正确的,则仅当要分配新的交换页面时才会发生丢弃,而不是在释放页面时发生。

答案2

您的系统可能已将其--discard=once作为默认设置。您是否尝试过使用特定丢弃选项进行安装?

# nano /etc/fstab
________________________________________________________________
...
/dev/sda2    none    swap    ..., --discard=pages,...    ...
...

并像这样强制:

# swapon --discard=pages /dev/sda2

您还可以尝试创建一项fstrim服务,或者如果它已经可用,则对其进行配置。

答案3

当我停止脚本时,它会释放所有内存,包括交换分配,“swapon -s”返回系统中没有交换使用情况。此时,预计 Linux 会在后台开始丢弃交换分区的内容,但实际上并没有起作用,即使过了几个小时,扇区的内容仍然是“4141”。

当返回“未使用交换”时,交换的内容实际上被“丢弃” swapon -s。系统不会覆盖块的内容(填充“4141”),因为它是 SSD,过多的写入会缩短 SSD 的寿命。(至少,这是我从文档中得到的)

相关内容