Set up MySQL replication to have the two servers in sync.
For the flat files, do an initial
tar zcf - mydirs/ | ssh user@remotehost 'tar zxpf - -C mydest/dir'
and then use rsync to copy over changes in an efficient manner on a regular schedule (at least once a day, but can be more often). It's also certainly possible to use rsync for the initial copy, but I find tar or cpio quicker.
Drop the DNS TTLs to ~15 minutes.
At the time of the switch over, put up a maintenance page and then:
- stop mail services
- stop MySQL replication
- point DNS records to the new server (which also has the maintenance text up)
- do a final rsync of the files
- restart services
- take the maintenance page down
- wait a few days and then raise your DNS TTLs to where they were once things are good
This way you always have two sets of files, and you can test things on the new server while still having the old one untouched (besides a MySQL tweak).
If anything strange goes south with the new server you can always switch back to the old one quite quickly (~15 minutes because of the TTLs).