Use O_DSYNC on metafd.

Use sync writes in mtest.
vmware
Howard Chu 13 years ago
parent 3e1c72a08e
commit 88a5f35c43
  1. 57
      libraries/libmdb/mdb.c
  2. 2
      libraries/libmdb/midl.h
  3. 2
      libraries/libmdb/mtest.c

@ -145,6 +145,7 @@ typedef struct MDB_page { /* represents a page of storage */
#define P_OVERFLOW 0x04 /* overflow page */ #define P_OVERFLOW 0x04 /* overflow page */
#define P_META 0x08 /* meta page */ #define P_META 0x08 /* meta page */
#define P_DIRTY 0x10 /* dirty page */ #define P_DIRTY 0x10 /* dirty page */
#define P_LEAF2 0x20 /* DB with small, fixed size keys and no data */
uint32_t mp_flags; uint32_t mp_flags;
#define mp_lower mp_pb.pb.pb_lower #define mp_lower mp_pb.pb.pb_lower
#define mp_upper mp_pb.pb.pb_upper #define mp_upper mp_pb.pb.pb_upper
@ -155,6 +156,10 @@ typedef struct MDB_page { /* represents a page of storage */
indx_t pb_upper; /* upper bound of free space */ indx_t pb_upper; /* upper bound of free space */
} pb; } pb;
uint32_t pb_pages; /* number of overflow pages */ uint32_t pb_pages; /* number of overflow pages */
struct {
indx_t pb_ksize; /* on a LEAF2 page */
indx_t pb_numkeys;
} pb2;
} mp_pb; } mp_pb;
indx_t mp_ptrs[1]; /* dynamic size */ indx_t mp_ptrs[1]; /* dynamic size */
} MDB_page; } MDB_page;
@ -308,7 +313,10 @@ typedef struct MDB_xcursor {
struct MDB_env { struct MDB_env {
int me_fd; int me_fd;
int me_lfd; int me_lfd;
uint32_t me_flags; int me_mfd; /* just for writing the meta pages */
uint16_t me_flags;
uint16_t me_db_toggle;
unsigned int me_psize;
unsigned int me_maxreaders; unsigned int me_maxreaders;
unsigned int me_numdbs; unsigned int me_numdbs;
unsigned int me_maxdbs; unsigned int me_maxdbs;
@ -320,8 +328,6 @@ struct MDB_env {
MDB_txn *me_txn; /* current write transaction */ MDB_txn *me_txn; /* current write transaction */
size_t me_mapsize; size_t me_mapsize;
off_t me_size; /* current file size */ off_t me_size; /* current file size */
unsigned int me_psize;
int me_db_toggle;
MDB_dbx *me_dbxs; /* array */ MDB_dbx *me_dbxs; /* array */
MDB_db *me_dbs[2]; MDB_db *me_dbs[2];
MDB_oldpages *me_pghead; MDB_oldpages *me_pghead;
@ -614,7 +620,7 @@ mdb_env_sync(MDB_env *env, int force)
{ {
int rc = 0; int rc = 0;
if (force || !F_ISSET(env->me_flags, MDB_NOSYNC)) { if (force || !F_ISSET(env->me_flags, MDB_NOSYNC)) {
if (fsync(env->me_fd)) if (fdatasync(env->me_fd))
rc = errno; rc = errno;
} }
return rc; return rc;
@ -914,8 +920,7 @@ mdb_txn_commit(MDB_txn *txn)
} }
if ((n = mdb_env_sync(env, 0)) != 0 || if ((n = mdb_env_sync(env, 0)) != 0 ||
(n = mdb_env_write_meta(txn)) != MDB_SUCCESS || (n = mdb_env_write_meta(txn)) != MDB_SUCCESS) {
(n = mdb_env_sync(env, 0)) != 0) {
mdb_txn_abort(txn); mdb_txn_abort(txn);
return n; return n;
} }
@ -1069,8 +1074,7 @@ mdb_env_write_meta(MDB_txn *txn)
off += env->me_psize; off += env->me_psize;
off += PAGEHDRSZ; off += PAGEHDRSZ;
lseek(env->me_fd, off, SEEK_SET); rc = pwrite(env->me_fd, ptr, len, off);
rc = write(env->me_fd, ptr, len);
if (rc != len) { if (rc != len) {
DPRINTF("write failed, disk error?"); DPRINTF("write failed, disk error?");
return errno; return errno;
@ -1111,6 +1115,7 @@ mdb_env_create(MDB_env **env)
e->me_maxdbs = 2; e->me_maxdbs = 2;
e->me_fd = -1; e->me_fd = -1;
e->me_lfd = -1; e->me_lfd = -1;
e->me_mfd = -1;
*env = e; *env = e;
return MDB_SUCCESS; return MDB_SUCCESS;
} }
@ -1288,7 +1293,10 @@ mdb_env_setup_locks(MDB_env *env, char *lpath, int mode, int *excl)
pthread_mutexattr_t mattr; pthread_mutexattr_t mattr;
pthread_mutexattr_init(&mattr); pthread_mutexattr_init(&mattr);
pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED); rc = pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED);
if (rc) {
goto fail;
}
pthread_mutex_init(&env->me_txns->mti_mutex, &mattr); pthread_mutex_init(&env->me_txns->mti_mutex, &mattr);
pthread_mutex_init(&env->me_txns->mti_wmutex, &mattr); pthread_mutex_init(&env->me_txns->mti_wmutex, &mattr);
env->me_txns->mti_version = MDB_VERSION; env->me_txns->mti_version = MDB_VERSION;
@ -1317,6 +1325,7 @@ mdb_env_setup_locks(MDB_env *env, char *lpath, int mode, int *excl)
fail: fail:
close(env->me_lfd); close(env->me_lfd);
env->me_lfd = -1;
return rc; return rc;
} }
@ -1346,13 +1355,20 @@ mdb_env_open(MDB_env *env, const char *path, unsigned int flags, mode_t mode)
else else
oflags = O_RDWR | O_CREAT; oflags = O_RDWR | O_CREAT;
if ((env->me_fd = open(dpath, oflags, mode)) == -1) if ((env->me_fd = open(dpath, oflags, mode)) == -1) {
return errno; rc = errno;
goto leave;
}
if ((rc = mdb_env_open2(env, flags)) == MDB_SUCCESS) {
/* synchronous fd for meta writes */
if (!(flags & (MDB_RDONLY|MDB_NOSYNC)))
oflags |= O_DSYNC;
if ((env->me_mfd = open(dpath, oflags, mode)) == -1) {
rc = errno;
goto leave;
}
if ((rc = mdb_env_open2(env, flags)) != MDB_SUCCESS) {
close(env->me_fd);
env->me_fd = -1;
} else {
env->me_path = strdup(path); env->me_path = strdup(path);
DPRINTF("opened dbenv %p", (void *) env); DPRINTF("opened dbenv %p", (void *) env);
pthread_key_create(&env->me_txkey, mdb_env_reader_dest); pthread_key_create(&env->me_txkey, mdb_env_reader_dest);
@ -1365,6 +1381,16 @@ mdb_env_open(MDB_env *env, const char *path, unsigned int flags, mode_t mode)
} }
leave: leave:
if (rc) {
if (env->me_fd >= 0) {
close(env->me_fd);
env->me_fd = -1;
}
if (env->me_lfd >= 0) {
close(env->me_lfd);
env->me_lfd = -1;
}
}
free(lpath); free(lpath);
return rc; return rc;
} }
@ -1385,6 +1411,7 @@ mdb_env_close(MDB_env *env)
if (env->me_map) { if (env->me_map) {
munmap(env->me_map, env->me_mapsize); munmap(env->me_map, env->me_mapsize);
} }
close(env->me_mfd);
close(env->me_fd); close(env->me_fd);
if (env->me_txns) { if (env->me_txns) {
pid_t pid = getpid(); pid_t pid = getpid();

@ -17,7 +17,7 @@
#ifndef _MDB_MIDL_H_ #ifndef _MDB_MIDL_H_
#define _MDB_MIDL_H_ #define _MDB_MIDL_H_
#define AC_MEMCPY(dst,src,size) memcpy(dst,src,size) #define AC_MEMCPY(dst,src,size) memmove(dst,src,size)
#define ID unsigned long #define ID unsigned long
#define NOID ((ID)~0) #define NOID ((ID)~0)

@ -41,7 +41,7 @@ int main(int argc,char * argv[])
rc = mdb_env_create(&env); rc = mdb_env_create(&env);
rc = mdb_env_set_mapsize(env, 10485760); rc = mdb_env_set_mapsize(env, 10485760);
rc = mdb_env_open(env, "./testdb", MDB_FIXEDMAP|MDB_NOSYNC, 0664); rc = mdb_env_open(env, "./testdb", MDB_FIXEDMAP /*|MDB_NOSYNC*/, 0664);
rc = mdb_txn_begin(env, 0, &txn); rc = mdb_txn_begin(env, 0, &txn);
rc = mdb_open(txn, NULL, 0, &dbi); rc = mdb_open(txn, NULL, 0, &dbi);

Loading…
Cancel
Save