]> git.sur5r.net Git - openldap/commitdiff
Add envflags for MDB config
authorHoward Chu <hyc@openldap.org>
Tue, 25 Sep 2012 11:31:37 +0000 (04:31 -0700)
committerHoward Chu <hyc@openldap.org>
Tue, 25 Sep 2012 11:31:37 +0000 (04:31 -0700)
allows setting writemap and some other useful flags

doc/man/man5/slapd-mdb.5
servers/slapd/back-mdb/config.c
servers/slapd/back-mdb/init.c

index 1624c7d91661956d193bc058eb1951416a70ffce..8a35b401cdf33ca2b09f51bd9707544544121fa9 100644 (file)
@@ -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<attrlist>\fR|\fBdefault\fR} [\fBpres\fR,\fBeq\fR,\fBapprox\fR,\fBsub\fR,\fI<special>\fR]
 Specify the indexes to maintain for the given attribute (or
index fb516a5dc554fac6e4a0e2d204c81b88125571e0..8e7ce671d30cbf4573bda6724f424090287c452e 100644 (file)
@@ -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; i<c->argc; 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);
index b757700505a794f341275c432cc891aed4219a37..e8d2690e6d6eab9f073cd00c8ab225e1f9d22b32 100644 (file)
@@ -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;