由于WSL2在NTFS上的IO性能过于捉急,还是决定把JupyterLab环境完全挪到WSL原生的文件系统下。但是WSL默认将文件系统放在系统盘,这样我额外加的NVME SSD就成了摆设,于是需要把承载WSL文件系统的虚拟硬盘文件移动到指定的位置。查询资料后,使用原生工具进行迁移的最佳实践是“导出-挪位置-再导入”,那就按这个来吧。

导出WSL环境

WSL的每个发行版环境实际上是一个最大1TB的vhdx虚拟硬盘,可以直接使用wsl导出这个文件到某个指定目录。

wsl --list --verbose
wsl --export Ubuntu-22.04 X:\WSL-Backup\Ubuntu22.vhdx --vhd

重新导入WSL环境

原本的环境我没有急着删——毕竟unregister也很方便,暂时留着以免新环境不能正常使用。这里就要注意导入上面导出的环境时需要起一个不同的名字。这里有两种方式导入:重新导入到某个指定目录,或者在上述的目录原地导入、

wsl --import Ubuntu22New X:\WSL\Ubuntu22New X:\WSL-Backup\Ubuntu22.vhdx --version 2
wsl --import-in-place Ubuntu22New X:\WSL-Backup\Ubuntu22.vhdx

但是导入过程中出现以下报错:

未指定的错误
Error code: Wsl/Service/E_FAIL

说白了,原因不明,但是在这个Github issue里找到了workaround,也就是设置默认WSL版本为WSL2后重新导入。

wsl --set-default-version 2
wsl --import Ubuntu22New E:\WSL\Ubuntu22New E:\WSL-Backup\Ubuntu22.vhdx --vhd

成功后会在指定目录下产生一个ext4.vhdx文件,顾名思义就是WSL使用的ext4文件系统了。实测在原生的文件系统里性能比跨到NTFS性能好上许多,愉快地将之前的Python venv都挪进去了——这时候就体现出虚拟环境的便利了。

设定默认发行版/用户名

设置默认发行版很简单:

wsl --set-default Ubuntu22New

但导入的WSL环境不支持通过wsl直接配置默认用户名,于是需要进到环境里手动修改/etc/wsl.conf文件,添加下面的配置项:

[user]
default=默认用户名

重启环境后(根据微软的文档,需要在登出全部终端后等待至少8s,该环境才会shutdown)再次进入该WSL发行版,就会用设定的默认用户名登入了。

题外话 - Windows Terminal

说实话,Windows终端跟WSL融合的挺好的,目前使用没遇到问题,比起在cmd或者PowerShell里使用WSL体验要好得多,之后没什么问题的话大概会继续用下去。