高级格式

来自 ArchWiki

此条目或章节可能需要移动到 存储布局和对齐

注释: “高级格式”是 HDD 特有的。(在 Talk:Advanced Format#Rewrite Advanced Format to a new Sector Sizes page 中讨论)

硬盘驱动器(HDD)的最小物理存储单元是扇区。固态硬盘(SSD)的等效单位是页。[1] 存储设备固件将其物理扇区抽象为软件可以操作的逻辑扇区。此扇区的大小是指磁盘上最小可寻址单元的大小。

注意: 软件和文档有时可能会互换使用“扇区”和“块”,而不管存储类型如何。
物理扇区大小
这是物理存储设备声称可以原子写入的最小单位。对于 HDD,它是盘片中扇区的实际大小。传统上,HDD 的物理扇区大小为 512 字节,这意味着每个扇区可以容纳 512 字节的数据。然而,随着高级格式 HDD 的引入,物理扇区大小增加到 4096 字节 (4 KiB),以提高存储密度和改进错误纠正能力。SSD 不会公开其 NAND 闪存的实际页面大小(通常范围为 4 KiB 到 16 KiB),而是将其报告的物理扇区大小与逻辑扇区大小相同。对于 NVMe SSD,如果可用,则使用原子写入单元掉电 (AWUPF) 参数值。
逻辑扇区大小
逻辑扇区大小,也称为操作系统扇区大小,表示暴露给操作系统和应用程序的扇区的大小。它是软件级别上用于从存储设备读取和写入的扇区大小。逻辑扇区大小可能与物理扇区大小不同。例如,物理扇区大小为 4096 字节的高级格式 HDD 仍然可以呈现 512 字节的逻辑扇区大小,以便与旧系统和应用程序兼容。

不同的“层”,即设备、堆叠块设备和文件系统,应使用相同的扇区大小。如果它们不这样做,来自固件翻译层的映射过程(虽然通常是透明的)将导致可以避免的开销。

当前的物理和逻辑扇区大小值可以使用 lsblk 列出

此条目或章节的事实准确性存在争议。

原因: 以下命令(lsblkcat /sys/class...)都不能准确提供 NVMe 驱动器(可能所有 SSD)上的物理扇区大小,而是报告逻辑扇区大小。(在 Talk:Advanced Format 中讨论)
$ lsblk -td
NAME    ALIGNMENT MIN-IO OPT-IO PHY-SEC LOG-SEC ROTA SCHED       RQ-SIZE  RA WSAME
sda             0   4096      0    4096    4096    1 mq-deadline      64 128    0B
nvme1n1         0   4096      0    4096    4096    0 none           1023 128    0B
nvme0n1         0   4096      0    4096    4096    0 none           1023 128    0B

PHY-SEC 显示物理扇区大小,LOG-SEC 显示逻辑扇区大小。

或者,可以从以下 sysfs 条目读取特定驱动器的值

$ cat /sys/class/block/drive/queue/physical_block_size
$ cat /sys/class/block/drive/queue/logical_block_size

扇区大小也可以在 fdisksmartctlhdparm 输出中看到。

更改扇区大小

警告: 更改驱动器的扇区大小将不可撤销地擦除驱动器上的所有数据。

一些 NVMe 驱动器和“企业级”SATA 硬盘驱动器支持分别使用标准 NVMe(来自 NVM Command Set Specification 1.0 或更高版本的 Format NVM)或 ATA(来自 ATA Command Set - 4 或更高版本的 SET SECTOR CONFIGURATION EXT)命令更改其报告的扇区大小。对于硬盘驱动器,这会更改逻辑扇区大小,以匹配物理扇区大小以获得最佳性能。而对于 NVMe 固态硬盘,逻辑和物理扇区大小值都会更改。

SATA 固态硬盘通常不支持更改其扇区大小。例外情况是某些英特尔 SATA SSD 可以更改报告的物理扇区大小,但不能更改逻辑扇区大小。[2] 按照 #Intel 中的说明更改其报告的物理扇区大小。

更改驱动器的扇区大小是一个复杂的过程,需要低级格式化。作为替代方案,您可以在驱动器上创建文件系统时手动指定所需的扇区大小,以获得最佳性能。请参阅 #dm-crypt#File_systems

高级格式硬盘驱动器

要确定是否可以更改高级格式硬盘驱动器的扇区大小,请使用 hdparm 实用程序

# hdparm -I /dev/sdX | grep 'Sector size:'
注意: 对于 USB 连接的驱动器,USB 桥接器需要支持 SAT(又名 SCSI/ATA 转换)(ANSI INCITS 431-2007)。

其扇区配置日志列出多个逻辑扇区大小的高级格式驱动器将显示一个列表

        Logical  Sector size:                   512 bytes [ Supported: 512 4096 ]
        Physical Sector size:                  4096 bytes

不支持多个可更改逻辑扇区大小的硬盘驱动器将仅报告当前的扇区大小。例如,高级格式 512e 驱动器

        Logical  Sector size:                   512 bytes
        Physical Sector size:                  4096 bytes

为了在这些类型的驱动器上获得最佳性能,请确保 #dm-crypt 扇区大小或 #File_systems 块大小至少为 4096 字节并与之对齐。

高级格式 4Kn 驱动器

        Logical  Sector size:                  4096 bytes
        Physical Sector size:                  4096 bytes

4Kn 驱动器开箱即用就具有最佳配置,并且在分区/格式化时不需要特殊考虑。它们可以直接使用。

如果您的 SATA HDD 支持多个逻辑扇区大小和可选的 ATA 命令 SET SECTOR CONFIGURATION EXT(通常仅在所谓的“企业级”HDD 中可用),则可以使用 hdparm 在支持的逻辑扇区大小之间进行更改。要将其设置为 4096 字节,即 4Kn,请运行

# hdparm --set-sector-size 4096 --please-destroy-my-drive /dev/sdX

之后,hdparm 应报告逻辑扇区大小为 4096 字节

# hdparm -I /dev/sdX | grep 'Sector size:'
        Logical  Sector size:                  4096 bytes [ Supported: 512 4096 ]
        Physical Sector size:                  4096 bytes

NVMe 固态硬盘

大多数固态硬盘 (SSD) 将其逻辑块地址大小报告为 512 字节,即使它们在物理上使用更大的块 - 通常为 4 KiB、8 KiB,有时甚至更大。

要检查 NVMe 驱动器的格式化逻辑块地址大小 (FLBAS),请结合 Identify Namespace 命令使用 nvme-cli 实用程序

# nvme id-ns -H /dev/nvme0n1 | grep "Relative Performance"
LBA Format  0 : Metadata Size: 0   bytes - Data Size: 512 bytes - Relative Performance: 0x2 Good (in use)
LBA Format  1 : Metadata Size: 0   bytes - Data Size: 4096 bytes - Relative Performance: 0x1 Better
  • Metadata Size 是每个逻辑块地址 (LBA) 的额外元数据字节数。由于 Linux 下对此支持不佳,因此最好在此处选择值为 0 的格式。
  • Relative Performance 指示哪种格式将提供 降级良好更好最佳 性能。

smartctl 也可以显示支持的逻辑块地址大小,但它不提供用户友好的描述。例如

# smartctl -c /dev/nvme0n1
...
Supported LBA Sizes (NSID 0x1)
Id Fmt  Data  Metadt  Rel_Perf
 0 +     512       0         2
 1 -    4096       0         1

要更改逻辑块地址大小,请使用 nvme format 并使用 --lbaf 参数指定首选值

# nvme format --lbaf=1 /dev/nvme0n1
You are about to format nvme0n1, namespace 0x1.
WARNING: Format may irrevocably delete this device's data.
You have 10 seconds to press Ctrl-C to cancel this operation.

Use the force [--force] option to suppress this warning.
Sending format operation ... 
Success formatting namespace:1

这应该只需几秒钟即可完成。

注意: 分区时请务必遵循 #Partition_alignment,否则任何性能优势都将失效。

此条目或章节的事实准确性存在争议。

原因: 在摆弄电源状态或 UEFI 设置之前,建议用户使用本机 nvme 命令检查操作日志,或使用例如 nvme reset 软重置控制器。(在 Talk:Advanced Format 中讨论)

2020 年之前的驱动器在用于在 POST 结束时发出非标准“安全冻结”的系统上时,可能会阻止 Format NVM 命令。[3][4] 如果 nvme format 失败,请尝试挂起系统(确保使用 S3 睡眠而不是 S0ix),然后在唤醒后再次尝试运行 nvme format[5][6]

使用制造商特定程序

如果上述通用实用程序不允许更改扇区大小,则仍然可以使用驱动器制造商的实用程序来更改它。

英特尔

对于英特尔,请使用 Intel Memory and Storage (MAS) Tool (intel-mas-cli-toolAUR) 和 -set PhysicalSectorSize=4096 选项。请注意,只会更改报告的物理扇区大小,逻辑扇区大小将保持不变。

注意: 自从英特尔的 SSD 业务被 SK Hynix 以 Solidigm 品牌收购以来,Intel MAS 不能用于管理 SSD,只能用于 Optane 产品。Solidigm 提供了 solidigm-sst-storage-tool-cliAUR 来执行 Intel MAS 过去提供的相同功能;请参阅 Solid state drive/NVMe#Intel/Solidigm

希捷

对于希捷,请使用 openseachestAUR

扫描所有驱动器以找到正确的驱动器,并打印您找到的驱动器的信息

# openSeaChest_Basics --scan
# openSeaChest_Basics -d /dev/sdX -i

应该打印出有关驱动器的信息。请务必检查序列号。

检查驱动器支持的逻辑块大小

# openSeaChest_Format -d /dev/sdX --showSupportedFormats

如果列出了 4096,您可以按如下方式将其逻辑扇区大小更改为 4096

# openSeaChest_Format -d /dev/sdX --setSectorSize=4096 --confirm this-will-erase-data

这将需要几分钟时间,之后您的驱动器现在使用 4 KiB 本地扇区大小。

分区对齐

正确对齐分区可以避免过多的读-修改-写周期。个人计算机的典型做法是将每个分区的起始位置和大小对齐到 1 MiB(1 048 576 字节)的标记。这涵盖了所有常见的页面和块大小方案,因为它可被所有常用的尺寸整除——1 MiB、512 KiB、128 KiB、4 KiB 和 512 B。

警告: 未对齐的分区将阻止 dm-crypt/LUKS 使用 4096 字节扇区。请参阅 [7]
  • fdisk, cfdisk and sfdisk 会自动处理对齐。
  • gdisk 和 cgdisk 会自动处理对齐。
    • sgdisk 默认情况下仅对齐分区的开头。使用 -I/--align-end 选项可额外启用分区大小/末尾对齐。
  • Parted 仅对齐分区的开头,而不对齐大小/末尾。创建分区时,请确保以兆字节或更大的 IEC 二进制单位指定分区末尾。

checkpartitionsalignment.sh 是一个 bash 脚本,它使用 Parted 和 awk 检查对齐。

dm-crypt

此条目或章节需要扩充。

原因: 添加纯 dm-crypt 的示例。(在 Talk:Advanced Format 中讨论)

Cryptsetup 2.4.0 开始,luksFormat 会自动检测 LUKS2 格式的最佳加密扇区大小 [8]

但是,为了使其工作,设备需要报告正确的默认扇区大小,请参阅 #Changing sector size

使用 cryptsetup luksFormat 后,您可以使用以下命令检查 LUKS2 卷使用的扇区大小

# cryptsetup luksDump device | grep sector

如果默认扇区大小不正确,您可以强制创建一个扇区大小为 4 KiB 且其他选项为默认值的 LUKS2 容器

# cryptsetup luksFormat --sector-size=4096 device

如果请求的大小与您的设备不匹配,该命令将因错误而中止

# cryptsetup luksFormat --sector-size 4096 device
(...)
Verify passphrase: 
Device size is not aligned to requested sector size.
注意: 请参阅 cryptsetup 问题 585,了解为什么底层驱动器确实使用 4 KiB 物理扇区时,该命令可能会失败。

如果您使用错误的扇区大小加密了设备,则可以通过运行以下命令重新加密设备

警告: 包含的文件系统必须具有 4096 字节或其倍数的块大小,否则它将崩溃。
# cryptsetup reencrypt --sector-size=4096 device

文件系统

此条目或章节需要扩充。

原因: 区分哪些 mkfs 实用程序显式使用 4096,哪些使用页面大小 (getconf PAGESIZE)。(在 Talk:Advanced Format 中讨论)

在 4Kn 磁盘(4096 字节物理扇区大小和 4096 字节逻辑扇区大小)上,所有 mkfs 实用程序都将使用 4096 字节的块大小。在 512e(4096 字节物理扇区大小,512 字节逻辑扇区大小)和 512n(512 字节物理扇区大小和 512 字节逻辑扇区大小)磁盘上,每个 mkfs 实用程序的行为都不同。

非 4Kn 磁盘上的文件系统块大小(以字节为单位)
mkfs 实用程序 512e 磁盘 512n 磁盘
mkfs.bcachefs 4096 512
mkfs.btrfs(8) 4096 4096
mkfs.exfat(8) 4096 512
mkfs.ext4(8) 40961 40961
mkfs.fat(8) 512 512
mkfs.f2fs(8) 512 512
mkfs.jfs(8) 4096 4096
mkfs.nilfs2(8) 4096 4096
mkfs.ntfs(8) 512 512
mkfs.reiserfs(8) 4096 4096
mkfs.udf(8) 512 512
mkfs.xfs(8) 4096 512
mkswap(8) 4096 4096
zpool-create(8) 512 512
  1. mkfs.ext4(8) 对于小于 512 MiB 的文件系统,默认使用 1024 字节扇区,对于 512 MiB 及更大的文件系统,默认使用 4096 字节扇区。

如果存储设备未报告正确的扇区大小,您可以根据物理扇区大小显式格式化分区。

特别是固件管理的叠瓦式磁记录 (SMR) 驱动器,如果其物理扇区大小为 4096 字节,而使用 512 字节的逻辑扇区大小,则会受到严重负面影响。这些驱动器具有不同的性能写入区域,并且在空闲时会发生重新映射重新分配,但在大量活动写入期间(例如,RAID 重建、备份、写入许多小文件、rsync 等),不同的文件系统扇区大小可能会将写入速度降至个位数兆字节/秒,因为高性能写入区域已耗尽,并且扇区转换层在叠瓦式区域上工作过度。

注意: 在 x86_64 系统上,Linux 无法挂载块大小大于 4 KiB 的文件系统。有关详细信息和当前进展,请参阅 Large block sizes (LBS)

以下是一些显式设置 4096 字节扇区大小的示例

  • Bcachefs:
    # bcachefs format --block_size=4096 /dev/device0 /dev/deviceN --replicas=n
  • exFAT
    # mkfs.exfat -s 4096 /dev/device
  • ext4:
    # mkfs.ext4 -b 4096 /dev/device
  • FAT:
    # mkfs.fat -S 4096 /dev/device
  • NTFS-3G:
    # mkfs.ntfs -Q -s 4096 /dev/device
  • UDF
    # mkfs.udf -b 4096 /dev/device
  • XFS:
    # mkfs.xfs -s size=4096 /dev/device
  • ZFS:
    # zpool create -o ashift=12 poolname raidz device0deviceN

参见