After adding the preload
package, my applications seem to speed up but if I copy a large file, the file cache grows by more than double the size of the file.
By transferring a single 3-4 GB virtualbox image or video file to an external drive, this huge cache seems to remove all the preloaded applications from memory, leading to increased load times and general performance drops.
Is there a way to copy large, multi-gigabyte files without caching them (i.e. bypassing the file cache)? Or a way to whitelist or blacklist specific folders from being cached?
There is the
nocache
utility, which can prepended to a command likeionice
andnice
. It works by preloading a library which addsposix_fadvise
with thePOSIX_FADV_DONTNEED
flag to any open calls.In simple terms, it advises the kernel that caching is not needed for that particular file; the kernel will then normally not cache the file. See here for the technical details.
It does wonders for any huge copy jobs, e. g. if you want to backup a multi terabyte disk in the background with the least possible impact on you running system, you can do something along
nice -n19 ionice -c3 nocache cp -a /vol /vol2
.A package will be available in Ubuntu 13.10 and up. If you are on a previous release you can either install the 13.10 package or opt for this 12.04 backport by François Marier.
For single large files, use
dd
with direct I/O to bypass the file cache:If you want to transfer one (or a few) large multi-gigabyte files, it's easy to do with
dd
:direct
flags telldd
to use the kernel's direct I/O option (O_DIRECT
) while reading and writing, thus completely bypassing the file cache.bs
blocksize option must be set to a reasonably large value since to minimize the number of physical disk operationsdd
must perform, since reads/writes are no longer cached and too many small direct operations can result in a serious slowdown.4M
).For multiple/recursive directory copies, unfortunately, there are no easily available tools; the usual
cp
,etc do not support direct I/O./e iflags & oflags changed to the correct iflag & oflag
You can copy a directory recursively with
dd
usingfind
andmkdir
We need to workaround two problems:
dd
doesn't know what to do with directoriesdd
can only copy one file at a timeFirst let's define input and output directories:
Now let's
cd
into the source directory sofind
will report relative directories we can easily manipulate:Duplicate the directory tree from
$SOURCE
to$TARGET
Duplicate files from
$SOURCE
to$TARGET
omitting write cache (but utilising read cache!)Please note that this won't preserve file modification times, ownership and other attributes.