Solid state drive (简体中文) - ArchWiki

Jump to content

相关文章

- Solid state drive/NVMe
- Solid state drive/Memory cell clearing
- Benchmarking/Data storage devices
- Improving performance (简体中文) #存储设备
- Flashcache

翻译状态：本文是 Solid_State_Drives 的翻译。上次翻译日期：2022-08-13。如果英文版本有所更改，则您可以帮助同步翻译。

本文介绍如何管理固态硬盘等基于闪存的存储设备。如果出于特定目的要对SSD进行分区，请考虑针对闪存优化的文件系统。对于一般用途，您只需选择喜好的文件系统。

## 使用

### TRIM

绝大多数SSD支持 ATA_TRIM 命令 以保持性能并降低损耗。本文展示了SSD装满数据前后的速度变化。

自 Linux 内核版本 3.8 开始，对 TRIM 的支持不断被添加到不同的文件系统中。见下表：

文件系统 | Continuous TRIM (`discard` 选项) | Periodic TRIM (fstrim) | 参考与备注
--- | --- | --- | ---
Btrfs | 是 | 是 |
exFAT | 是 | 是 | 从5.13版内核开始支持fstrim， [1]
ext3 | 是 | 是 |
ext4 | 是 | 是 | "discard, nodiscard(*)" in [2]
F2FS | 是 | 是 |
JFS | 是 | 是 | [3]
NILFS2 | 是 | 是 |
NTFS-3G | 否 | 是 | 从2015.3.14版本开始， [4]
VFAT | 是 | 是 | 从4.19版内核开始支持fstrim， [5]
XFS | 是 | 是 | [6]

警告： 在启用TRIM功能前，请确保SSD支持TRIM。否则可能导致数据丢失！

要检查TRIM支持，执行：

    $ lsblk --discard

若DISC-GRAN (discard granularity)和DISC-MAX (discard max bytes)列上的数值不为零，则表示对应设备支持TRIM。

或者，安装hdparm包并执行：

    # hdparm -I /dev/sda | grep TRIM

            *    Data Set Management TRIM supported (limit 1 block)

注意： 不同的规范定义了不同的TRIM支持类型。因此，对于不同设备，以上输出可能不同。参见Wikipedia:Trim (computing)#ATA

#### Periodic TRIM

util-linux包提供了`fstrim.service`和`fstrim.timer`两个systemd unit文件。启用`fstrim.timer`计时器会在每周激活服务，在所有已挂载的支持discard操作的文件系统上执行fstrim(8)。

该计时器使用`/var/lib/systemd/timers/stamp-fstrim.timer`（将在服务第一次启动时创建）的时间戳来判断上次运行的时间。因此，不必担心服务被过于频繁地调用（类似anacron）。

该unit的状态与活动可通过journalctl查看。若要修改运行的周期或执行的指令，可编辑unit文件。

#### Continuous TRIM

注意： 如果你已定期运行`fstrim`，就不必再启用Continuous TRIM。只需在Periodic TRIM和Continuous TRIM中选择一个即可。

除定期执行TRIM指令外（若使用`fstrim.timer`则默认为每周），也可每次在文件被删除后就立即执行TRIM指令（这被称为Continuous TRIM）。

警告： 在SATA 3.1前，所有TRIM指令都是非队列的(non-queued)，使用Continuous TRIM将造成频繁的卡顿，这种情况下应使用#Periodic TRIM。此外，对于某些设备，队列的（queued）TRIM指令会造成严重的数据损坏（参见Linux源码中的`ata_device_blacklist`）。因此，在这些设备上，系统可能会强制发送非队列的(non-queued)TRIM指令。详见Wikipedia:Trim_(computing)#Disadvantages
注意： Continuous TRIM不是最被Linux社区推荐的TRIM方式。例如，Ubuntu默认使用periodic TRIM[7], Debian不建议使用continuous TRIM continuous TRIM，Red Hat建议在可行的情况下使用periodic TRIM。[8][失效链接 2020-04-03 ⓘ]（存档于[9]）

要使用Continuous TRIM，在`/etc/fstab`中对应挂载点指定`discard`选项：

    /dev/sda1  /           ext4  defaults,discard   0  1

