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>
※コメント投稿者のブログIDはブログ作成者のみに通知されます