先進格式化
機械硬盤的最小物理存儲單元為單個扇區。固態硬盤(SSD)相對應為頁。[1] 存儲設備的固件將設備上的物理扇區抽象為軟件可操作的邏輯扇區。該扇區的大小即硬盤上最小可尋址單元的大小。
- 物理扇區大小
- 這是物理存儲設備聲稱的可原子寫入的最小單元。對於機械硬盤來説,這是指碟片上扇區的實際大小。在傳統上,機械硬盤的物理扇區大小是 512 字節,這意味着每個扇區可以存放 512 字節的數據。但是,隨着先進格式化機械硬盤的出現,物理扇區的扇區提高到了 4096 字節(4 KiB),使得存儲密度和錯誤校正能力都有所提升。固態硬盤(SSD)則不對外 NAND 閃存的實際頁大小(通常在 4 KiB 到 16 KiB 之間),而是將物理扇區大小和邏輯扇區大小匯報為同意值。對於 NVMe 固態硬盤,它會在電源故障原子寫入單位(Atomic Write Unit Power Fail,AWUPF)參數可用時使用改值。
- 邏輯扇區大小
- 邏輯扇區大小(又稱為作業系統扇區大小)代表了暴露給作業系統和應用的扇區大小。它是在軟件層寫入和讀取存儲設備的扇區大小。邏輯扇區大小可以和物理扇區不同,例如:為了保證舊系統和應用的兼容性,一個有 4096 字節物理扇區大小的先進格式化機械硬盤的邏輯扇區大小可能為 512 字節。
對於不同的「層」而言,即設備,堆疊塊設備和文件系統,應保持同一扇區大小。否則,雖然固件的轉換層的映射操作是透明的,仍會帶來本可避免的開銷。
可通過 lsblk 列出當前物理和邏輯扇區大小:
$ 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
也可以通過 fdisk,smartctl 和 hdparm 的輸出查看扇區大小。
修改扇區大小[編輯 | 編輯原始碼]
部分 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:'
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
代表各類格式所提供的性能級別(包括 degraded,good,better 和 best)。
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
修改需要數秒來完成。
在啟動結束階段會發出非標準的「security freeze」的系統上時,生產於 2020 年前的硬盤可能會攔截 {{ic|Format NVM} 命令。[3][4] 如果 nvme format
命令失敗,可以先嘗試休眠系統(確保使用 S3 而不是 S0ix 休眠),然後在喚醒系統後嘗試再次運行 nvme format
命令。[5][6]
使用製造商專用工具[編輯 | 編輯原始碼]
如果上述通用工具無法修改扇區大小,可以試下使用硬盤製造商的專用工具進行修改。
英特爾(Intel)[編輯 | 編輯原始碼]
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)。
- fdisk,cfdisk 和 sfdisk 會自動處理分區對齊。
- gdisk 和 cgdisk 會自動處理分區對齊。
- sgdisk 默認只對齊分區的起始端。可以通過
-I
/--align-end
選項額外啟用分區大小和末端對齊。
- sgdisk 默認只對齊分區的起始端。可以通過
- Parted 只對齊分區起始端,而不對齊分區大小和末端。在創建分區時,請確保使用 mebibytes 或是更大的 IEC 二進制單位指定分區末端。
可以通過 checkpartitionsalignment.sh bash 腳本來使用 Parted 和 awk 檢查對齊。
dm-crypt[編輯 | 編輯原始碼]
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.
If you encrypted your device with the wrong sector size, the device can be re-encrypted by running:
# cryptsetup reencrypt --sector-size=4096 device
文件系統[編輯 | 編輯原始碼]
在 4Kn(物理和邏輯扇區大小為 4096 字節)硬盤上,所有 mkfs 工具都會使用 4096 字節塊大小。在 512e(4096 字節物理扇區大小,512 字節邏輯扇區大小)及 512n(物理和邏輯扇區大小為 512 字節)硬盤上,不同的 mkfs 工具會使用不同的值。
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 |
- mkfs.ext4(8) 默認為小於 512 MiB 的文件系統使用 1024 字節塊大小,為 512MiB 及以上的使用 4096 字節大小。
如果存儲設備沒有匯報正確的扇區大小,你可以手動將分區按照物理扇區大小進行格式化。
特別是對於由固件管理的疊瓦式磁記錄(SMR)硬盤,例如在物理扇區大小為 4096 字節的設備上使用了 512 字節邏輯扇區大小,它們將受到嚴重影響。這類磁盤有不同的寫入性能區間,且在空閒時會進行重映射和重分配。但是當出現大量寫入活動時(例如 RAID resilvering,備份,寫入大量小文件,rsync 等),由於高性能寫入區被耗盡且疊瓦區會拖慢扇區轉換層,文件系統扇區與物理扇區大小不一致可能導致寫入速度降到每秒個位數兆字節。
以下為一些將扇區顯式設為 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 device0 … deviceN
參考[編輯 | 編輯原始碼]
- Western Digital’s Advanced Format: The 4K Sector Transition Begins
- White paper entitled "Advanced Format Technology."
- Failure to align one's HDD results in poor read/write performance. See [10] for specific examples.