注意： 不能在`/etc/fstab`中为XFS `/` 分区指定discard挂载选项。根据此帖子，必须使用`rootflags=discard` 内核参数。

对于Ext4文件系统，也可用tune2fs将`discard`设置为一个默认挂载选项：

    # tune2fs -o discard /dev/sdXY

对于可移动设备，使用此方式而不是在`/etc/fstab`中新增条目尤其有用。这样，在其他计算机上挂载分区时，就不需要每次修改`/etc/fstab`了。

注意： 此默认挂载选项不会在`/proc/mounts`中列出。

#### Trim整个设备

当在全新安装或想卖掉你的SSD时，你可能想Trim整个设备。可以使用blkdiscard命令，

#### 为LVM启用TRIM

由LVM逻辑卷上的文件系统产生的TRIM请求将直达对应物理卷，无需额外的配置。

LVM操作（lvremove, lvreduce等）默认不会产生TRIM请求，以便使用vgcfgrestore(8)恢复之前的卷组设定。`/etc/lvm/lvm.conf`中的`issue_discards`设置决定是否在逻辑卷不再占用卷组空间时将discard发送给底层物理卷。

注意： 在修改`issue_discards`设置前，请仔细阅读`/etc/lvm/lvm.conf`中的注释。`issue_discards`设置不会影响由逻辑卷文件系统产生的TRIM请求（如在文件系统内删除文件）的传递，也不会影响thin pool中的空间管理。
警告： 启用`issue_discards`后，将不能再使用vgcfgrestore恢复卷组元数据。一旦执行LVM命令，将无法撤销。

#### 为dm-crypt启用TRIM

警告： discard选项允许discard请求通过加密的块设备传递。这不一定能[10]提升性能，而且有安全风险。详见：

- Debian:SSDOptimization#Mounting SSD filesystems
- dm-crypt/Specialties#Discard/TRIM support for solid state drives (SSD)

