PostgreSQLをext3上とext4上でそれぞれ動かしたときに、insertの速度が違うようだ。特にext4のときに遅い模様。そこで、ext4上のpostgresのpostgresql.confのfsyncをオフにしてみるとinsertの速度が劇的に上がる。
でも、こんなに劇的に上がっていいの?というのが正直な感想で、実はext3のfsyncは実際には呼び出されてもsyncしていないのではないか、ということが気になってくる。
ためしに、ext3とext4でそれぞれに繰り返し書き込みとfsyncを繰り返し行うだけのプログラムを作成して、実行時間を測ってみた。
準備: ローカルのファイルシステム(ext3)にファイルを二つ作成して、片方をext3(ext3_disk)、もう片方をext4でマウント(ext4_disk)する。
dd if=/dev/zero of=ext3_file.dat bs=1M count=10
dd if=/dev/zero of=ext4_file.dat bs=1M count=10
mkfs.ext3 ext3_file.dat
mkfs.ext4 ext4_file.dat
mkdir ext3_disk ext4_disk
mount ext3_file.dat ext3_disk
mount ext4_file.dat ext4_disk
テスト用プログラム: 以下のようなプログラムを実行した。
#include<stdio.h>
#include<stdlib.h>
#include<sys/time.h>
#define REPEAT 10
#define SIZE 1000
int main(int argc, char** argv){
char* buf = "0123456789";
char* names[] = {"ext3", "ext4"};
int i,r, f;
struct timeval start, end, dur;
FILE* files[2];
FILE* ext3 = NULL;
FILE* ext4 = NULL;
ext3 = fopen("ext3_disk/test.dat", "w");
ext4 = fopen("ext4_disk/test.dat", "w");
files[0] = ext3;
files[1] = ext4;
for(f = 0; f<2; f++){
printf("%s: ", names[f]);
fflush(stdout);
gettimeofday(&start, NULL);
for(r = 0; r<REPEAT; r++){
for(i = 0; i<SIZE; i++){
fprintf(files[f], "%s", buf);
int fd = fileno(files[f]); // get fd
fsync(fd);
}
}
gettimeofday(&end, NULL);
timersub(&end, &start, &dur);
printf("%d sec, %lf msecn", dur.tv_sec, dur.tv_usec/1000.0);
}
printf("donen");
fclose(ext3);
fclose(ext4);
}
</pre>
実行結果:
ext3: 0 sec, 20.671000 msec
ext4: 10 sec, 263.353000 msec
done
----------------------------------
この結果を見ると、ext3は一瞬で完了していて、ext4は10秒以上かかっている。ext3はfsyncのタイミングでは実際の同期は行っていなさそうな雰囲気だ。ではext3はいつsyncされるのかというと、5秒ごとルールということだろうか。
データベース屋さんの間ではよく知られた問題なんだろうか?
<script type="text/javascript">
SyntaxHighlighter.all()
</script
</script>