fsync is slow on later kernels with ext4 filesystms

Asked by Caron Wills on 2018-08-01

So this is a simple one, if I run the following code (see below) on Ubuntu 18.04 (4.15.0-29-generic ) and against Ubuntu 16.04 ( 4.4.0-87-generic) I get two different results ; The question is why? It seems that fsync may be broken in the latest kernel and may well be broken as early as 4.10 ? This has huge implications around performance sensitive applications like mysql.

It also so worth noting that I'm running this against an ext4 filesystem with the following mount options
rw,noatime,nodiratime,nobarrier,data=journal

4.4.0-87-generic - # time ./fsync
real 0m7.537s <-----
user 0m0.000s
sys 0m1.060s <-----

4.15.0-29-generic - # time ./fsync
real 1m38.299s <-----
user 0m0.013s
sys 0m0.893s <-----

Linux buntu-1804 4.15.0-29-generic

no sync() seconds:0.024438 writes per second:0.000000
   sync() seconds:1.705764 writes per second:0.000000

real 3m6.475s
user 0m0.006s
sys 0m1.725s

Linux ubuntu 4.4.0-87-generic

no sync() seconds:0.012887 writes per second:0.000001
   sync() seconds:0.736563 writes per second:0.000000

real 0m8.945s
user 0m0.016s
sys 0m0.732s

#!/usr/bin/python
import os, sys, mmap
# Open a file
fd = os.open( "/a/testfile", os.O_RDWR|os.O_CREAT|os.O_DIRECT )
m = mmap.mmap(-1, 512)
for i in range (1,10000):
   os.lseek(fd,os.SEEK_SET,0)
   m[1] = "1"
   os.write(fd, m)
   os.fsync(fd)
# Close opened file
os.close( fd )

#define _GNU_SOURCE
#include <stdio.h>
#include <fcntl.h>
#include <time.h>
#include <unistd.h>

void withSync() {
    int f = open( "/a/t8" , O_RDWR | O_CREAT |O_DIRECT );
    lseek (f, 0, SEEK_SET );
    int records = 10*1000;
    clock_t ustart = clock();
    for(int i = 0; i < records; i++) {
        write(f, "012345678901234567890123456789" , 30);
        fsync(f);
    }
    clock_t uend = clock();
    close (f);
    printf(" sync() seconds:%lf writes per second:%lf\n", ((double)(uend-ustart))/(CLOCKS_PER_SEC), ((double)records)/((double)(uend-ustart))/(CLOCKS_PER_SEC));
}

void withoutSync() {
    int f = open( "/a/t10" , O_RDWR | O_CREAT | O_DIRECT );
    lseek (f, 0, SEEK_SET );
    int records = 10*1000;
    clock_t ustart = clock();
    for(int i = 0; i < records; i++) {
        write(f, "012345678901234567890123456789" , 30 );
    }
    clock_t uend = clock();
    close (f);
    printf("no sync() seconds:%lf writes per second:%lf \n", ((double)(uend-ustart))/(CLOCKS_PER_SEC), ((double)records)/((double)(uend-ustart))/(CLOCKS_PER_SEC));
}

int main(int argc, const char * argv[])
{
    withoutSync();
    withSync();
    return 0;
}

Linux buntu-1804 4.15.0-29-generic

no sync() seconds:0.024438 writes per second:0.000000
   sync() seconds:1.705764 writes per second:0.000000

real 3m6.475s
user 0m0.006s
sys 0m1.725s

Linux ubuntu 4.4.0-87-generic

no sync() seconds:0.012887 writes per second:0.000001
   sync() seconds:0.736563 writes per second:0.000000

real 0m8.945s
user 0m0.016s
sys 0m0.732s

Question information

Language:
English Edit question
Status:
Answered
For:
Ubuntu Edit question
Assignee:
No assignee Edit question
Last query:
2018-08-01
Last reply:
2018-08-02

I suggest you report a bug

Caron Wills (cwills) said : #2

How do I go about raising a bug for this?

Caron Wills (cwills) said : #3

Bug logged against this issue.

Can you help with this problem?

Provide an answer of your own, or ask Caron Wills for more information if necessary.

To post a message you must log in.