对非`/`文件系统，可修改`/etc/crypttab`，在相应设备的options中加入`discard`选项。(见 Dm-crypt/System configuration#crypttab)。

对于`/`文件系统，依照 Dm-crypt/TRIM support for SSD 中的步骤来将正确的内核参数加入到bootloader配置中。

### 提升性能

参见Improving performance#Storage devices。

#### 物理块大小

参见 Advanced Format#Solid state drives。

#### 清空SSD

TRIM只在删除文件时起作用，而在增量保存等替换操作上无能为力。因此，即使在支持TRIM的SSD上，写入性能也会随时间降低。你可能想将SSD存储单元恢复到出厂时的状态，来使其恢复出厂时的写入性能。

要清除存储单元，依照SSD memory cell clearing中的步骤。

注意： 如果你想通过清除存储单元来清除数据，靠SSD控制器来执行该操作可能并不安全可靠。如果你不信任SSD制造商或担心固件中潜在的bug，参见Securely wipe disk#Flash memory。

### 安全

#### Hdparm 显示 "frozen" 状态

一些主板BIOS在初始化时发送了"security freeze"命令给连接的存储设备。同样，一些SSD(和HDD) BIOS在工厂时已被设置为"security freeze"。二者都会导致设备的密码安全设置设为 frozen，如下面的输出:

    :~# hdparm -I /dev/sda

    Security:
     	Master password revision code = 65534
     		supported
     	not	enabled
     	not	locked
     		frozen
     	not	expired: security count
     		supported: enhanced erase
     	4min for SECURITY ERASE UNIT. 2min for ENHANCED SECURITY ERASE UNIT.

如格式化设备或安装新系统之类的操作不受"security freeze"影响。

上面的输出显示了设备在启动处于not locked状态（未设置HDD密码），其frozen状态可防止恶意软件在运行时对设备设置密码。

如果你想为"frozen"的设备设置密码，则主板BIOS必须支持该功能。因为支持设备密码是 硬件加密 所必需的，许多笔记本都支持该功能，但台式机/服务器主板则不然。例如，对于 Intel DH67CL/BL 主板，必须用跳线设置为"maintenance mode"来查看该设置 (见 [11], [12])。

警告： 不要试图用`hdparm`来改变上述的lock安全设置，除非你十分清楚自己在干什么。

如果你想擦除SSD，见 Securely wipe disk#hdparm 以及 上文。

##### 从睡眠中唤醒时设置SSD为"frozen"状态

当从睡眠中唤醒时，SSD很可能失去"frozen"状态，这导致其可被ATA SECURE ERASE命令擦除。

要防止这一问题，可以在每次唤醒后运行一个脚本：

    /usr/lib/systemd/system-sleep/ssd-freeze.sh

    #!/bin/sh
    if [ "$1" = 'post' ]; then
    	sleep 1
    	if hdparm --security-freeze /dev/disk/by-id/ata-name-of-disk; then
    		logger "$0: SSD freeze command executed successfully"
    	else
    		logger "$0: SSD freeze command failed"
    	fi
    fi

#### 硬件加密

正如#Hdparm 显示 "frozen" 状态中提到的，在支持的设备上，在BIOS中为存储设备（SSD/HDD）设置密码可能启动硬件加密。如果设备同时符合OPAL标准，即使BIOS没有设置密码的功能，硬件加密也可能启动，见Self-encrypting drives。

## 故障排除

你遇到的问题可能是由于SSD固件而不是Linux产生的。在尝试排除故障前，请检查固件是否有更新：

- SSD的固件[损坏的链接：无效的章节]
- 主板的BIOS/UEFI

即使是固件的bug，也可能在不更新固件的情况下避免。若没有固件更新可用，或你不想进行固件更新，以下内容可能有所帮助。

### 处理NCQ错误

部分SSD和SATA芯片组在Linux的原生命令队列(NCQ)下不能正常工作。通过dmesg可看到如下错误信息:

    [ 9.115544] ata9: exception Emask 0x0 SAct 0xf SErr 0x0 action 0x10 frozen
    [ 9.115550] ata9.00: failed command: READ FPDMA QUEUED
    [ 9.115556] ata9.00: cmd 60/04:00:d4:82:85/00:00:1f:00:00/40 tag 0 ncq 2048 in
    [ 9.115557] res 40/00:18:d3:82:85/00:00:1f:00:00/40 Emask 0x4 (timeout)

要在系统启动时禁用NCQ，在bootloader配置中添加内核命令行`libata.force=noncq`。例如，要仅为disk0 port9关闭NCQ，使用：`libata.force=9.00:noncq`

或者，可通过sysfs在不重启的情况下在指定设备上关闭NCQ：

    # echo 1 > /sys/block/sdX/device/queue_depth

如果问题仍未得到解决或导致了其他问题，提交一个bug。

### 处理与SATA电源管理有关的错误

某些SSD（如Transcend MTS400）在SATA Active Link Power Management（ALPM）启用时会出现错误。 ALPM默认关闭，但会被节能程序（如TLP, Laptop Mode Tools）启用。

如果在使用这些节能程序时遇到SATA相关错误，应将使用电池时与充电时的电源配置都设为`max_performance`来关闭ALPM。

### 支持TRIM的外接SSD

一些USB转SATA芯片（如VL715、VL716等）以及在外接NVMe硬盘盒（如IB-1817M-C31[失效链接 2022-09-23 ⓘ])）中使用的USB转PCIe芯片（如 智微（JMicron） JMS583 ）支持类似TRIM的命令，这些命令可通过 USB Attached SCSI 驱动程序（在Linux下称为"uas"）发送。

然而内核可能不会自动检测到并启用这一功能。假设有问题的设备为/dev/sdX，可以用以下命令确定是否为这种情况：

    # sg_readcap -l /dev/sdX

如果输出中有一行写着“Logical block provisioning: lbpme=0”，则由于没有设置LBPME位，内核认为该设备不支持Logical Block Provisioning Management 。此时，你应该检查设备的"Logical Block Provisioning"中的"Vital Product Data"页是否显示了支持的unmapping data机制。你可以执行以下命令：

    # sg_vpd -a /dev/sdX

查看有无类似下面的输出:

    Unmap command supported (LBPU): 1
    Write same (16) with unmap bit supported (LBPWS): 0
    Write same (10) with unmap bit supported (LBPWS10): 0

