Commit 35655c05 authored by Kurt Zeilenga's avatar Kurt Zeilenga
Browse files

Reimplement LDBM_SYNC/LDBM_NOSYNC code (dbnosync).

Old code applied sync flags to store(), however supported DBMs
require such flags to be specified during open().  The new
code now applies flags in ldbm_cache_open (which calls ldbm_open).
ldbm_cache_close() now calls ldbm_sync().  This will force
a updating of on-disk contents after each LDAP operation.
The old code either failed to sync the on-disk contents until
close or synced on every store.   Per LDBM operation syncing
*should* be safe enough... real data safety requires transactions.
Removed nosync option from BDB2 as it is not compatible with
txn support.
Also added code to disable DBM level locking as slapd is only
process acessing the databases (dbnolocking).
parent 4acaa64c
......@@ -387,10 +387,13 @@ Specify the size in bytes of the in-memory cache associated
with each open index file. If not supported by the underlying database
method, this option is ignored without comment. The default is 100000 bytes.
.TP
.B dbcachenowsync
Specify that database writes should not be immediately synchronized
with in memory changes. Enabling this option may improve performance
at the expense of data security.
.B dbnolocking
Specify that no database locking should be performed.
Enabling this option may improve performance at the expense of data security.
.B dbnosync
Specify that on-disk database contents should not be immediately
synchronized with in memory changes. Enabling this option may improve
performance at the expense of data security.
.TP
.B directory <directory>
Specify the directory where the LDBM files containing the database and
......
......@@ -15,11 +15,11 @@
#include <ldap_cdefs.h>
#ifdef LDBM_USE_DBBTREE
#if defined( LDBM_USE_DBBTREE ) || defined( LDBM_USE_DBHASH )
/*****************************************************************
* *
* use berkeley db btree package *
* use berkeley db btree or hash package *
* *
*****************************************************************/
......@@ -51,8 +51,6 @@ typedef DBT Datum;
typedef DB *LDBM;
#define DB_TYPE DB_BTREE
/* for ldbm_open */
#ifdef HAVE_BERKELEY_DB2
typedef DBC LDBMCursor;
......@@ -77,77 +75,25 @@ typedef int LDBMCursor;
LDAP_END_DECL
# define LDBM_FAST 0
#define LDBM_SUFFIX ".dbb"
#define LDBM_ORDERED 1
/* for ldbm_open */
#define LDBM_NOSYNC 0
#define LDBM_SYNC 0
#define LDBM_LOCKING 0
#define LDBM_NOLOCKING 0
/* for ldbm_insert */
#define LDBM_INSERT R_NOOVERWRITE
#define LDBM_REPLACE 0
#define LDBM_SYNC 0x80000000
#elif defined( LDBM_USE_DBHASH )
/*****************************************************************
* *
* use berkeley db hash package *
* *
*****************************************************************/
#include <sys/types.h>
#include <limits.h>
#include <fcntl.h>
#ifdef HAVE_DB_185_H
# include <db_185.h>
#else
# ifdef HAVE_DB1_DB_H
# include <db1/db.h>
# else
# include <db.h>
# endif
# ifdef LDBM_USE_DB2
# define R_NOOVERWRITE DB_NOOVERWRITE
# define DEFAULT_DB_PAGE_SIZE 1024
# endif
#endif
LDAP_BEGIN_DECL
typedef DBT Datum;
#define dsize size
#define dptr data
typedef DB *LDBM;
#define DB_TYPE DB_HASH
/* for ldbm_open */
#ifdef LDBM_USE_DB2
typedef DBC LDBMCursor;
# define LDBM_READER DB_RDONLY
# define LDBM_WRITER 0x00000 /* hopefully */
# define LDBM_WRCREAT (DB_NOMMAP|DB_CREATE|DB_THREAD)
# define LDBM_NEWDB (DB_TRUNCATE|DB_CREATE|DB_THREAD)
#ifdef LDBM_USE_DBBTREE
# define LDBM_ORDERED 1
# define LDBM_SUFFIX ".dbb"
# define DB_TYPE DB_BTREE
#else
typedef int LDBMCursor;
# define LDBM_READER O_RDONLY
# define LDBM_WRITER O_RDWR
# define LDBM_WRCREAT (O_RDWR|O_CREAT)
# define LDBM_NEWDB (O_RDWR|O_TRUNC|O_CREAT)
# define LDBM_FAST 0
# define LDBM_SUFFIX ".dbh"
# define DB_TYPE DB_HASH
#endif
LDAP_END_DECL
#define LDBM_SUFFIX ".dbh"
/* for ldbm_insert */
#define LDBM_INSERT R_NOOVERWRITE
#define LDBM_REPLACE 0
#define LDBM_SYNC 0x80000000
#elif defined( HAVE_GDBM )
/*****************************************************************
......@@ -173,14 +119,29 @@ LDAP_END_DECL
#define LDBM_WRITER GDBM_WRITER
#define LDBM_WRCREAT GDBM_WRCREAT
#define LDBM_NEWDB GDBM_NEWDB
#define LDBM_FAST GDBM_FAST
#ifdef GDBM_FAST
#define LDBM_NOSYNC GDBM_FAST
#else
#define LDBM_NOSYNC 0
#endif
#ifdef GDBM_SYNC
#define LDBM_SYNC GDBM_SYNC
#else
#define LDBM_SYNC 0
#endif
#define LDBM_LOCKING 0
#ifdef GDBM_NOLOCK
#define LDBM_NOLOCKING GDBM_NOLOCK
#endif
#define LDBM_SUFFIX ".gdbm"
/* for ldbm_insert */
#define LDBM_INSERT GDBM_INSERT
#define LDBM_REPLACE GDBM_REPLACE
#define LDBM_SYNC 0x80000000
#elif defined( HAVE_MDBM )
......@@ -209,15 +170,17 @@ LDAP_END_DECL
#define LDBM_WRITER O_RDWR
#define LDBM_WRCREAT (O_RDWR|O_CREAT)
#define LDBM_NEWDB (O_RDWR|O_TRUNC|O_CREAT)
#define LDBM_FAST 0
#define LDBM_SYNC 0
#define LDBM_NOSYNC 0
#define LDBM_LOCKING 0
#define LDBM_NOLOCKING 0
#define LDBM_SUFFIX ".mdbm"
/* for ldbm_insert */
#define LDBM_INSERT MDBM_INSERT
#define LDBM_REPLACE MDBM_REPLACE
#define LDBM_SYNC 0x80000000
#elif defined( HAVE_NDBM )
......@@ -246,14 +209,17 @@ LDAP_END_DECL
#define LDBM_WRITER O_WRONLY
#define LDBM_WRCREAT (O_RDWR|O_CREAT)
#define LDBM_NEWDB (O_RDWR|O_TRUNC|O_CREAT)
#define LDBM_FAST 0
#define LDBM_NOSYNC 0
#define LDBM_SYNC 0
#define LDBM_NOLOCK 0
#define LDBM_SYNC 0
#define LDBM_SUFFIX ".ndbm"
/* for ldbm_insert */
#define LDBM_INSERT DBM_INSERT
#define LDBM_REPLACE DBM_REPLACE
#define LDBM_SYNC 0
#endif
......
......@@ -192,11 +192,9 @@ struct ldbminfo {
struct cache li_cache;
Avlnode *li_attrs;
int li_dbcachesize;
int li_dbcachewsync;
/* a list of all files of the database */
BDB2_TXN_HEAD li_txn_head;
};
......
......@@ -163,10 +163,6 @@ bdb2i_back_db_config_internal(
if ( li->li_dbcachesize < DEFAULT_DBCACHE_SIZE )
li->li_dbcachesize = DEFAULT_DBCACHE_SIZE;
/* no write sync */
} else if ( strcasecmp( argv[0], "dbcachenowsync" ) == 0 ) {
li->li_dbcachewsync = 0;
/* anything else */
} else {
fprintf( stderr,
......
......@@ -43,8 +43,6 @@ bdb2i_dn2id_add(
data.dsize = sizeof(ID);
flags = LDBM_INSERT;
if ( li->li_dbcachewsync ) flags |= LDBM_SYNC;
rc = bdb2i_cache_store( db, key, data, flags );
free( key.dptr );
......
......@@ -45,7 +45,6 @@ bdb2i_id2entry_add( BackendDB *be, Entry *e )
/* store it */
flags = LDBM_REPLACE;
if ( li->li_dbcachewsync ) flags |= LDBM_SYNC;
rc = bdb2i_cache_store( db, key, data, flags );
ldap_pvt_thread_mutex_unlock( &entry2str_mutex );
......
......@@ -214,7 +214,6 @@ idl_store(
#endif
flags = LDBM_REPLACE;
if( li->li_dbcachewsync ) flags |= LDBM_SYNC;
rc = bdb2i_cache_store( db, key, data, flags );
/* Debug( LDAP_DEBUG_TRACE, "<= idl_store %d\n", rc, 0, 0 ); */
......
......@@ -169,9 +169,6 @@ bdb2i_back_db_init_internal(
/* default database cache size */
li->li_dbcachesize = DEFAULT_DBCACHE_SIZE;
/* default cache mode is sync on write */
li->li_dbcachewsync = 1;
/* default file creation mode */
li->li_mode = DEFAULT_MODE;
......
......@@ -42,8 +42,6 @@ int bdb2_tool_entry_open(
flags = LDBM_READER;
}
li->li_dbcachewsync = 0;
if ( (id2entry = bdb2i_cache_open( be, "id2entry", BDB2_SUFFIX, flags ))
== NULL ) {
Debug( LDAP_DEBUG_ANY, "Could not open/create id2entry" BDB2_SUFFIX "\n",
......@@ -63,7 +61,6 @@ int bdb2_tool_entry_close(
assert( id2entry != NULL );
bdb2i_cache_close( be, id2entry );
li->li_dbcachewsync = 1;
id2entry = NULL;
return 0;
......
......@@ -481,8 +481,6 @@ bdb2i_put_nextid( BackendDB *be, ID id )
data.size = sizeof( buf );
flags = LDBM_REPLACE;
if ( li->li_dbcachewsync ) flags |= LDBM_SYNC;
if (( rc = bdb2i_db_store( head->nextidFile, key, data, flags )) != 0 ) {
Debug( LDAP_DEBUG_ANY, "next_id_write(%ld): store failed (%d)\n",
id, rc, 0 );
......@@ -522,7 +520,7 @@ bdb2i_db_store( LDBM ldbm, Datum key, Datum data, int flags )
{
int rc;
rc = (*ldbm->put)( ldbm, txnid, &key, &data, flags & ~LDBM_SYNC );
rc = (*ldbm->put)( ldbm, txnid, &key, &data, flags );
rc = (-1 ) * rc;
if ( txnid != NULL ) {
......
......@@ -138,8 +138,9 @@ struct ldbminfo {
char *li_directory;
Cache li_cache;
Avlnode *li_attrs;
int li_dblocking; /* lock databases */
int li_dbwritesync; /* write sync */
int li_dbcachesize;
int li_dbcachewsync;
DBCache li_dbcache[MAXDBCACHE];
ldap_pvt_thread_mutex_t li_dbcache_mutex;
ldap_pvt_thread_cond_t li_dbcache_cv;
......
......@@ -89,9 +89,15 @@ ldbm_back_db_config(
}
li->li_dbcachesize = atoi( argv[1] );
/* no write sync */
} else if ( strcasecmp( argv[0], "dbcachenowsync" ) == 0 ) {
li->li_dbcachewsync = 0;
/* no locking (not safe) */
} else if ( strcasecmp( argv[0], "dbnolocking" ) == 0 ) {
li->li_dblocking = 0;
/* no write sync (not safe) */
} else if ( ( strcasecmp( argv[0], "dbnosync" ) == 0 )
|| ( strcasecmp( argv[0], "dbcachenowsync" ) == 0 ) )
{
li->li_dbwritesync = 0;
/* anything else */
} else {
......
......@@ -42,6 +42,18 @@ ldbm_cache_open(
sprintf( buf, "%s" LDAP_DIRSEP "%s%s",
li->li_directory, name, suffix );
if( li->li_dblocking ) {
flags |= LDBM_LOCKING;
} else {
flags |= LDBM_NOLOCKING;
}
if( li->li_dbwritesync ) {
flags |= LDBM_SYNC;
} else {
flags |= LDBM_NOSYNC;
}
Debug( LDAP_DEBUG_TRACE, "=> ldbm_cache_open( \"%s\", %d, %o )\n", buf,
flags, li->li_mode );
......@@ -135,6 +147,10 @@ ldbm_cache_close( Backend *be, DBCache *db )
{
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
if( li->li_dbwritesync ) {
ldbm_sync( db->dbc_db );
}
ldap_pvt_thread_mutex_lock( &li->li_dbcache_mutex );
if ( --db->dbc_refcnt == 0 ) {
ldap_pvt_thread_cond_signal( &li->li_dbcache_cv );
......
......@@ -48,8 +48,6 @@ dn2id_add(
data.dsize = sizeof(ID);
flags = LDBM_INSERT;
if ( li->li_dbcachewsync ) flags |= LDBM_SYNC;
rc = ldbm_cache_store( db, key, data, flags );
free( key.dptr );
......
......@@ -49,7 +49,6 @@ id2entry_add( Backend *be, Entry *e )
/* store it */
flags = LDBM_REPLACE;
if ( li->li_dbcachewsync ) flags |= LDBM_SYNC;
rc = ldbm_cache_store( db, key, data, flags );
ldap_pvt_thread_mutex_unlock( &entry2str_mutex );
......
......@@ -217,7 +217,6 @@ idl_store(
#endif
flags = LDBM_REPLACE;
if( li->li_dbcachewsync ) flags |= LDBM_SYNC;
rc = ldbm_cache_store( db, key, data, flags );
/* Debug( LDAP_DEBUG_TRACE, "<= idl_store %d\n", rc, 0, 0 ); */
......
......@@ -130,8 +130,11 @@ ldbm_back_db_init(
/* default database cache size */
li->li_dbcachesize = DEFAULT_DBCACHE_SIZE;
/* default cache mode is sync on write */
li->li_dbcachewsync = 1;
/* default db mode is with locking */
li->li_dblocking = 1;
/* default db mode is with write synchronization */
li->li_dbwritesync = 1;
/* default file creation mode */
li->li_mode = DEFAULT_MODE;
......
......@@ -77,8 +77,6 @@ next_id_write( Backend *be, ID id )
data.dsize = sizeof(ID);
flags = LDBM_REPLACE;
if( li->li_dbcachewsync ) flags |= LDBM_SYNC;
if ( ldbm_cache_store( db, key, data, flags ) != 0 ) {
id = NOID;
}
......
......@@ -42,7 +42,7 @@ int ldbm_tool_entry_open(
flags = LDBM_READER;
}
li->li_dbcachewsync = 0;
li->li_dbwritesync = 0;
if ( (id2entry = ldbm_cache_open( be, "id2entry", LDBM_SUFFIX, flags ))
== NULL ) {
......@@ -63,7 +63,7 @@ int ldbm_tool_entry_close(
assert( id2entry != NULL );
ldbm_cache_close( be, id2entry );
li->li_dbcachewsync = 1;
li->li_dbwritesync = 1;
id2entry = NULL;
return 0;
......
......@@ -29,4 +29,3 @@ index cn,sn,uid pres,eq,approx
index default none
# index default pres,eq,approx
lastmod on
dbcachenowsync
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment