2 giờ sáng, điện thoại rung lên. Alert từ vCenter báo hàng loạt VM đang Not Responding. Mình vào console, datastore chuyển màu vàng, log vmkernel đỏ rực. Đây là kịch bản mình đã gặp ba lần trong mấy năm quản lý cluster VMware với 8 host ESXi tại công ty — và mỗi lần như vậy, câu hỏi đầu tiên luôn là: đây là APD hay PDL?
Hai trạng thái này trông giống nhau ngoài mặt — VM đứng hình, I/O timeout, storage không accessible — nhưng nguyên nhân và cách xử lý hoàn toàn khác. Nhầm giữa hai cái có thể tốn thêm cả tiếng đồng hồ, tệ hơn là làm hỏng data.
APD và PDL khác nhau chỗ nào?
All Paths Down (APD)
APD xảy ra khi tất cả đường dẫn (path) từ ESXi host đến storage device đều bị mất, nhưng ESXi chưa xác định được đây là tạm thời hay vĩnh viễn. Host giữ nguyên I/O queue, tiếp tục retry, và đặt device vào trạng thái “APD timeout” sau đúng 140 giây mặc định.
Nguyên nhân thường gặp:
- Cáp FC bị đứt, SFP hỏng, switch SAN restart đột ngột
- iSCSI network gián đoạn (VLAN misconfiguration, NIC flap)
- Storage array tạm thời offline do maintenance không báo trước
- Zoning thay đổi trên FC switch
Permanent Device Loss (PDL)
PDL nặng hơn APD một bậc. Storage array gửi lại SCSI sense code xác nhận thiết bị không còn tồn tại — cụ thể là sense code 0x05/0x25 (logical unit not supported) hoặc 0x02/0x3a (medium not present). ESXi nhận tín hiệu rõ ràng này và biết ngay: mất vĩnh viễn, không cần chờ timeout.
Các tình huống dẫn đến PDL:
- LUN bị xóa hoặc unmapped trực tiếp trên storage array
- Storage array failover không hoàn chỉnh
- Disk group trên vSAN bị lỗi toàn bộ
- HBA driver crash khiến device bị detach ở kernel level
So sánh nhanh
- APD: Chưa rõ tạm thời hay vĩnh viễn — ESXi chờ 140s rồi vào timeout state, VM bị treo (hung), có thể tự phục hồi khi connectivity quay lại
- PDL: Xác nhận vĩnh viễn ngay qua SCSI sense code — phản hồi tức thì, VM nhận I/O error, cần can thiệp thủ công để recovery
Xác định bạn đang gặp APD hay PDL
Đừng đoán mò. SSH vào ESXi host bị ảnh hưởng và chạy ngay các lệnh sau:
# Kiểm tra trạng thái path đến storage device
esxcli storage nmp path list | grep -A5 "State"
# Tìm APD/PDL events trong vmkernel log
grep -i "APD\|PDL\|permanent device\|all paths down" /var/log/vmkernel.log | tail -50
# Kiểm tra trạng thái device cụ thể
esxcli storage nmp device list
# Xem SCSI sense codes (quan trọng để phân biệt PDL)
grep -i "H:0x0 D:0x2 P:0x0 Valid sense\|sense data" /var/log/vmkernel.log | tail -20
Song song đó, mở vCenter Event Log và lọc theo host bị ảnh hưởng. APD sẽ có event esx.problem.storage.apd.start, còn PDL sẽ có esx.problem.storage.permanentDeviceLoss.set. Thấy cái nào là biết ngay.
Xử lý APD
Bước 1: Kiểm tra kết nối vật lý
Trước khi đụng vào phần mềm, kiểm tra phần cứng trước. Mình từng mất 20 phút troubleshoot trên CLI rồi mới phát hiện ra người vận hành datacenter vô tình rút nhầm cáp FC. Bài học đắt giá.
# Kiểm tra HBA port status
esxcli storage san fc list
# Với iSCSI, kiểm tra kết nối network
esxcli iscsi adapter list
esxcli iscsi session list
# Ping storage IP từ VMkernel interface
vmkping -I vmk1 192.168.10.50
Bước 2: Rescan storage adapters
Kết nối vật lý đã ổn? Rescan để ESXi rediscover lại các path:
# Rescan tất cả storage adapter
esxcli storage core adapter rescan --all
# Hoặc rescan adapter cụ thể (ví dụ vmhba1)
esxcli storage core adapter rescan --adapter vmhba1
Sau rescan, VM thường tự resume nếu kết nối đã được khôi phục. Không cần restart VM.
Tùy chỉnh APD timeout và response
Mặc định ESXi chờ 140 giây trước khi vào APD timeout. Sau đó, HA có thể tự động power off VM đang hung — thay vì để VM treo vô thời hạn. Cấu hình qua PowerCLI:
# Kết nối vCenter
Connect-VIServer -Server vcenter.company.com
# Bật APD handling trên tất cả host trong cluster
# Khi APD timeout, HA được phép power off VM hung thay vì chờ vô thời hạn
$cluster = Get-Cluster "Production-Cluster"
Get-VMHost -Location $cluster | ForEach-Object {
$esxHost = $_
Get-AdvancedSetting -Entity $esxHost -Name "Disk.APDHandlingEnable" |
Set-AdvancedSetting -Value 1 -Confirm:$false
Write-Host "APD handling enabled on $($esxHost.Name)"
}
Xử lý PDL
PDL khó chịu hơn nhiều vì VM không bao giờ tự phục hồi. Đồng nghiệp mình từng vô tình xóa nhầm LUN trên NetApp trong lúc maintenance — 12 VM rơi vào PDL ngay lập tức, không cái nào boot được. Phải mất gần 3 tiếng để recovery toàn bộ.
Bước 1: Xác định VM bị ảnh hưởng
# Tìm VM đang bị ảnh hưởng bởi PDL
Get-VM | Get-View | Where-Object {
$_.Runtime.ConnectionState -eq "inaccessible" -or
($_.Runtime.PowerState -eq "poweredOn" -and
$_.Runtime.ConnectionState -eq "disconnected")
} | Select-Object Name, @{N="ConnectionState";E={$_.Runtime.ConnectionState}}
Bước 2: Force power off VM bị hung
VM trong trạng thái PDL không thể shutdown bình thường. Phải dùng kill:
# SSH vào ESXi host đang chạy VM đó
# Tìm world ID của VM
esxcli vm process list
# Force kill VM (thay 12345 bằng world ID thực tế)
esxcli vm process kill --type=force --world-id=12345
# Nếu force không được, dùng hard kill
esxcli vm process kill --type=hard --world-id=12345
Bước 3: Khôi phục storage và re-register VM
Sau khi fix vấn đề storage (recreate LUN, remap, hoặc restore từ backup snapshot của storage array):
# Rescan để ESXi nhận diện lại datastore
esxcli storage core adapter rescan --all
# Kiểm tra datastore đã accessible chưa
esxcli storage vmfs extent list
# Re-register VM nếu nó bị removed khỏi inventory
$datastore = Get-Datastore "DS-Production-01"
$vmxFiles = Get-ChildItem -Path "vmstore:\datacenter\$($datastore.Name)" -Recurse -Filter "*.vmx"
foreach ($vmx in $vmxFiles) {
$resourcePool = Get-ResourcePool "Resources" -Location (Get-Cluster "Production-Cluster")
New-VM -VMFilePath $vmx.DatastoreFullPath -ResourcePool $resourcePool
Write-Host "Registered: $($vmx.Name)"
}
Script monitoring để phát hiện sớm
Ba lần bị đánh thức lúc 2 giờ sáng là đủ. Mình viết script này chạy mỗi 5 phút qua Task Scheduler — gửi cảnh báo trước khi sự cố leo thang:
# apd-pdl-monitor.ps1 — chạy mỗi 5 phút qua Task Scheduler hoặc cron
Connect-VIServer -Server vcenter.company.com -User admin -Password $env:VC_PASS
$alerts = @()
# Kiểm tra tất cả datastore
Get-Datastore | ForEach-Object {
$ds = $_
if ($ds.State -ne "Available") {
$alerts += "[CRITICAL] Datastore '$($ds.Name)' state: $($ds.State)"
}
# Kiểm tra host mount status
$ds.ExtensionData.Host | ForEach-Object {
$mountInfo = $_.MountInfo
if (-not $mountInfo.Accessible) {
$alerts += "[CRITICAL] Datastore '$($ds.Name)' inaccessible on host $($_.Key)"
}
}
}
# Kiểm tra VM disconnected
Get-VM | Where-Object {$_.ExtensionData.Runtime.ConnectionState -eq "inaccessible"} | ForEach-Object {
$alerts += "[WARNING] VM '$($_.Name)' is inaccessible — possible APD/PDL"
}
if ($alerts.Count -gt 0) {
$body = $alerts -join "`n"
# Gửi email hoặc webhook Slack/Teams
Send-MailMessage -To "[email protected]" -Subject "vSphere Storage Alert" -Body $body -SmtpServer "smtp.company.com"
Write-Host $body
}
Disconnect-VIServer -Confirm:$false
Bài học từ những đêm trực sự cố
Qua những lần đó, mình rút ra bốn việc cần làm ngay khi storage có vấn đề:
- Không restart ESXi host ngay — phản xạ tự nhiên nhưng sai. Restart host đang có VM chạy là rủi ro mất thêm data.
- Đọc vmkernel.log trước — 5 phút đọc log tiết kiệm 2 tiếng troubleshoot mù quáng.
- Phân biệt APD/PDL trước khi hành động — APD có thể tự giải quyết, PDL thì không. Chờ sai chỗ là mất thời gian.
- Cấu hình HA/APD response trong vSphere HA — vào Cluster Settings → vSphere HA → Advanced Options, đặt
das.config.fdm.apd.timeouttheo nhu cầu để HA tự handle khi bạn đang ngủ.
Và điều căn bản nhất: multipath phải được cấu hình đúng từ đầu. Một LUN một path là APD đang chờ xảy ra. Tối thiểu cần 2 path độc lập — lý tưởng là 4 (2 HBA × 2 fabric).