上例中，设备支持"UNMAP"命令。

此外，查看如下命令的输出：

    $ cat /sys/block/sdX/device/scsi_disk/*/provisioning_mode

如果输出为"full"，则表明内核没有检测到该设备支持unmap data。 除了"full"外，内核的SCSI存储驱动目前接受以下provisioning_mode的值：

    unmap
    writesame_16
    writesame_10
    writesame_zero
    disabled

对于上例，要使内核使用"unmap"模式，你可以向"provisioning_mode"中写入"unmap"：

    # echo "unmap" >/sys/block/sdX/device/scsi_disk/*/provisioning_mode

之后，你应该能立刻在对应设备上使用blkdiscard等工具，并在其文件系统上使用fstrim。

如果你想对于特定制造商的所有产品或特定产品，当通过USB其连接时，都能自动设置provisioning_mode，可配置udev。

首先，找到对应设备的Vendor ID和Product ID：

    $ cat /sys/block/sdX/../../../../../../idVendor
    $ cat /sys/block/sdX/../../../../../../idProduct

然后，创建或修改相应的udev规则（本例中使用idVendor 152d和idProduct 0583）：

    # echo 'ACTION=="add|change", ATTRS{idVendor}=="152d", ATTRS{idProduct}=="0583", SUBSYSTEM=="scsi_disk", ATTR{provisioning_mode}="unmap"' >>/etc/udev/rules.d/10-uas-discard.rules

（也可以使用`lsusb`命令来查看idVendor/idProduct。）

## 固件更新

如果设备制造商支持，建议使用fwupd工具来更新固件。

### ADATA

ADATA 在其支持页面上提供了Linux (i686)版的工具。在选择型号之后会出现最新固件的链接。最新的升级工具打包有固件。下载完成后，必须首先给二进制文件设置执行权限，并以root权限运行。

### Crucial

Crucial 提供了以ISO镜像文件升级固件的选项。选择产品后，下载"Manual Boot File"可获取ISO镜像。

注意： Crucial提供的ISO镜像可能不是hybrid格式。如果直接使用`dd`命令将镜像复制到设备上，由于MBR不会被设置，将无法从该设备启动。

M4 Crucial model用户可通过`smartctl`检查是否有需要的固件更新。

    $ smartctl --all /dev/sdX

    ==> WARNING: This drive may hang after 5184 hours of power-on time:
    https://www.tomshardware.com/news/Crucial-m4-Firmware-BSOD,14544.html
    See the following web page for firmware updates:
    https://www.crucial.com/usa/en/support-ssd

建议看见这个警告的用户备份所有重要数据并立即更新。参见该指引来使用ISO镜像和grub更新Crucial MX100的固件。

### Intel

对于无法使用Windows版本Intel® Solid-State Drive Toolbox软件的系统，Intel提供了一个基于Linux live系统的固件更新工具。

此外，还可用使用Intel Memory and Storage (MAS) Tool（intel-mas-cli-toolAUR）命令行工具在Linux下刷入固件。（其PDF用户指南）

例如，要检查固件状态：

    # intelmas show -intelssd 0

    DevicePath : /dev/nvme0n1
    DeviceStatus : Healthy
    Firmware : 002C
    FirmwareUpdateAvailable : The selected Intel SSD contains current firmware as of this tool release.

若有多个SSD，请将`-intelssd 0`修改为对应的值（`1`对应第二块SSD，以此类推）。

如果有可用的更新，可通过`intelmas load -intelssd 0`来应用。PDF用户指南建议进行应用操作后重启并再进行一次。所有设备的最新固件都作为MAS工具的一部分发布，无需单独下载。

### Kingston

适用于基于Sandforce设备的KUF工具可从kingston_fw_updaterAUR获取。

### Mushkin

不那么出名的 Mushkin 牌固态硬盘也使用 Sandforce 控制器，提供了Linux版的升级工具 (和 Kingston 的几乎一样)。

### OCZ

OCZ为Linux提供Command Line Online Update Tool (CLOUT)。相关软件包可在AUR找到：ocz-ssd-utilityAUR、ocztoolboxAUR、oczcloutAUR。

