From 0ef87764d708541e33c2a374ca617bb510aef9d9 Mon Sep 17 00:00:00 2001 From: Randy Kunkee Date: Thu, 28 Jun 2001 09:20:33 +0000 Subject: [PATCH] Move backend_syncfreq code down into back-ldbm. Creates new configuration for LDBM backends called "dbsync", which takes minimum of one argument up to 3 args which are sync frequency, # of delays, and delay periods. See man page update for "dbsync" configuration for more details. --- doc/man/man5/slapd.conf.5 | 30 +++++++++++++ servers/slapd/back-ldbm/back-ldbm.h | 5 +++ servers/slapd/back-ldbm/close.c | 6 +++ servers/slapd/back-ldbm/config.c | 52 +++++++++++++++++++++++ servers/slapd/back-ldbm/dbcache.c | 32 ++++++++++++++ servers/slapd/back-ldbm/init.c | 28 ++++++++++++ servers/slapd/back-ldbm/proto-back-ldbm.h | 1 + 7 files changed, 154 insertions(+) diff --git a/doc/man/man5/slapd.conf.5 b/doc/man/man5/slapd.conf.5 index 2cd32ec51c..3b228813d9 100644 --- a/doc/man/man5/slapd.conf.5 +++ b/doc/man/man5/slapd.conf.5 @@ -640,11 +640,41 @@ method, this option is ignored without comment. The default is 100000 bytes. .B dbnolocking Specify that no database locking should be performed. Enabling this option may improve performance at the expense of data security. +.TP .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 dbsync +Flush dirty database buffers to disk every +.B +seconds. Implies +.B dbnosync +(ie. indvidual updates are no longer written to disk). It attempts to avoid +syncs during periods of peak activity by waiting +.B +seconds if the server is busy, repeating this delay up to +.B +times before proceeding. +It is an attempt to provide higher write performance with some amount of data +security. Note that it may still be possible to get an inconsistent +database if the underlying engine fills its cache and writes out individual +pages and slapd crashes or is killed before the next sync. +.B +and +.B +are optional and default to +.B 12 +and +.B 5 +respectively, giving a total elapsed delay of 60 seconds before a sync +will occur. +.B +may be zero, and +.B +must be 1 or greater. +.TP .B directory Specify the directory where the LDBM files containing this database and associated indexes live. A separate directory must be specified for diff --git a/servers/slapd/back-ldbm/back-ldbm.h b/servers/slapd/back-ldbm/back-ldbm.h index dd2c70871a..74cf0e9b2c 100644 --- a/servers/slapd/back-ldbm/back-ldbm.h +++ b/servers/slapd/back-ldbm/back-ldbm.h @@ -119,6 +119,11 @@ struct ldbminfo { ldap_pvt_thread_cond_t li_dbcache_cv; DB_ENV *li_dbenv; int li_envdirok; + int li_dbsyncfreq; + int li_dbsyncwaitn; + int li_dbsyncwaitinterval; + ldap_pvt_thread_t li_dbsynctid; + int li_dbshutdown; }; LDAP_END_DECL diff --git a/servers/slapd/back-ldbm/close.c b/servers/slapd/back-ldbm/close.c index 452d38f222..ec32899f68 100644 --- a/servers/slapd/back-ldbm/close.c +++ b/servers/slapd/back-ldbm/close.c @@ -17,6 +17,12 @@ int ldbm_back_db_close( Backend *be ) { + struct ldbminfo *li = (struct ldbminfo *) be->be_private; + if ( li->li_dbsyncfreq > 0 ) + { + li->li_dbshutdown++; + ldap_pvt_thread_join( li->li_dbsynctid, (void *) NULL ); + } #ifdef NEW_LOGGING LDAP_LOG(( "backend", LDAP_LEVEL_CRIT, "ldbm_back_db_close: ldbm backend syncing\n" )); diff --git a/servers/slapd/back-ldbm/config.c b/servers/slapd/back-ldbm/config.c index 35b6d907b3..f574839fd5 100644 --- a/servers/slapd/back-ldbm/config.c +++ b/servers/slapd/back-ldbm/config.c @@ -101,6 +101,58 @@ ldbm_back_db_config( { li->li_dbwritesync = 0; + /* run sync thread */ + } else if ( strcasecmp( argv[0], "dbsync" ) == 0 ) { +#ifndef NO_THREADS + int i; + if ( argc < 2 ) { + Debug( LDAP_DEBUG_ANY, + "%s: line %d: missing frquency value in \"dbsync [ [wait-interval]]\" line\n", + fname, lineno, 0 ); + return 1; + } + + i = atoi( argv[1] ); + + if( i < 0 ) { + Debug( LDAP_DEBUG_ANY, + "%s: line %d: frquency value (%d) invalid \"dbsync [ [wait-interval]]\" line\n", + fname, lineno, i ); + return 1; + } + + li->li_dbsyncfreq = i; + li->li_dbwritesync = 0; + + if ( argc > 2 ) { + i = atoi( argv[2] ); + if ( i < 0 ) { + Debug( LDAP_DEBUG_ANY, + "%s: line %d: frquency value (%d) invalid \"dbsync [ [wait-interval]]\" line\n", + fname, lineno, i ); + return 1; + } + li ->li_dbsyncwaitn = i; + } + + if ( argc > 3 ) { + i = atoi( argv[3] ); + if ( i <= 0 ) { + Debug( LDAP_DEBUG_ANY, + "%s: line %d: frquency value (%d) invalid \"dbsync [ [wait-interval]]\" line\n", + fname, lineno, i ); + return 1; + } + li ->li_dbsyncwaitinterval = i; + } + +#else + Debug( LDAP_DEBUG_ANY, + "\"dbsync\" policies not supported in non-threaded environments\n"); + return 1; +#endif + + /* anything else */ } else { fprintf( stderr, diff --git a/servers/slapd/back-ldbm/dbcache.c b/servers/slapd/back-ldbm/dbcache.c index de27b7ec70..080af04d69 100644 --- a/servers/slapd/back-ldbm/dbcache.c +++ b/servers/slapd/back-ldbm/dbcache.c @@ -376,3 +376,35 @@ ldbm_cache_delete( return( rc ); } + +void * +ldbm_cache_sync_daemon( + void *be_ptr +) +{ + Backend *be = (Backend *)be_ptr; + struct ldbminfo *li = (struct ldbminfo *) be->be_private; + + Debug( LDAP_DEBUG_ANY, "synchronizer starting for %s\n", li->li_directory, 0, 0 ); + + while (!li->li_dbshutdown) { + int i = li->li_dbsyncwaitn; + + sleep( li->li_dbsyncfreq ); + + while (i && ldap_pvt_thread_pool_backload(&connection_pool) != 0) { + Debug( LDAP_DEBUG_ANY, "delay syncing %s\n", li->li_directory, 0, 0 ); + sleep(li->li_dbsyncwaitinterval); + i--; + } + + if (!li->li_dbshutdown) { + Debug( LDAP_DEBUG_ANY, "syncing %s\n", li->li_directory, 0, 0 ); + ldbm_cache_sync( be ); + } + } + + Debug( LDAP_DEBUG_ANY, "synchronizer stopping\n", 0, 0, 0 ); + + return NULL; +} diff --git a/servers/slapd/back-ldbm/init.c b/servers/slapd/back-ldbm/init.c index 7592920b51..4b9e257a46 100644 --- a/servers/slapd/back-ldbm/init.c +++ b/servers/slapd/back-ldbm/init.c @@ -159,6 +159,18 @@ ldbm_back_db_init( /* envdirok is turned on by ldbm_initialize_env if DB3 */ li->li_envdirok = 0; + /* syncfreq is 0 if disabled, or # seconds */ + li->li_dbsyncfreq = 0; + + /* wait up to dbsyncwaitn times if server is busy */ + li->li_dbsyncwaitn = 12; + + /* delay interval */ + li->li_dbsyncwaitinterval = 5; + + /* flag to notify ldbm_cache_sync_daemon to shut down */ + li->li_dbshutdown = 0; + /* initialize various mutex locks & condition variables */ ldap_pvt_thread_mutex_init( &li->li_root_mutex ); ldap_pvt_thread_mutex_init( &li->li_add_mutex ); @@ -180,6 +192,22 @@ ldbm_back_db_open( struct ldbminfo *li = (struct ldbminfo *) be->be_private; li->li_dbenv = ldbm_initialize_env( li->li_directory, li->li_dbcachesize, &li->li_envdirok ); + + /* sync thread */ + if ( li->li_dbsyncfreq > 0 ) + { + int rc; + rc = ldap_pvt_thread_create( &li->li_dbsynctid, + 0, ldbm_cache_sync_daemon, (void*)be ); + + if ( rc != 0 ) + { + Debug( LDAP_DEBUG_ANY, + "sync ldap_pvt_thread_create failed (%d)\n", rc, 0, 0 ); + return 1; + } + } + return 0; } diff --git a/servers/slapd/back-ldbm/proto-back-ldbm.h b/servers/slapd/back-ldbm/proto-back-ldbm.h index 56095c8e71..a6798ce513 100644 --- a/servers/slapd/back-ldbm/proto-back-ldbm.h +++ b/servers/slapd/back-ldbm/proto-back-ldbm.h @@ -70,6 +70,7 @@ void ldbm_cache_sync LDAP_P(( Backend *be )); Datum ldbm_cache_fetch LDAP_P(( DBCache *db, Datum key )); int ldbm_cache_store LDAP_P(( DBCache *db, Datum key, Datum data, int flags )); int ldbm_cache_delete LDAP_P(( DBCache *db, Datum key )); +void *ldbm_cache_sync_daemon LDAP_P(( void *)); /* * dn2id.c -- 2.39.5