先進格式化

出自 Arch Linux 中文维基

此頁面或章節適合移動到 Storage layout and alignment

附註: 「先進格式化」僅適用於機械硬碟。(在 Talk:先進格式化#Rewrite Advanced Format to a new Sector Sizes page 討論)


機械硬碟的最小物理存儲單元為單個扇區。固態硬碟(SSD)相對應為頁。[1] 存儲設備的固件將設備上的物理扇區抽象為軟體可操作的邏輯扇區。該扇區的大小即硬碟上最小可尋址單元的大小。

注意: 無論存儲設備為何種類型,軟體和文檔可能將「扇區」與「塊」互換使用。
物理扇區大小
這是物理存儲設備聲稱的可原子寫入的最小單元。對於機械硬碟來說,這是指碟片上扇區的實際大小。在傳統上,機械硬碟的物理扇區大小是 512 字節,這意味著每個扇區可以存放 512 字節的數據。但是,隨著先進格式化機械硬碟的出現,物理扇區的扇區提高到了 4096 字節(4 KiB),使得存儲密度和錯誤校正能力都有所提升。固態硬碟(SSD)則不對外 NAND 快閃記憶體的實際頁大小(通常在 4 KiB 到 16 KiB 之間),而是將物理扇區大小和邏輯扇區大小匯報為同意值。對於 NVMe 固態硬碟,它會在電源故障原子寫入單位(Atomic Write Unit Power Fail,AWUPF)參數可用時使用改值。
邏輯扇區大小
邏輯扇區大小(又稱為作業系統扇區大小)代表了暴露給作業系統和應用的扇區大小。它是在軟體層寫入和讀取存儲設備的扇區大小。邏輯扇區大小可以和物理扇區不同,例如:為了保證舊系統和應用的兼容性,一個有 4096 字節物理扇區大小的先進格式化機械硬碟的邏輯扇區大小可能為 512 字節。

對於不同的「層」而言,即設備,堆疊塊設備和文件系統,應保持同一扇區大小。否則,雖然固件的轉換層的映射操作是透明的,仍會帶來本可避免的開銷。

可通過 lsblk 列出當前物理和邏輯扇區大小:

本文或本章節的事實準確性存在爭議。

原因: 下列的兩種命令(lsblkcat /sys/class...)都無法準確提供 NVMe 硬碟的物理扇區大小(可能涉及所有 SSDs),而是會給出邏輯扇區的大小。(在 Talk:先進格式化 中討論)
$ 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(NVMe 命令集標準 1.0 或以上的 Format NVM)或 ATA(ATA 命令集 - 4 或以上的 SET SECTOR CONFIGURATION EXT)命令修改它們匯報的扇區大小。對於機械硬碟而言,這一操作通過修改它們的邏輯扇區大小到與物理扇區大小一致,優化了硬碟性能。而對於 NVMe 固態硬碟而言,邏輯扇區和物理扇區的大小都受到更改。

SATA 固態硬碟通常不支持修改扇區大小。部分 Intel SATA SSD 僅可以被修改匯報的物理扇區大小,無法修改邏輯扇區大小。[2] 可按照 #Intel 中的操作來修改硬碟匯報的物理扇區大小。

修改扇區大小包含了一系列複雜的操作,其中涉及到了低級格式化。作為替代,你可以在硬碟上創建文件系統時手動指定扇區大小來優化性能。詳細信息可參考 #dm-crypt#文件系統

先進格式化機械硬碟[編輯 | 編輯原始碼]

使用 hdparm 工具確定先進格式化硬碟的扇區大小是否可被更改:

# hdparm -I /dev/sdX | grep 'Sector size:'
注意: 對於通過 USB 連接的硬碟,對應的 USB 橋接器需支持 SAT(SCSI/ATA 翻譯)(ANSI INCITS 431-2007)。

Advanced Format drives whose Sector Configuration Log lists multiple logical sector sizes will show a list of them:

        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 扇區大小或#文件系統塊大小至少為 4096 字節,並與其對齊。

對於一塊先進格式化的 4Kn 硬碟:

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

4Kn 硬碟在出廠時已經是最佳配置,不需要在分區/格式化是進行特殊操作,可以照常使用。

如果你的 SATA 機械硬碟支持多個邏輯扇區大小和可選的 SET SECTOR CONFIGURATION EXT ATA 命令(例如希捷宣傳帶有 FastFormat 功能的硬碟),你可以使用 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)經常使用較大的物理塊(通常為 4 KiB,8 KiB,有時會更大),它們通常還是將自己的邏輯塊大小匯報為 512 字節。

