This article has some useful suggestions for
rsync at least:
rsync --sparse works, but causes a huge a mount of unnecessary disk writes. Changing 10 bytes on 50GB long (1GB used) should cause only one or two blocks to be written, this causes 1GB to be written. This is slow, and possible not good for the disks' longevity.
rsync --inplace works, but creates non-sparse files.
You cannot use --sparse and --inplace at the same time :-( this is disallowed by rsync.
rsync: --sparse cannot be used with --inplace
If you use --inplace to update a pre-existing sparse file, the file will remain sparse and only have a small number of blocks written. It's only when rsync --inplace creates a file that it makes it non-sparse.
So the solution is to create a corresponding, correctly-lengthed, empty, sparse file on the target machine for every file on the source machine - if the file isn't yet present on the target machine.
Then rsync --inplace will work as intended, leaving sparse files sparse, and only writing the changed blocks to disk.
So, if I read that correctly, you want to first create an empty sparse file on the target. You can do this with
truncate -s 3G filename
You can then use
rsync --inplace to copy the files over. This should only be necessary once.
The same article suggests using Virtsync which is
a $49 commercial Linux command-line tool for synchronizing the contents of huge files (such as virtual machine disk images and databases).
This might be the best solution if you're willing to pay for it since it seems to be written specifically for this type of situation.