如何从 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)的新预版本为磁盘映像提供了一种新的“稀疏”模式,当删除文件时,该模式会自动缩小映像。

虽然我还没有亲自测试过,但从DevBlog公告,您可以使用以下命令从 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\

然后,您可以使用几种技术来删除未使用的空间。我建议您从开始wsl --shutdown并复制 vhdx 作为备份以开始。如果您正在运行 Docker Desktop,也请将其关闭,否则它可能会在您之后无意中尝试重新启动 WSL --shutdown

  • 如果你使用的是 Windows Professional 或更高版本,则可以安装 Hyper-V 并使用 Optimize-VHD 命令行,如原始问题。 。

  • 在 Windows Home (及更高版本)上,您可以diskpart按照说明使用在这条评论中

  • 导出 WSL 发行版并将其重新导入到新的 WSL 实例中(例如此评论)也将回收空间。请注意,导入后需要重置默认用户名。请参阅这里(和这里以寻找替代选择)。

我已经亲自测试并确认了第二种和第三种技术。

答案2

optimize-vhd当您的系统中没有let 命令时,请执行以下操作:

在管理磁盘之前关闭 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”)。

相关内容