可以通過 nvme-cli 使用 Identify Namespace 命令來查看 NVMe 硬碟的格式化後邏輯塊地址大小(Formatted Logical Block Address Size, FLBAS):

# 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 是每個邏輯塊地址(Logical Block Address, LBA)的額外元數據字節大小。這一功能在 Linux 上尚無完善支持,所以最好是使用該值為 0 的格式。
  • Relative Performance 代表各類格式所提供的性能級別(包括 degradedgoodbetterbest)。

smartctl 也可以顯示設備支持的邏輯塊地址大小,但輸出的結果可讀性不佳。例如:

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

可以使用 --lbaf 參數向 nvme format 命令傳入目標值來修改邏輯塊地址大小:

# 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

修改需要數秒來完成。

注意: 確保分區時參照#分區對齊進行,否則將破壞任何性能優勢。

本文或本章節的事實準確性存在爭議。

原因: 在調整電源狀態或是 UEFI 設置前,建議用戶使用原生 nvme 命令檢查操作日誌,或是使用類似 nvme reset 的命令軟重置控制器。(在 Talk:先進格式化 中討論)


在啟動結束階段會發出非標準的「security freeze」的系統上時,生產於 2020 年前的硬碟可能會攔截 {{ic|Format NVM} 命令。[3][4] 如果 nvme format 命令失敗,可以先嘗試休眠系統(確保使用 S3 而不是 S0ix 休眠),然後在喚醒系統後嘗試再次運行 nvme format 命令。[5][6]

使用製造商專用工具[編輯 | 編輯原始碼]

如果上述通用工具無法修改扇區大小,可以試下使用硬碟製造商的專用工具進行修改。

英特爾(Intel)[編輯 | 編輯原始碼]

本文內容或本節內容已經過期。

原因: 自從 Intel 固態硬碟業務被 SK 海力士以 Solidigm 品牌收購後,Intel MAS 工具就只能用於傲騰(Optane)產品上,不再能被用於管理固態硬碟。Solidigm 提供了與 Intel MAS 過去功能相同的 solidigm-sst-storage-tool-cliAUR 工具,可參考 Solid_state_drive/NVMe#Intel/Solidigm。 (在Talk:先進格式化討論)

這篇文章的某些內容需要擴充。

原因: Intel 的工具只會修改匯報的物理扇區大小,邏輯扇區大小仍將保持為 512 字節。[7] (在 Talk:先進格式化 中討論)

For Intel use the Intel Memory and Storage (MAS) Tool (intel-mas-cli-toolAUR) with the -set PhysicalSectorSize=4096 option.

希捷(Seagate)[編輯 | 編輯原始碼]

對於希捷可以使用 openseachestAUR

掃描所有硬碟來找到要修改的硬碟,然後輸出對應硬碟的相關信息:

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

應該可以看到硬碟的詳細信息了。請確保序列號與修改目標匹配。

通過以下命令檢查硬碟支持的邏輯區塊大小:

# openSeaChest_Format -d /dev/sdX --showSupportedFormats

如果其中包含 4096,你可以使用以下命令將邏輯扇區大小修改為對應值:

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

修改需要數分鐘,完成後你的硬碟扇區就是 4K 原生大小了。

分區對齊[編輯 | 編輯原始碼]

正確的分區對齊可避免過多的讀寫操作。對於個人電腦而言,通常建議將各分區的起始端和大小對齊到 1 MiB(1 048 576 bytes)位置。這一操作涵蓋了多數常見的頁和塊大小場景(通常的有 1 MiB,512 KiB,128 KiB,4 KiB 和 512 B)。

警告: 分區對齊錯誤將造成無法在 dm-crypt/LUKS 上使用 4096 字節扇區大小,參見 [8]
  • fdisk,cfdisk 和 sfdisk 會自動處理分區對齊。
  • gdisk 和 cgdisk 會自動處理分區對齊。
    • sgdisk 默認只對齊分區的起始端。可以通過 -I/--align-end 選項額外啟用分區大小和末端對齊。
  • Parted 只對齊分區起始端,而不對齊分區大小和末端。在創建分區時,請確保使用 mebibytes 或是更大的 IEC 二進位單位指定分區末端。

可以通過 checkpartitionsalignment.sh bash 腳本來使用 Parted 和 awk 檢查對齊。

dm-crypt[編輯 | 編輯原始碼]

這篇文章的某些內容需要擴充。

原因: Add example for plain dm-crypt. (在 Talk:先進格式化 中討論)

As of Cryptsetup 2.4.0, luksFormat automatically detects the optimal encryption sector size for LUKS2 format [9].

However, for this to work, the device needs to report the correct default sector size, see #Changing sector size.

After using cryptsetup luksFormat, you can check the sector size used by the LUKS2 volume with

# cryptsetup luksDump device | grep sector

If the default sector size is incorrect, you can force create a LUKS2 container with a 4K sector size and otherwise default options with:

# cryptsetup luksFormat --sector-size=4096 device

The command will abort on an error if the requested size does not match your device:

# cryptsetup luksFormat --sector-size 4096 device
(...)
Verify passphrase: 
Device size is not aligned to requested sector size.
注意: See cryptsetup issue 585 for why the command may fail while the underlying drive does use 4K physical sectors.

If you encrypted your device with the wrong sector size, the device can be re-encrypted by running:

警告: The contained file system must have a block size of 4096 bytes or a multiple of it, otherwise it will break.
# cryptsetup reencrypt --sector-size=4096 device

文件系統[編輯 | 編輯原始碼]

這篇文章的某些內容需要擴充。

原因: Differentiate which mkfs utilities use 4096 explicitly and which use the page size (getconf PAGESIZE). (在 Talk:先進格式化 中討論)

在 4Kn(物理和邏輯扇區大小為 4096 字節)硬碟上,所有 mkfs 工具都會使用 4096 字節塊大小。在 512e(4096 字節物理扇區大小,512 字節邏輯扇區大小)及 512n(物理和邏輯扇區大小為 512 字節)硬碟上,不同的 mkfs 工具會使用不同的值。

非 4Kn 硬碟的文件系統塊大小(字節)
mkfs 工具 512e 硬碟 512n 硬碟
mkfs.bcachefs 4096 512
mkfs.btrfs(8) 4096 4096
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 字節塊大小,為 512MiB 及以上的使用 4096 字節大小。

如果存儲設備沒有匯報正確的扇區大小,你可以手動將分區按照物理扇區大小進行格式化。

特別是對於由固件管理的疊瓦式磁記錄(SMR)硬碟,例如在物理扇區大小為 4096 字節的設備上使用了 512 字節邏輯扇區大小,它們將受到嚴重影響。這類磁碟有不同的寫入性能區間,且在空閒時會進行重映射和重分配。但是當出現大量寫入活動時(例如 RAID resilvering,備份,寫入大量小文件,rsync 等),由於高性能寫入區被耗盡且疊瓦區會拖慢扇區轉換層,文件系統扇區與物理扇區大小不一致可能導致寫入速度降到每秒個位數兆字節。

注意: 在 x86_64 系統上,Linux 無法掛載扇區大於 4 KiB 的文件系統。具體細節和當前進度可參考 Large block sizes (LBS)

以下為一些將扇區顯式設為 4096 字節大小的命令示例:

  • Bcachefs:
    # bcachefs format --block_size=4096 /dev/device0 /dev/deviceN --replicas=n
  • 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

參考[編輯 | 編輯原始碼]