What exactly do you mean by "touching the hash" and "dirty the hash"? $db->sync will not actually write anything unless the hash contents have actually been modified in some way (i.e., there must be some cached buffers in order to "Flush any cached buffers to disk"). You cannot force a write with $db->sync. For example:
$db->sync; # not modified
$hash{foo} = 'bar'; # not modified
$db->sync; # MODIFIED
@hash{qw<one two three>} = 1..3; # not modified
$db->sync; # MODIFIED
delete $hash{two}; # not modified
$db->sync; # MODIFIED
$db->sync; # not modified
Edit (Further thoughts): If you have definitely modified the hash and after a $db->sync the file still appears to be unmodified, you should be checking the return of $db->sync, which unfortunately returns 0 on success; if it returns -1, it failed, and a more detailed error is available in $!. 1 is also an error: "1 generally (but not always) means that the key specified did not exist in the database". Finally, remember by default stat and friends operate with whole-second resolution, so if you were to run my above code and use the file's mtime as your test, probably all lines would appear not modified. See stat (especially the caveats!), and consider using other metrics such as file size and Digest::MD5 checksum, but beware the latter may negatively impact performance if the file is large or checked very frequently.
use strict; use warnings; omitted for brevity.