### Samsung

除了使用Magician软件外，也有其它方法升级固件（尽管Samsung认为这是”不受支持“的）。Magician软件可以创建包含固件更新的启动盘，然而Samsung不再为消费级SSD提供该软件。此外，Samsung提供的可引导的ISO镜像也能用来更新固件。还可以使用magician工具（samsung_magician-consumer-ssdAUR）。Magician只支持三星品牌的SSD，不支持Samsung为其它OEM（如联想）制造的SSD。

注意： 对于这些信息，Samsung提供得并不“显然”。它们似乎有4个不同的固件更新页面，每个都介绍了不同的更新方法。

如果你想通过在Linux下创建的Live USB来更新固件（而不是在Microsoft Windows下使用Samsung的Magician软件），参见[13]。

#### 在Linux下更新

此外，固件可在不使用USB启动盘的情况下直接更新。首先，从这里下载适用于对应SSD的最新固件（一个ISO镜像）。

注意： 若ISO镜像中没有下面提到的`initrd`镜像，见#较旧的SSD。

从ISO镜像中解压Linux `initrd`镜像（将samsung_ssd_firmware替换为对应的ISO镜像文件名）：

    $ bsdtar xf samsung_ssd_firmware.iso initrd

解压`root/fumagician/`。该目录中包含固件更新文件：

    $ bsdtar xf initrd root/fumagician

最后，以root权限运行`root/fumagician/fumagician`，确认成功更新固件后，重启计算机。

#### 较旧的SSD

有些SSD固件ISO中包含FreeDOS镜像而不是Linux `initrd`镜像，故需要采取不同的更新方法。下表展示了这些SSD及固件的相对路径：

SSD型号 | FreeDOS镜像路径 | 固件包路径
--- | --- | ---
470, 830 | `BTDSK.IMG` | `SSR/`
840 | `isolinux/btdsk.img` | `samsung/DSRD/`
840 EVO (mSATA), Pro | `ISOLINUX/BTDSK.IMG`

首先，从ISO镜像中解压FreeDOS镜像（将samsung_ssd_firmware替换为对应的ISO镜像文件名，freedos_image_path替换为FreeDOS镜像路径，下同）：

    $ bsdtar xf samsung_ssd_firmware.iso freedos_image_path

将FreeDOS镜像挂载到`/mnt/`：

    # mount freedos_image_path /mnt

利用Magician SSD management utility获取SSD对应的Disk Number：

    # magician --list

更新SSD固件（将firmware_package_path替换为对应的固件包路径）：

    # magician --disk Disk Number --firmware-update --fwpackage-path /mnt/firmware_package_path

最后，以root权限执行`magician --list`，检查输出中Firmware对应的固件版本是否成功更新，并重启计算机。

### SanDisk

对于SanDisk SSD Toolkit不支持的操作系统，SanDisk制作了ISO镜像来进行固件更新。

你必须选择对应SSD型号和容量的固件。烧录ISO镜像后，从创建的CD/DVD启动盘启动计算机即可（可能可以使用USB启动盘）。

此外，由于ISO镜像只包含了Linux内核及initrd，也可以将内核及initrd提取到`/boot`下，并用GRUB或Syslinux启动来更新固件。

另见：

- SanDisk Extreme SSD Firmware Release notes 和 Manual Firmware update version R211
- SanDisk Ultra SSD Firmware release notes 和 Manual Firmware update version 365A13F0
- SanDisk Ultra+ SSD Firmware release notes 和 Manual Firmware update version X2316RL - 使用 `smartctl -a /dev/sdX`检查是否使用了"H2"或"HP"模式。

## 另见

- Discussion on Reddit about installing Arch on an SSD
- Re: Varying Leafsize and Nodesize in Btrfs
- Re: SSD alignment and Btrfs sector size
- Erase Block (Alignment) Misinformation?
- Is alignment to erase block size needed for modern SSD's?
- Btrfs support for efficient SSD operation (data blocks alignment)
- SSD, Erase Block Size & LVM: PV on raw device, Alignment

Category:

- Storage (简体中文)

Hidden categories:

- Pages with dead links
- Pages with broken section links