Linux使用parted命令管理大磁盤分區(qū)
在當今數(shù)據(jù)爆炸的時代,TB 級甚至 PB 級存儲設備早已不是稀罕物。傳統(tǒng)的 fdisk 工具面對超過 2TB 的磁盤時束手無策,這時候我們就需要更強大的工具 —— parted。本文將帶你從零開始掌握 parted 的使用方法,涵蓋基礎操作、高級技巧、腳本自動化,并附帶 Java 實際調用示例,助你成為 Linux 存儲管理大師!
什么是 parted?
parted(Partition Editor)是一個功能強大的命令行磁盤分區(qū)工具,支持創(chuàng)建、刪除、調整、移動和復制分區(qū),尤其擅長處理大于 2TB 的 GPT 分區(qū)表磁盤。與 fdisk 相比,parted 支持多種分區(qū)表格式(如 MBR、GPT、BSD、DASD 等),并能直接操作文件系統(tǒng)邊界。
# 查看 parted 版本 parted --version
小貼士:parted 默認以交互模式運行,但也可以通過 -s 參數(shù)執(zhí)行非交互式命令,非常適合腳本自動化。
安裝與基本語法
大多數(shù)現(xiàn)代 Linux 發(fā)行版默認已安裝 parted。若未安裝,可使用包管理器安裝:
# Ubuntu/Debian sudo apt install parted # CentOS/RHEL/Fedora sudo yum install parted # 或 sudo dnf install parted
基本語法結構:
parted [選項] [設備] [命令 [參數(shù)]...]
常用選項:
-l:列出所有塊設備的分區(qū)表-s:靜默模式(非交互)-m:機器可讀輸出(適合腳本解析)
列出當前磁盤信息
首先,我們查看系統(tǒng)中所有磁盤及其分區(qū)情況:
parted -l
輸出示例:
Model: ATA WDC WD40EFRX-68N (scsi) Disk /dev/sda: 4001GB Sector size (logical/physical): 512B/4096B Partition Table: gpt Disk Flags: Number Start End Size File system Name Flags 1 1049kB 538MB 537MB fat32 EFI System Partition boot, esp 2 538MB 26.3GB 25.8GB ext4 3 26.3GB 4001GB 3975GB ext4
注意:parted 中默認單位是 MB,可通過 unit 命令切換為 GB、TB、%、sectors 等。
創(chuàng)建新分區(qū)(實戰(zhàn)演示)
假設我們有一塊全新的 8TB 磁盤 /dev/sdb,我們需要為其創(chuàng)建 GPT 分區(qū)表并劃分兩個分區(qū)。
步驟 1:進入交互模式
parted /dev/sdb
步驟 2:創(chuàng)建分區(qū)表(GPT)
(parted) mklabel gpt
提示:MBR 最大僅支持 2TB,超過必須使用 GPT!
步驟 3:創(chuàng)建第一個分區(qū)(1TB)
(parted) mkpart primary ext4 0% 1TB
步驟 4:創(chuàng)建第二個分區(qū)(剩余空間)
(parted) mkpart primary ext4 1TB 100%
步驟 5:查看并退出
(parted) print (parted) quit
調整分區(qū)大小
parted 支持在線調整分區(qū)大小(需配合文件系統(tǒng)工具如 resize2fs 使用)。
# 縮小第二分區(qū)到 5TB(先縮小文件系統(tǒng)?。? parted /dev/sdb resizepart 2 5TB # 擴展第一分區(qū)到 2TB parted /dev/sdb resizepart 1 2TB
重要提醒:調整分區(qū)前務必備份數(shù)據(jù)!部分文件系統(tǒng)不支持在線收縮。
刪除分區(qū)
刪除某個分區(qū)非常簡單:
parted /dev/sdb rm 2
這會刪除編號為 2 的分區(qū)。
使用 unit 設置單位
parted 支持靈活的單位設置,便于精確控制:
(parted) unit TB (parted) print (parted) unit % (parted) print (parted) unit s # sectors (parted) print
常用單位:
MB,GB,TB%(百分比)s(扇區(qū),最精確)cyl(柱面,舊式)
高級功能:設置分區(qū)標志
某些分區(qū)需要特殊標志,比如 EFI 分區(qū)或 LVM 標志:
# 設置分區(qū) 1 為 boot/esp parted /dev/sdb set 1 boot on parted /dev/sdb set 1 esp on # 設置分區(qū) 2 為 LVM parted /dev/sdb set 2 lvm on
可用標志列表:
bootrootswaphiddenraidlvmespbios_grub
自動化腳本示例
以下是一個 Bash 腳本,自動為新磁盤創(chuàng)建 GPT + 兩個 ext4 分區(qū):
#!/bin/bash
DISK="/dev/sdb"
echo ">>> 初始化磁盤 $DISK"
parted -s $DISK mklabel gpt
echo ">>> 創(chuàng)建分區(qū) 1 (2TB)"
parted -s $DISK mkpart primary ext4 0% 2TB
echo ">>> 創(chuàng)建分區(qū) 2 (剩余空間)"
parted -s $DISK mkpart primary ext4 2TB 100%
echo ">>> 格式化分區(qū)"
mkfs.ext4 ${DISK}1
mkfs.ext4 ${DISK}2
echo ">>> 掛載分區(qū)"
mkdir -p /mnt/data1 /mnt/data2
mount ${DISK}1 /mnt/data1
mount ${DISK}2 /mnt/data2
echo "? 完成!"
保存為 auto-partition.sh 并賦予執(zhí)行權限:
chmod +x auto-partition.sh ./auto-partition.sh
Java 調用 parted 示例
雖然 parted 是命令行工具,但我們可以通過 Java 的 ProcessBuilder 或 Runtime.exec() 來調用它,實現(xiàn)圖形界面或 Web 后臺管理。
示例 1:列出所有磁盤信息
import java.io.*;
public class PartedManager {
public static void listDisks() {
try {
Process process = Runtime.getRuntime().exec("parted -l");
BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getInputStream())
);
String line;
System.out.println("=== 磁盤分區(qū)信息 ===");
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
int exitCode = process.waitFor();
if (exitCode == 0) {
System.out.println("? 獲取成功");
} else {
System.err.println("? 獲取失敗");
}
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
listDisks();
}
}示例 2:創(chuàng)建 GPT 分區(qū)表(需 root 權限)
import java.io.*;
public class CreateGPT {
public static boolean createGPT(String device) {
try {
// 構建命令:parted -s /dev/sdX mklabel gpt
ProcessBuilder pb = new ProcessBuilder("parted", "-s", device, "mklabel", "gpt");
pb.redirectErrorStream(true); // 合并錯誤流
Process process = pb.start();
BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getInputStream())
);
StringBuilder output = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
output.append(line).append("\n");
}
int exitCode = process.waitFor();
if (exitCode == 0) {
System.out.println("? GPT 分區(qū)表創(chuàng)建成功:" + device);
return true;
} else {
System.err.println("? 創(chuàng)建失敗:" + output.toString());
return false;
}
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public static void main(String[] args) {
// 示例:為 /dev/sdb 創(chuàng)建 GPT
createGPT("/dev/sdb");
}
}示例 3:完整分區(qū)創(chuàng)建流程(Java GUI 后端邏輯)
import java.io.*;
import java.util.ArrayList;
import java.util.List;
public class DiskPartitioner {
// 執(zhí)行 shell 命令并返回輸出
private static String executeCommand(String... command) {
try {
ProcessBuilder pb = new ProcessBuilder(command);
pb.redirectErrorStream(true);
Process process = pb.start();
BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getInputStream())
);
StringBuilder result = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
result.append(line).append("\n");
}
int exitCode = process.waitFor();
if (exitCode != 0) {
throw new RuntimeException("命令執(zhí)行失敗: " + result.toString());
}
return result.toString();
} catch (Exception e) {
throw new RuntimeException("執(zhí)行命令異常: " + e.getMessage(), e);
}
}
// 創(chuàng)建分區(qū)
public static boolean createPartition(String device, int partitionNum,
String fsType, String start, String end) {
try {
System.out.printf(">>> 創(chuàng)建分區(qū) %d: %s 從 %s 到 %s\n",
partitionNum, fsType, start, end);
executeCommand("parted", "-s", device, "mkpart", "primary", fsType, start, end);
String partDevice = device + partitionNum;
// 格式化
System.out.println(">>> 格式化 " + partDevice + " 為 " + fsType);
if ("ext4".equalsIgnoreCase(fsType)) {
executeCommand("mkfs.ext4", "-F", partDevice);
} else if ("xfs".equalsIgnoreCase(fsType)) {
executeCommand("mkfs.xfs", "-f", partDevice);
}
System.out.println("? 分區(qū)創(chuàng)建完成: " + partDevice);
return true;
} catch (Exception e) {
System.err.println("? 分區(qū)創(chuàng)建失敗: " + e.getMessage());
return false;
}
}
// 主函數(shù)測試
public static void main(String[] args) {
String disk = "/dev/sdb";
// 1. 創(chuàng)建 GPT
System.out.println(">>> 初始化 GPT...");
executeCommand("parted", "-s", disk, "mklabel", "gpt");
// 2. 創(chuàng)建多個分區(qū)
createPartition(disk, 1, "ext4", "0%", "2TB");
createPartition(disk, 2, "xfs", "2TB", "6TB");
createPartition(disk, 3, "ext4", "6TB", "100%");
System.out.println("?? 所有分區(qū)創(chuàng)建完畢!");
}
}性能與最佳實踐
推薦做法:
對齊分區(qū):現(xiàn)代 SSD 和 RAID 陣列建議從 1MiB 開始分區(qū)以確保對齊。
parted /dev/sdb mkpart primary ext4 1MiB 100%
使用百分比或明確單位:避免歧義。
備份分區(qū)表:
sfdisk -d /dev/sdb > sdb-backup.txt
操作前卸載分區(qū):
umount /dev/sdb1
parted vs fdisk vs gdisk
| 工具 | 支持 >2TB | 支持 GPT | 交互性 | 易用性 | 適用場景 |
|---|---|---|---|---|---|
fdisk | ? | ? | ? | ??? | 小磁盤、MBR |
gdisk | ? | ? | ? | ?? | GPT 專用 |
parted | ? | ? | ?/? | ???? | 大磁盤、腳本、通用 |
常見錯誤與解決方案
錯誤 1:Error: The backup GPT table is corrupt...
# 修復 GPT 備份表 parted /dev/sdb rescue
或使用 gdisk:
gdisk /dev/sdb # 輸入 'r' 進入恢復菜單,再輸入 'v' 驗證,'w' 寫入修復
錯誤 2:Partition(s) on /dev/sdb are being used
# 查看誰在使用 lsof /dev/sdb1 # 卸載 umount /dev/sdb1 # 或強制卸載(危險?。? umount -l /dev/sdb1
錯誤 3:Unable to open /dev/sdb - Permission denied
# 使用 sudo sudo parted /dev/sdb
或臨時提升權限:
sudo -i parted /dev/sdb
磁盤容量計算技巧
parted 中單位換算容易混淆,記住:
- 1TB = 1000GB(十進制,廠商標準)
- 1TiB = 1024GiB(二進制,系統(tǒng)標準)
# 查看真實扇區(qū)數(shù) parted /dev/sdb unit s print # 計算總容量(字節(jié)) # 總扇區(qū)數(shù) × 扇區(qū)大小 = 總字節(jié)數(shù)
文件系統(tǒng)與 parted 配合
parted 只負責分區(qū),不負責格式化。常用格式化命令:
# ext4 mkfs.ext4 /dev/sdb1 # xfs mkfs.xfs /dev/sdb1 # btrfs mkfs.btrfs /dev/sdb1 # swap mkswap /dev/sdb1 swapon /dev/sdb1
導航磁盤:print, select, help
在交互模式下,這些命令非常實用:
(parted) print devices # 列出所有設備 (parted) select /dev/sdc # 切換當前設備 (parted) help mkpart # 查看 mkpart 幫助 (parted) help # 所有命令幫助
數(shù)據(jù)可視化:磁盤使用情況(mermaid 圖表)
我們可以用 mermaid 繪制磁盤分區(qū)結構圖,便于理解:
渲染錯誤: Mermaid 渲染失敗: Parsing failed: unexpected character: ->“<- at offset: 38, skipped 3 characters. unexpected character: ->數(shù)<- at offset: 44, skipped 4 characters. unexpected character: ->:<- at offset: 49, skipped 1 characters. unexpected character: ->“<- at offset: 60, skipped 3 characters. unexpected character: ->日<- at offset: 66, skipped 3 characters. unexpected character: ->:<- at offset: 70, skipped 1 characters. unexpected character: ->“<- at offset: 81, skipped 3 characters. unexpected character: ->備<- at offset: 87, skipped 3 characters. unexpected character: ->:<- at offset: 91, skipped 1 characters. Expecting token of type 'EOF' but found `1`. Expecting token of type 'EOF' but found `2`. Expecting token of type 'EOF' but found `3`.
注:上圖單位為 GB,實際可根據(jù) parted print 輸出動態(tài)生成。
動態(tài)調整分區(qū)實戰(zhàn)
假設我們要將 /dev/sdb2 從 4TB 擴展到 6TB:
# 1. 先擴展分區(qū)邊界(如果后面有空閑空間) parted /dev/sdb resizepart 2 6TB # 2. 擴展文件系統(tǒng)(ext4) resize2fs /dev/sdb2 # 如果是 xfs xfs_growfs /mount/point
不支持收縮 xfs!ext4 收縮前必須先卸載并檢查:
umount /dev/sdb2 e2fsck -f /dev/sdb2 resize2fs /dev/sdb2 4T parted /dev/sdb resizepart 2 4TB
LVM 與 parted 結合使用
parted 可以為 LVM 創(chuàng)建物理卷分區(qū):
# 創(chuàng)建分區(qū)并標記為 LVM parted /dev/sdb mkpart primary 0% 100% parted /dev/sdb set 1 lvm on # 創(chuàng)建物理卷 pvcreate /dev/sdb1 # 創(chuàng)建卷組 vgcreate vg_data /dev/sdb1 # 創(chuàng)建邏輯卷 lvcreate -L 5T -n lv_mysql vg_data # 格式化掛載 mkfs.ext4 /dev/vg_data/lv_mysql mount /dev/vg_data/lv_mysql /var/lib/mysql
安全測試:使用 loop 設備模擬大磁盤
無需真實大磁盤,可用文件模擬:
# 創(chuàng)建 10GB 文件 dd if=/dev/zero of=disk.img bs=1G count=10 # 關聯(lián)為 loop 設備 sudo losetup -fP disk.img sudo losetup -a # 查看分配的設備,如 /dev/loop0 # 使用 parted 操作 sudo parted /dev/loop0 mklabel gpt sudo parted /dev/loop0 mkpart primary ext4 0% 100% # 格式化掛載 sudo mkfs.ext4 /dev/loop0p1 sudo mkdir /mnt/test sudo mount /dev/loop0p1 /mnt/test # 清理 sudo umount /mnt/test sudo losetup -d /dev/loop0 rm disk.img
Java 圖形界面封裝思路
設想一個 Swing 界面,用戶選擇磁盤、輸入分區(qū)大小、選擇文件系統(tǒng),點擊“創(chuàng)建”后后臺調用上述 Java 代碼。
關鍵類設計:
public class PartitionTask {
private String device;
private List<PartitionConfig> partitions;
public void execute() {
// 1. 驗證輸入
// 2. 執(zhí)行 parted 創(chuàng)建分區(qū)表
// 3. 循環(huán)創(chuàng)建每個分區(qū)
// 4. 格式化
// 5. 掛載(可選)
// 6. 寫入 /etc/fstab(可選)
}
}
public class PartitionConfig {
private int number;
private String filesystem;
private String start;
private String end;
private boolean mountAtBoot;
private String mountPoint;
// getters & setters...
}持久化配置:寫入 /etc/fstab
分區(qū)創(chuàng)建完成后,建議寫入 fstab 實現(xiàn)開機自動掛載:
# 獲取 UUID blkid /dev/sdb1 # 編輯 /etc/fstab UUID=xxxx-xxxx-xxxx /mnt/data1 ext4 defaults,noatime 0 2
Java 中可追加寫入:
public static void addToFstab(String uuid, String mountPoint, String fsType) {
String entry = String.format("UUID=%s %s %s defaults,noatime 0 2\n",
uuid, mountPoint, fsType);
try (FileWriter fw = new FileWriter("/etc/fstab", true)) {
fw.write(entry);
System.out.println("? 已添加到 fstab: " + mountPoint);
} catch (IOException e) {
System.err.println("? 寫入 fstab 失敗: " + e.getMessage());
}
}
生產環(huán)境請先備份原 fstab!
導航歷史:parted 的 undo 功能?
很遺憾,parted 沒有撤銷功能!一旦寫入即生效。
替代方案:
操作前備份分區(qū)表:
sfdisk -d /dev/sdb > backup-sdb.txt
出錯后恢復:
sfdisk /dev/sdb < backup-sdb.txt
企業(yè)級應用場景
場景 1:數(shù)據(jù)庫服務器部署
# 為 MySQL 創(chuàng)建獨立分區(qū) parted /dev/sdb mkpart primary ext4 0% 2TB # 數(shù)據(jù) parted /dev/sdb mkpart primary ext4 2TB 3TB # 日志 parted /dev/sdb mkpart primary ext4 3TB 100% # 備份
場景 2:虛擬化平臺存儲池
# 為 KVM 虛擬機創(chuàng)建 RAW 存儲 parted /dev/sdc mkpart primary 0% 100% mkfs.xfs /dev/sdc1 mount /dev/sdc1 /var/lib/libvirt/images
網(wǎng)絡存儲中的 parted 應用
在 iSCSI 或 NFS 環(huán)境中,parted 同樣適用:
# 連接 iSCSI 目標后,對 /dev/sdd 操作 parted /dev/sdd mklabel gpt parted /dev/sdd mkpart primary xfs 0% 100% mount /dev/sdd1 /mnt/iscsi-data
UEFI/GPT 啟動分區(qū)設置
現(xiàn)代 Linux 安裝推薦 UEFI + GPT:
parted /dev/sda mklabel gpt parted /dev/sda mkpart ESP fat32 1MiB 513MiB parted /dev/sda set 1 boot on parted /dev/sda set 1 esp on parted /dev/sda mkpart primary ext4 513MiB 100%
然后格式化 ESP:
mkfs.fat -F32 /dev/sda1
清理與重建分區(qū)表
徹底清空磁盤簽名和分區(qū)表:
# 清除 GPT/MBR 簽名 sgdisk --zap-all /dev/sdb # 或使用 dd(危險!) dd if=/dev/zero of=/dev/sdb bs=1M count=10 # 重建 parted /dev/sdb mklabel gpt
健康檢查與 SMART
分區(qū)前建議檢查磁盤健康:
smartctl -a /dev/sdb
Java 調用示例:
public static boolean isDiskHealthy(String device) {
try {
String output = executeCommand("smartctl", "-H", device);
return output.contains("PASSED");
} catch (Exception e) {
return false;
}
}Docker 與容器中的磁盤管理
在容器中通常無法直接使用 parted(需要特權和設備訪問),但可在宿主機操作后掛載給容器:
# 宿主機創(chuàng)建分區(qū)并格式化 parted /dev/sdb mkpart ... mkfs.ext4 /dev/sdb1 mount /dev/sdb1 /docker-volumes/app-data # 啟動容器時掛載 docker run -v /docker-volumes/app-data:/data my-app
性能基準:不同文件系統(tǒng)對比
雖然不屬于 parted 范疇,但分區(qū)后選擇合適文件系統(tǒng)很重要:
| 文件系統(tǒng) | 優(yōu)點 | 缺點 | 適用場景 |
|---|---|---|---|
| ext4 | 穩(wěn)定、兼容性好 | 不適合超大文件 | 通用、桌面 |
| xfs | 高并發(fā)、大文件性能優(yōu) | 不支持收縮 | 數(shù)據(jù)庫、媒體存儲 |
| btrfs | 快照、壓縮、RAID | 相對較新 | 實驗性、NAS |
| zfs | 企業(yè)級功能 | 內存占用高 | 企業(yè)存儲 |
故障轉移與高可用
在集群環(huán)境中,共享磁盤需謹慎分區(qū):
# 在主節(jié)點操作 parted /dev/mapper/mpathb mklabel gpt parted /dev/mapper/mpathb mkpart ... # 所有節(jié)點掃描新分區(qū) partprobe /dev/mapper/mpathb
避免多節(jié)點同時寫入分區(qū)表!
總結:parted 的核心優(yōu)勢
- 支持超大磁盤(>2TB)
- 多分區(qū)表支持(GPT/MBR/BSD等)
- 腳本友好(-s 靜默模式)
- 精確控制(扇區(qū)級操作)
- 跨平臺(GNU/Linux、BSD、甚至 macOS)
掌握 parted,你就掌握了 Linux 存儲世界的鑰匙!
最后提醒
- 操作前備份重要數(shù)據(jù)
- 使用
parted print確認當前狀態(tài) - 生產環(huán)境先在測試機演練
- 不確定時查閱
help或手冊頁 - Java 調用時注意權限和異常處理
現(xiàn)在,你已經準備好征服任何規(guī)模的磁盤了!去創(chuàng)建、調整、管理你的存儲王國吧!
Bonus Tip: 使用 lsblk -f 和 df -hT 配合 parted,獲得完整的存儲視圖!
以上就是Linux使用parted命令管理大磁盤分區(qū)的詳細內容,更多關于Linux parted管理大磁盤分區(qū)的資料請關注腳本之家其它相關文章!

