From: Jong Hyuk Choi Date: Tue, 1 Jul 2003 11:55:18 +0000 (+0000) Subject: Berkeley DB congestion avoidance X-Git-Tag: OPENLDAP_REL_ENG_2_1_MP~841 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=5bc1e1a3c90062ccc8711f469b22ecdc530bf4af;p=openldap Berkeley DB congestion avoidance --- diff --git a/servers/slapd/back-bdb/Makefile.in b/servers/slapd/back-bdb/Makefile.in index 47a6d9a57b..1ff4dbe15b 100644 --- a/servers/slapd/back-bdb/Makefile.in +++ b/servers/slapd/back-bdb/Makefile.in @@ -6,12 +6,12 @@ SRCS = init.c tools.c config.c \ add.c bind.c compare.c delete.c modify.c modrdn.c search.c \ extended.c passwd.c referral.c operational.c \ attr.c index.c key.c dbcache.c filterindex.c \ - dn2entry.c dn2id.c error.c id2entry.c idl.c nextid.c cache.c + dn2entry.c dn2id.c error.c id2entry.c idl.c nextid.c cache.c trans.c OBJS = init.lo tools.lo config.lo \ add.lo bind.lo compare.lo delete.lo modify.lo modrdn.lo search.lo \ extended.lo passwd.lo referral.lo operational.lo \ attr.lo index.lo key.lo dbcache.lo filterindex.lo \ - dn2entry.lo dn2id.lo error.lo id2entry.lo idl.lo nextid.lo cache.lo + dn2entry.lo dn2id.lo error.lo id2entry.lo idl.lo nextid.lo cache.lo trans.lo LDAP_INCDIR= ../../../include LDAP_LIBDIR= ../../../libraries diff --git a/servers/slapd/back-bdb/add.c b/servers/slapd/back-bdb/add.c index fd128d146a..c2df351f87 100644 --- a/servers/slapd/back-bdb/add.c +++ b/servers/slapd/back-bdb/add.c @@ -33,6 +33,8 @@ bdb_add(Operation *op, SlapReply *rs ) DB_LOCK lock; int noop = 0; + int num_retries = 0; + #ifdef LDAP_SYNC Operation* ps_list; #endif @@ -96,6 +98,7 @@ retry: /* transaction retry */ rs->sr_text = "internal error"; goto return_results; } + bdb_trans_backoff( ++num_retries ); ldap_pvt_thread_yield(); } diff --git a/servers/slapd/back-bdb/delete.c b/servers/slapd/back-bdb/delete.c index 824de2e67d..3d382a2e42 100644 --- a/servers/slapd/back-bdb/delete.c +++ b/servers/slapd/back-bdb/delete.c @@ -33,6 +33,8 @@ bdb_delete( Operation *op, SlapReply *rs ) int noop = 0; + int num_retries = 0; + #ifdef LDAP_SYNC Operation* ps_list; #endif @@ -66,6 +68,7 @@ retry: /* transaction retry */ rs->sr_text = "internal error"; goto return_results; } + bdb_trans_backoff( ++num_retries ); ldap_pvt_thread_yield(); } diff --git a/servers/slapd/back-bdb/modify.c b/servers/slapd/back-bdb/modify.c index 7844ce0261..089808a926 100644 --- a/servers/slapd/back-bdb/modify.c +++ b/servers/slapd/back-bdb/modify.c @@ -304,6 +304,8 @@ bdb_modify( Operation *op, SlapReply *rs ) int noop = 0; + int num_retries = 0; + #ifdef LDAP_SYNC Operation* ps_list; struct psid_entry *pm_list, *pm_prev; @@ -347,6 +349,7 @@ retry: /* transaction retry */ rs->sr_text = "internal error"; goto return_results; } + bdb_trans_backoff( ++num_retries ); ldap_pvt_thread_yield(); } diff --git a/servers/slapd/back-bdb/modrdn.c b/servers/slapd/back-bdb/modrdn.c index 3e2f2a86c3..9c390b3810 100644 --- a/servers/slapd/back-bdb/modrdn.c +++ b/servers/slapd/back-bdb/modrdn.c @@ -51,6 +51,8 @@ bdb_modrdn( Operation *op, SlapReply *rs ) int noop = 0; + int num_retries = 0; + #ifdef LDAP_SYNC Operation *ps_list; struct psid_entry *pm_list, *pm_prev; @@ -105,6 +107,7 @@ retry: /* transaction retry */ rs->sr_text = "internal error"; goto return_results; } + bdb_trans_backoff( ++num_retries ); ldap_pvt_thread_yield(); } diff --git a/servers/slapd/back-bdb/passwd.c b/servers/slapd/back-bdb/passwd.c index 1c96ace428..d847cd3ef5 100644 --- a/servers/slapd/back-bdb/passwd.c +++ b/servers/slapd/back-bdb/passwd.c @@ -36,6 +36,8 @@ bdb_exop_passwd( Operation *op, SlapReply *rs ) u_int32_t locker = 0; DB_LOCK lock; + int num_retries = 0; + assert( ber_bvcmp( &slap_EXOP_MODIFY_PASSWD, &op->oq_extended.rs_reqoid ) == 0 ); rc = slap_passwd_parse( op->oq_extended.rs_reqdata, @@ -118,6 +120,7 @@ retry: /* transaction retry */ rs->sr_text = "internal error"; goto done; } + bdb_trans_backoff( ++num_retries ); ldap_pvt_thread_yield(); } diff --git a/servers/slapd/back-bdb/proto-bdb.h b/servers/slapd/back-bdb/proto-bdb.h index c99f9da36b..1d3a55a31f 100644 --- a/servers/slapd/back-bdb/proto-bdb.h +++ b/servers/slapd/back-bdb/proto-bdb.h @@ -540,6 +540,12 @@ bdb_send_ldap_intermediate( struct berval *cookie ); #endif +/* + * trans.c + */ + +void +bdb_trans_backoff( int num_retries ); LDAP_END_DECL diff --git a/servers/slapd/back-bdb/trans.c b/servers/slapd/back-bdb/trans.c new file mode 100644 index 0000000000..51fecf418b --- /dev/null +++ b/servers/slapd/back-bdb/trans.c @@ -0,0 +1,47 @@ +/* trans.c - bdb backend transaction routines */ +/* $OpenLDAP$ */ + +#include "portable.h" + +#include +#include + +#include "back-bdb.h" +#include "external.h" +#include "lber_pvt.h" + + +/* Congestion avoidance code + * for Deadlock Rollback + */ + +void +bdb_trans_backoff( int num_retries ) +{ + int i; + int delay = 0; + int pow_retries = 1; + unsigned long key = 0; + unsigned long max_key = -1; + struct timeval timeout; + + lutil_entropy( &key, sizeof( unsigned long )); + + for ( i = 0; i < num_retries; i++ ) { + if ( i >= 5 ) break; + pow_retries *= 4; + } + + delay = 16384 * (key * (double) pow_retries / (double) max_key); + delay = delay ? delay : 1; + +#ifdef NEW_LOGGING + LDAP_LOG( OPERATION, ERR, "delay = %d, num_retries = %d\n", delay, num_retries, 0 ); +#else + Debug( LDAP_DEBUG_TRACE, "delay = %d, num_retries = %d\n", delay, num_retries, 0 ); +#endif + + timeout.tv_sec = delay / 1000000; + timeout.tv_usec = delay % 1000000; + select( 0, NULL, NULL, NULL, &timeout ); +} diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index e94158bf44..3148cd0ef9 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -1112,6 +1112,8 @@ LDAP_SLAPD_V (ldap_pvt_thread_mutex_t) passwd_mutex; #endif LDAP_SLAPD_V (ldap_pvt_thread_mutex_t) gmtime_mutex; +LDAP_SLAPD_V (ldap_pvt_thread_mutex_t) rand_mutex; + LDAP_SLAPD_V (AccessControl *) global_acl; LDAP_SLAPD_V (ber_socket_t) dtblsize;