Re: fsync(2) weirdness

Bernhard Heidegger (bheide@hyperwave.com)
Fri, 3 Oct 1997 10:32:25 +0200 (MET DST)


>>>>> ">" == Scott Laird <laird@pacificrim.net> writes:

>> In message <199710030050.UAA00411@gringo.telsur.cl>, Gordon Oliver writes:
>>
>> you didn't say what fs it is on... prolly ext2?

>> Right.

>> ... could you turn on kernel profiling and send the top few functions
>> while this is running. Unless it is doing a lot of I/O the 100 seconds
>> still seems way long... (hmm. 1.4G/512= ~2.8M... 2.8 million buffer
>> lookups... ouch) Is that file full of holes? or is it completely full
>> of data?

We have a similar problem: big file (around 300MB); sometime it takes up to
15 seconds to fsync() the file (according to strace with timestamps).

>> I'll make a profiling run tomorrow, unless someone posts a solution
>> before then. The file shouldn't have any holes. Yes, it has 1.4 GB
>> worth of data. I can see why 2.8 million buffer lookups would take
>> time...

>> If you have access to the source try changing the way it does things.
>> you can:
>> 1) use O_SYNC on the file, which does what you need.

Then every write "hangs" until the data is on the disk, right?
We have a sort of transactions and we sync after 30 seconds because we
thought it would perform better (maybe we should test O_SYNC...)

>> 2) use sync() to sync the entire disk... which will mostly
>> do what you want, but on busy systems will do a whole lot
>> more... since it checks buffers in memory, it may actually
>> take quite a lot less time...
>>
>> anybody else have better ideas... (flame me if I'm totally off base)

>> I don't have the source (it's a commercial database server). I'm
>> really tempted to map all of the fsync() calls to sync() -- I can't
>> see how that could slow me down much, since the database is the only
>> noteworthy process on this system.

>> What's the easiest way to force a sync? LD_PRELOAD a libc with
>> fsync() munged? Or should I just drop fsync clean out of ext2? It'll
>> fall back to sync, right? Would this work?

I did it in the following way:
------------------------------ sync.c --------------------------------
int sync(void);
int fsync(int fd)
{
return sync();
}
------------------------------ sync.c --------------------------------

compiled as a shared lib (sync.so) and preload it:
#!/bin/sh
export LD_PRELOAD=/home/.../lib/sync.so
exec /path/to/original/software

With this fsync "implementation" it was better, but sometimes took around
5 seconds to complete....

The best result I got with:
int fsync(int);
int fsync(int i)
{
return 0;
}
but that's another story ;-)

Bernhard

get my pgp public key by 'finger bheide@iicm.tu-graz.ac.at'
-----------------------------------------------------------------------------
Bernhard Heidegger bheide@hyperwave.com
Hyperwave Software Research & Development
Schloegelgasse 9/1, A-8010 Graz
Voice: ++43/316/820918-25 Fax: ++43/316/820918-99
-----------------------------------------------------------------------------