如何從 WSL2 上的 Ubuntu 取回未使用的磁碟空間?

如何從 WSL2 上的 Ubuntu 取回未使用的磁碟空間?

我在 Windows 10 上的 WSL2 上使用 Ubuntu 20.04,我注意到在 Ubuntu 上刪除檔案後,我沒有收回被刪除檔案佔用的空間。例如:在我在 Ubuntu 上刪除檔案之前,它在 Windows 資源管理器上顯示我的 ( C:) 磁碟機上的可用空間約為 46GB。然後,在我刪除了大約 10GB 的檔案(在我的例子中是一些臨時 Gatsby 網站)之後,它導致可用空間更少,大約 45GB,我認為這很奇怪。

那我要怎麼取回那些未使用的位呢?是否有一些我可以使用的終端命令,或者我可以透過 Windows GUI 或其他方式執行某些操作?

答案1

2023 年 9 月更新:據報道,新的 WSL 預發行版 (2.0.0) 為磁碟映像提供了新的「稀疏」模式,當檔案被刪除時,該模式會自動縮小映像。

雖然我還沒有親自測試過,但從開發部落格公告,您可以使用 PowerShell 中的下列命令將現有磁碟映像轉換為稀疏磁碟映像:

wsl --manage <distro> --set-sparse true

您也可以將以下內容新增至您的.wslconfig(位於 Windows輪廓目錄,不在 WSL 內)以使任何新建立的發行版映像稀疏:

[experimental]
sparseVhd=true

較舊的答案:

有一個 WSL Github問題就這個話題展開。 WSL 將自動成長虛擬磁碟 (ext4.vhdx),但縮小虛擬磁碟以回收未使用的空間目前必須手動完成。

您需要做的第一件事是了解 ext4.vhdx 的位置。對於預設的 Ubuntu 安裝,它應該是這樣的%USERPROFILE%\AppData\Local\Packages\CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc\LocalState\

然後,您可以使用多種技術來刪除未使用的空間。我建議您從 a 開始wsl --shutdown並複製 vhdx 作為備份來啟動。如果您正在運行 Docker Desktop,也請將其關閉,否則它可能會在您的--shutdown.

  • 如果您使用的是 Windows Professional 或更高版本,則可以安裝 Hyper-V 並使用 Optimize-VHD commandlet,如原始問題。 。

  • 在 Windows Home(及更高版本)上,您可以diskpart按照指示使用在這個評論中

  • 匯出 WSL 發行版並將其重新匯入到新的 WSL 實例中(如這則評論)也將回收空間。請注意,導入後您需要重置預設使用者名稱。看這裡(和這裡以獲得替代選項)。

我親自測試並確認了第二種和第三種技術。

答案2

當命令 letoptimize-vhd在您的系統中不可用時,請執行下列操作:

在管理其磁碟之前關閉 wsl

wsl --shutdown

將以下腳本儲存為compact-disk.txt

select vdisk file="C:\Users\%username%\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu20.04onWindows_79rhkp1fndgsc\LocalState\ext4.vhdx"
attach vdisk readonly
compact vdisk
detach vdisk

以管理員身份開啟提示符並執行上面儲存的腳本

diskpart /s <SAVED_SCRIPT_FOLDER_PATH>\compact-disk.txt

答案3

  • 在 Windows 功能中啟動 Hyper-V 模組(控制台 -> 開啟或關閉 Windows 功能 -> 啟動 Hyper-V -> 重新啟動)。這是啟動 Optimize-vhd 指令所必需的。
  • 以管理員身分開啟Windows powershell:首先,按Windows+R開啟“執行”,然後在文字方塊中輸入“powershell”。接下來,按 Ctrl+Shift+Enter。 Windows PowerShell 將以管理模式開啟。在 powershell 中,執行以下命令。
  • wsl.exe --shutdown
  • cd 進入 ext4.vhdx 資料夾,通常是cd C:\Users\<user>\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu20.04onWindows_79rhkp1fndgsc\LocalState\
  • optimize-vhd -Path .\ext4.vhdx -Mode full(確保ext4.vhdx沒有被滑鼠點擊,否則會導致powershell中的檔案正在被其他進程使用的錯誤)

答案4

使用此自提升腳本,您可以一次壓縮多個 vhdx。

# Self-elevate the script if required
if (-Not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] 'Administrator')) {
    if ([int](Get-CimInstance -Class Win32_OperatingSystem | Select-Object -ExpandProperty BuildNumber) -ge 6000) {
        $CommandLine = "-File `"" + $MyInvocation.MyCommand.Path + "`" " + $MyInvocation.UnboundArguments
        Start-Process -FilePath PowerShell.exe -Verb Runas -ArgumentList $CommandLine
        Exit
    }
}

#Full Path of vhdx file
$d1 = #Ex: "E:\Docker\wsl\data\ext4.vhdx"
$d2 = ""
$d3 = ""
$d4 = ""
$d5 = ""
$d6 = ""

$paths = $d1, $d2, $d3, $d4, $d5, $d6

foreach ($file in $paths) {
    echo ""
    echo "Befor Shrinking File sizes in MB"
    Get-ChildItem -Path $file | Select-Object FullName, @{Name = "Size"; E = { $_.Length / 1MB } }
    echo ""
    echo "---------"
    echo "Shrinking $file"
    echo "---------"

    wsl --shutdown
    Optimize-VHD -Path $file -Mode Full

    echo ""
    echo "After Shrinking File sizes in MB"
    Get-ChildItem -Path $file | Select-Object FullName, @{Name = "Size"; E = { $_.Length / 1MB } }
    echo ""
    echo ""
    echo ""
    echo ""
}

Read-Host -Prompt "Press Enter to exit"

順便說一句,透過一些調整,您也可以在啟動時運行它(「登入時啟動 Docker」應該被停用)

相關內容