На самом деле физическое копирование занимает столько же времени. Но драйвер файловой системы ext4 close() ожидает, пока данные действительно не будут записаны, когда операция выполняется на существующем i-узле, и не ожидает операции записи, если она выполняется на новом узле. Я провел несколько экспериментов и понял, что это особенность ext4. Я не видел такой разницы с копированием на btrfs, zfs, ext3, ext.
Как я могу сказать, что закрытие - это трудоемкая операция? strace предоставляет информацию:
$ strace -tt -T cp bigfile newfile
...
14:36:41.985437 open("bigfile", O_RDONLY) = 3 <0.000009>
14:36:41.985466 fstat(3, {st_mode=S_IFREG|0664, st_size=647608649, ...}) = 0 <0.000007>
14:36:41.985495 open("newfile", O_WRONLY|O_CREAT|O_EXCL, 0664) = 4 <0.000086>
14:36:41.985602 fstat(4, {st_mode=S_IFREG|0664, st_size=0, ...}) = 0 <0.000007>
14:36:41.985633 fadvise64(3, 0, 0, POSIX_FADV_SEQUENTIAL) = 0 <0.000008>
... a lot of reads and writes
14:36:43.584223 close(4) = 0 <0.000009>
14:36:43.584248 close(3) = 0 <0.000008>
...
$ strace -tt -T cp bigfile existingfile
...
14:36:52.393034 open("bigfile", O_RDONLY) = 3 <0.000010>
14:36:52.393071 fstat(3, {st_mode=S_IFREG|0664, st_size=647608649, ...}) = 0 <0.000009>
14:36:52.393104 open("existingfile", O_WRONLY|O_TRUNC) = 4 <0.097058>
14:36:52.490211 fstat(4, {st_mode=S_IFREG|0664, st_size=0, ...}) = 0 <0.000007>
14:36:52.490278 fadvise64(3, 0, 0, POSIX_FADV_SEQUENTIAL) = 0 <0.000009>
... a lot of reads and writes
14:36:54.047408 close(4) = 0 <5.346015>
14:36:59.393466 close(3) = 0 <0.000011>
...
Обратите внимание, что close(4) занимает более 5 секунд, тогда как в случае копирования в существующий файл и непосредственно при создании нового файла.
Я запускаю iostat, чтобы проверить, что делает система. Чтение bigfile было выполнено перед тестом, чтобы избежать эффекта кэширования файловой системы.
# iostat sda 1 100
Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
sda 0.00 0.00 0.00 0 0
sda 0.00 0.00 0.00 0 0
--------------- copy to a new file starts here -----------------------
sda 24.00 0.00 8340.00 0 8340
sda 174.00 8.00 86596.00 8 86596
sda 170.00 0.00 86020.00 0 86020
--------------- copy to a new file finishes here ---------------------
sda 177.00 4.00 90112.00 4 90112
sda 176.00 4.00 89600.00 4 89600
sda 166.00 0.00 84992.00 0 84992
sda 161.00 4.00 81920.00 4 81920
sda 157.00 0.00 78888.00 0 78888
sda 52.00 0.00 26224.00 0 26224
sda 0.00 0.00 0.00 0 0
sda 0.00 0.00 0.00 0 0
sda 0.00 0.00 0.00 0 0
--------------- copy to the existing file starts here ----------------
sda 12.00 0.00 4128.00 0 4128
sda 172.00 4.00 87040.00 4 87040
sda 180.00 4.00 91648.00 4 91648
sda 175.00 0.00 89600.00 0 89600
sda 173.00 4.00 88064.00 4 88064
sda 168.00 4.00 83532.00 4 83532
sda 159.00 0.00 81408.00 0 81408
sda 181.00 4.00 92160.00 4 92160
sda 30.00 0.00 14960.00 0 14960
--------------- copy to the existing file finishes here --------------
sda 0.00 0.00 0.00 0 0
sda 3.00 0.00 28.00 0 28
Обратите внимание, что копирование в новый файл заканчивается до записи данных, а операция записи продолжается, хотя cp выполняется с точки зрения пользователя.