排查 NVMe 磁盘问题


本文档列出了使用具有非易失性存储规范 (NVMe) 接口的磁盘时可能遇到的错误。

您可以将 NVMe 接口用于本地 SSD 和永久性磁盘(Persistent Disk 或 Google Cloud Hyperdisk)。只有最新的机器系列(如 Tau T2A、M3、C3、C3D 和 H3)才对 Persistent Disk 使用 NVMe 接口。机密虚拟机也使用 NVMe Persistent Disk。所有其他 Compute Engine 机器系列都为永久性磁盘使用 SCSI 磁盘接口。

I/O 操作超时错误

如果您遇到 I/O 超时错误,则延迟时间可能会超过提交到 NVMe 设备的 I/O 操作的默认超时参数。

错误消息

[1369407.045521] nvme nvme0: I/O 252 QID 2 timeout, aborting
[1369407.050941] nvme nvme0: I/O 253 QID 2 timeout, aborting
[1369407.056354] nvme nvme0: I/O 254 QID 2 timeout, aborting
[1369407.061766] nvme nvme0: I/O 255 QID 2 timeout, aborting
[1369407.067168] nvme nvme0: I/O 256 QID 2 timeout, aborting
[1369407.072583] nvme nvme0: I/O 257 QID 2 timeout, aborting
[1369407.077987] nvme nvme0: I/O 258 QID 2 timeout, aborting
[1369407.083395] nvme nvme0: I/O 259 QID 2 timeout, aborting
[1369407.088802] nvme nvme0: I/O 260 QID 2 timeout, aborting
...

解决方法

如需解决此问题,请增加超时参数的值。

  1. 查看超时参数的当前值。

    1. 确定永久性磁盘或本地 SSD 卷使用的 NVMe 控制器。
      ls -l /dev/disk/by-id
      
    2. 显示磁盘的 io_timeout 设置(以秒为单位)。

      cat /sys/class/nvme/CONTROLLER_ID/NAMESPACE/queue/io_timeout
      
      替换以下内容:

      • CONTROLLER_ID:NVMe 磁盘控制器的 ID,例如 nvme1
      • NAMESPACE:NVMe 磁盘的命名空间,例如 nvme1n1

      如果您只有一个使用 NVMe 的磁盘,请使用以下命令:

      cat /sys/class/nvme/nvme0/nvme0n1/queue/io_timeout
      

  2. 如需增加提交到 NVMe 设备的 I/O 操作的超时参数,请将以下行添加到 /lib/udev/rules.d/65-gce-disk-naming.rules 文件中,然后重启虚拟机:

    KERNEL=="nvme*n*", ENV{DEVTYPE}=="disk", ATTRS{model}=="nvme_card-pd", ATTR{queue/io_timeout}="4294967295"
    

已分离的磁盘仍出现在计算实例的操作系统中

在使用 Linux 内核版本 6.0 到 6.2 的虚拟机上,涉及 Compute Engine API 方法 instances.detachDiskgcloud compute instances detach-disk 命令的操作可能无法按预期运行。Google Cloud 控制台将设备显示为已移除,计算实例元数据(compute disks describe 命令)将设备显示为已移除,但设备装载点以及由 udev 规则创建的任何符号链接仍会出现在客机操作系统。

错误消息

尝试从虚拟机上已分离的磁盘进行读取导致 I/O 错误:

sudo head /dev/nvme0n3

head: error reading '/dev/nvme0n3': Input/output error

问题

使用 Linux 6.0-6.2 内核但不包含 NVMe 修复的向后移植的操作系统映像在分离 NVMe 磁盘时无法识别。

解决方法

重新启动虚拟机以完成移除磁盘的过程。

为避免此问题,请使用具有不存在此问题的 Linux 内核版本的操作系统:

  • 5.19 或更早版本
  • 6.3 或更高版本

您可以在客户机操作系统中使用 uname -r 命令查看 Linux 内核版本。

如果您将本地 SSD 磁盘挂接到 C3 或 C3D 虚拟机,则可能需要执行额外步骤来为本地 SSD 磁盘创建符号链接。仅当您使用 Google Cloud 提供的以下任何公共映像时,才需要执行这些步骤:

  • SLES 15 SP4 和 SP5
  • SLES 12 SP4

这些额外步骤仅适用于本地 SSD 磁盘:您无需对 Persistent Disk 卷执行任何操作。

之前列出的公共 Linux 映像没有正确的 udev 配置,因此无法为挂接到 C3 和 C3D 虚拟机的本地 SSD 设备创建符号链接。自定义映像也可能不包含为挂接到 C3 和 C3D 虚拟机的本地 SSD 设备创建符号链接所需的 udev 规则。

使用以下说明为 SUSE 或自定义映像添加 udev 规则。

  1. 找到 udev 规则目录。通常为 /lib/udev/rules.d/usr/lib/udev/rules.d。您的映像可能具有不同的 udev 规则目录。
  2. 在 udev 规则目录中找到 65-gce-disk-naming.rules 文件。
  3. 如果 65-gce-disk-naming.rules 文件包含以下行,则您的映像支持新规则,您可以就此停止:

    KERNEL=="nvme*n*", ATTRS{model}=="nvme_card[0-9]*",IMPORT{program}="google_nvme_id -d $tempnode"
    
  4. 如果前面的行不存在,或者文件 65-gce-disk-naming.rules 不存在,请替换现有文件或创建新文件,使用以下网址中的文件内容:https://raw.githubusercontent.com/GoogleCloudPlatform/guest-configs/20230630.00/src/lib/udev/rules.d/65-gce-disk-naming.rules。此文件包含 65-gce-disk-naming.rules 文件的更新内容,包括上一步中的行以及 Compute Engine 磁盘命名所需的其他规则。例如:

    sudo curl -o 65-gce-disk-naming.rules https://raw.githubusercontent.com/GoogleCloudPlatform/guest-configs/20230630.00/src/lib/udev/rules.d/65-gce-disk-naming.rules
    
  5. 转到 udev 目录。

  6. udev 目录中找到 google_nvme_id 文件。

  7. 使用以下网址的内容替换现有 google_nvme_id 文件的内容,或创建一个新文件:

    sudo curl -o google_nvme_id https://raw.githubusercontent.com/GoogleCloudPlatform/guest-configs/20230630.00/src/lib/udev/google_nvme_id
    
  8. 确保 google_nvme_id 文件可执行。

    sudo chmod 755 google_nvme_id
    
  9. 重新启动虚拟机。

  10. 验证符号链接是否已成功创建。

    ls -l /dev/disk/by-id/google-local-nvme-ssd*
    

    输出应列出与实例挂接的本地 SSD 相同的链路,并且每个链路应指向不同的 /dev/nvme 设备路径。例如:

    lrwxrwxrwx 1 root root 13 Jul 19 22:52 /dev/disk/by-id/google-local-nvme-ssd-0 -> ../../nvme0n1
    lrwxrwxrwx 1 root root 13 Jul 19 22:52 /dev/disk/by-id/google-local-nvme-ssd-1 -> ../../nvme1n1
    

    如需详细了解设备名称,请参阅设备命名

    您可以通过运行 lsblk 来验证 /dev/nvme 设备路径是否为本地 SSD 设备。显示 375G 大小的 NVMe 设备是本地 SSD 设备。

后续步骤