From dc9ef835c55d56fb196757e6b34b4cb66e499fe9 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Tue, 25 Sep 2012 04:31:37 -0700 Subject: [PATCH] Add envflags for MDB config allows setting writemap and some other useful flags --- doc/man/man5/slapd-mdb.5 | 42 ++++++++++++++++++++++ servers/slapd/back-mdb/config.c | 64 ++++++++++++++++++++++++++++++++- servers/slapd/back-mdb/init.c | 2 +- 3 files changed, 106 insertions(+), 2 deletions(-) diff --git a/doc/man/man5/slapd-mdb.5 b/doc/man/man5/slapd-mdb.5 index 1624c7d916..8a35b401cd 100644 --- a/doc/man/man5/slapd-mdb.5 +++ b/doc/man/man5/slapd-mdb.5 @@ -53,6 +53,48 @@ associated indexes live. A separate directory must be specified for each database. The default is .BR LOCALSTATEDIR/openldap\-data . +.TP +\fBenvflags \fR{\fBnosync\fR,\fBnometasync\fR,\fBwritemap\fR,\fBmapasync\fR} +Specify flags for finer-grained control of the MDB library's operation. +.RS +.TP +.B nosync +This is exactly the same as the +.I dbnosync +directive. +.RE +.RS +.TP +.B nometasync +Flush the data on a commit, but skip the sync of the meta page. This mode is +slightly faster than doing a full sync, but can potentially lose the last +committed transaction if the operating system crashes. If both +.I nometasync +and +.I nosync +are set, the +.I nosync +flag takes precedence. +.RE +.RS +.TP +.B writemap +Use a writable memory map instead of just read-only. This speeds up write operations +but makes the database vulnerable to corruption in case any bugs in slapd +cause stray writes into the mmap region. +.RE +.RS +.TP +.B mapasync +When using a writable memory map and performing flushes on each commit, use an +asynchronous flush instead of a synchronous flush (the default). This option +has no effect if +.I writemap +has not been set. It also has no effect if +.I nosync +is set. +.RE + .TP \fBindex \fR{\fI\fR|\fBdefault\fR} [\fBpres\fR,\fBeq\fR,\fBapprox\fR,\fBsub\fR,\fI\fR] Specify the indexes to maintain for the given attribute (or diff --git a/servers/slapd/back-mdb/config.c b/servers/slapd/back-mdb/config.c index fb516a5dc5..8e7ce671d3 100644 --- a/servers/slapd/back-mdb/config.c +++ b/servers/slapd/back-mdb/config.c @@ -34,6 +34,7 @@ enum { MDB_CHKPT = 1, MDB_DIRECTORY, MDB_DBNOSYNC, + MDB_ENVFLAGS, MDB_INDEX, MDB_MAXREADERS, MDB_MAXSIZE, @@ -55,6 +56,10 @@ static ConfigTable mdbcfg[] = { mdb_cf_gen, "( OLcfgDbAt:1.4 NAME 'olcDbNoSync' " "DESC 'Disable synchronous database writes' " "SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL }, + { "envflags", "flags", 2, 0, 0, ARG_MAGIC|MDB_ENVFLAGS, + mdb_cf_gen, "( OLcfgDbAt:12.3 NAME 'olcDbEnvFlags' " + "DESC 'Database environment flags' " + "SYNTAX OMsDirectoryString )", NULL, NULL }, { "index", "attr> <[pres,eq,approx,sub]", 2, 3, 0, ARG_MAGIC|MDB_INDEX, mdb_cf_gen, "( OLcfgDbAt:0.2 NAME 'olcDbIndex' " "DESC 'Attribute index parameters' " @@ -87,13 +92,21 @@ static ConfigOCs mdbocs[] = { "DESC 'MDB backend configuration' " "SUP olcDatabaseConfig " "MUST olcDbDirectory " - "MAY ( olcDbCheckpoint $ " + "MAY ( olcDbCheckpoint $ olcDbEnvFlags " "olcDbNoSync $ olcDbIndex $ olcDbMaxReaders $ olcDbMaxsize $ " "olcDbMode $ olcDbSearchStack ) )", Cft_Database, mdbcfg }, { NULL, 0, NULL } }; +static slap_verbmasks mdb_envflags[] = { + { BER_BVC("nosync"), MDB_NOSYNC }, + { BER_BVC("nometasync"), MDB_NOMETASYNC }, + { BER_BVC("writemap"), MDB_WRITEMAP }, + { BER_BVC("mapasync"), MDB_MAPASYNC }, + { BER_BVNULL, 0 } +}; + /* perform periodic syncs */ static void * mdb_checkpoint( void *ctx, void *arg ) @@ -293,6 +306,13 @@ mdb_cf_gen( ConfigArgs *c ) c->value_int = 1; break; + case MDB_ENVFLAGS: + if ( mdb->mi_dbenv_flags ) { + mask_to_verbs( mdb_envflags, mdb->mi_dbenv_flags, &c->rvalue_vals ); + } + if ( !c->rvalue_vals ) rc = 1; + break; + case MDB_INDEX: mdb_attr_index_unparse( mdb, &c->rvalue_vals ); if ( !c->rvalue_vals ) rc = 1; @@ -349,7 +369,31 @@ mdb_cf_gen( ConfigArgs *c ) break; case MDB_DBNOSYNC: mdb_env_set_flags( mdb->mi_dbenv, MDB_NOSYNC, 0 ); + mdb->mi_dbenv_flags &= ~MDB_NOSYNC; + break; + + case MDB_ENVFLAGS: + if ( c->valx == -1 ) { + int i; + for ( i=0; mdb_envflags[i].mask; i++) { + if ( mdb->mi_dbenv_flags & mdb_envflags[i].mask ) { + /* not all flags are runtime resettable */ + rc = mdb_env_set_flags( mdb->mi_dbenv, mdb_envflags[i].mask, 0 ); + if ( rc ) + break; + mdb->mi_dbenv_flags ^= mdb_envflags[i].mask; + } + } + } else { + int i = verb_to_mask( c->line, mdb_envflags ); + if ( mdb_envflags[i].mask & mdb->mi_dbenv_flags ) { + rc = mdb_env_set_flags( mdb->mi_dbenv, mdb_envflags[i].mask, 0 ); + if ( !rc ) + mdb->mi_dbenv_flags ^= mdb_envflags[i].mask; + } + } break; + case MDB_INDEX: if ( c->valx == -1 ) { int i; @@ -530,6 +574,24 @@ mdb_cf_gen( ConfigArgs *c ) } break; + case MDB_ENVFLAGS: { + int i, j; + for ( i=1; iargc; i++ ) { + j = verb_to_mask( c->argv[i], mdb_envflags ); + if ( mdb_envflags[j].mask ) { + if ( mdb->mi_flags & MDB_IS_OPEN ) + rc = mdb_env_set_flags( mdb->mi_dbenv, mdb_envflags[j].mask, 1 ); + else + rc = 0; + if ( rc ) + break; + else + mdb->mi_dbenv_flags |= mdb_envflags[i].mask; + } + } + } + break; + case MDB_INDEX: rc = mdb_attr_index_config( mdb, c->fname, c->lineno, c->argc - 1, &c->argv[1], &c->reply); diff --git a/servers/slapd/back-mdb/init.c b/servers/slapd/back-mdb/init.c index b757700505..e8d2690e6d 100644 --- a/servers/slapd/back-mdb/init.c +++ b/servers/slapd/back-mdb/init.c @@ -166,7 +166,7 @@ mdb_db_open( BackendDB *be, ConfigReply *cr ) flags = mdb->mi_dbenv_flags; if ( slapMode & SLAP_TOOL_QUICK ) - flags |= MDB_NOSYNC; + flags |= MDB_NOSYNC|MDB_WRITEMAP; if ( slapMode & SLAP_TOOL_READONLY) flags |= MDB_RDONLY; -- 2.39.5