Dmesg is full of I/O errors on Ubuntu 18.04 VM, physical disks and host are fine
I checked and tried everything shodanshok recommended (thanks again!), but it looks like the problem ended up being the VDI file itself. My best guess is that it was somehow corrupted.
I created a new VDI and moved everything to it during a scheduled maintenance window. Before this, the errors mentioned in my question occurred almost every day, but now it's been more than 3 weeks since the last error, so I truly believe this fixed the problem.