原文链接:
http://www.cnblogs.com/promise6522/archive/2012/05/27/2520028.html
写的很棒也很详细. 摘要:
fsync需要sync文件修改和 metadata; fdatasync则只在必要的时候才sync metadata, 可以节省一次文件sync操作.
berkeley db通过预先设置 log文件大小, 从而保证fdatasync不会去sync metadata.
这里简单的列一下对应的bdb 代码:
os/os_fsync.c:
__os_fsync() if (DB_GLOBAL(j_fsync) != NULL) ret = DB_GLOBAL(j_fsync)(fhp->fd); //用户自定义sync函数 else { #if defined(F_FULLFSYNC) // MAC OS X RETRY_CHK((fcntl(fhp->fd, F_FULLFSYNC, 0)), ret); if (ret == ENOTSUP) RETRY_CHK((fsync(fhp->fd)), ret); #elif defined(HAVE_QNX) // QNX实时OS ret = __qnx_fsync(fhp); #elif defined(HAVE_FDATASYNC) // 优先使用fdatasync RETRY_CHK((fdatasync(fhp->fd)), ret); #else RETRY_CHK((fsync(fhp->fd)), ret); #endif }
log/log_put.c:
__log_write() #ifdef HAVE_FILESYSTEM_NOTZERO if (lp->w_off == 0 && !__os_fs_notzero()) { #else if (lp->w_off == 0) { // lp->w_off为当前log文件的write offset #endif // lp->w_off为0, 标识第一次写 此log文件 (void)__db_file_extend(env, dblp->lfhp, lp->log_size); if (F_ISSET(dblp, DBLOG_ZERO)) (void)__db_zero_extend(env, dblp->lfhp, 0, lp->log_size/lp->buffer_size, lp->buffer_size); }
env/env_file.c:
__db_file_extend() // size为log文件大小, 写文件的最后一个byte为0 buf = '\0'; pages = (db_pgno_t)((size - sizeof(buf)) / MEGABYTE); relative = (u_int32_t)((size - sizeof(buf)) % MEGABYTE); if ((ret = __os_seek(env, fhp, pages, MEGABYTE, relative)) == 0) ret = __os_write(env, fhp, &buf, sizeof(buf), &nw);