QEMU - incorrect real disk size of a virtual drive
du both report the actual allocated space from host point of view. They can not know/understand if the guest OS is really using that space or if, as in you case, it was freed by the user.
To inform the host that your guest has a ton of free space you need to
fstrim your guest filesystem and you must be sure that your qemu/guest block device stack correctly passes down
TRIM/discard requests. In order to do that, you need to:
use a qemu block device driver with TRIM/discard support. Example of such drives are
sata/ahci. All these drivers expose block devices using the classical
/dev/sd[abcd...]nomenclature. On the other hand it appears that your guest is using a plain
/dev/vd[abcd...]names), which does not support TRIM/discard. You can check if your driver support discards by issuing
enable the relative libvirt domain
Finally, your host must be using a filesystem with
hole_punching support as ext4 (which you are using) and xfs.
You can read here for some more information.
If all prerequisites are true, issuing
fstrim <mount_point> inside your guest will automatically de-allocate unused space on host also. Be sure to understand that the logical/apparent file size will remain unchanged (ie: it will show 2.0 TB ever after
fstrim), but using
du will reveal the true (smaller) allocated file size.
If the prerequisites are not met, you need to offline compact your image file via
qemu-img convert after cleaning your guest free space with zeroes (ie:
dd if=/dev/zero of=bigfile bs=1M count=<almost_all_free_space>; rm bigfile).
Be sure to understand what the above steps means: doing any error can irremediably corrupt your image file. And be sure to have a know-good backup before attempting any operation on your disk image file!*
It’s expected behavior. As you wrote, “after I deleted some files and reduced the used space from 1.9T to 761G” - raw virtual image cannot “collect garbage” automatically and the real space will remain written and allocated even for removed files. Workaround is to perform (double)conversion raw>qcow2(>raw).
More detailed explained here - https://balau82.wordpress.com/2011/05/08/qemu-raw-images-real-size/ and here - https://techpiezo.com/tech-insights/raw-vs-qcow2-disk-images-in-qemu-kvm/