From 8ab4308c636447ea8a1c709d5f54b0537cca41c0 Mon Sep 17 00:00:00 2001 From: Howard Chu <hyc@openldap.org> Date: Wed, 31 Jan 2018 15:19:58 +0000 Subject: [PATCH] ITS#8789 avoid unnecessary writes of context entry If syncprov is present, only write contextCSN attribute on actual state changes, not on per-entry modifications. Continue to update in-memory cookieState. Saves overhead, syncprov will eventually checkpoint it into the DB anyway. --- servers/slapd/syncrepl.c | 81 +++++++++++++++++++++++----------------- 1 file changed, 47 insertions(+), 34 deletions(-) diff --git a/servers/slapd/syncrepl.c b/servers/slapd/syncrepl.c index 8baca58ea7..96d3f2038d 100644 --- a/servers/slapd/syncrepl.c +++ b/servers/slapd/syncrepl.c @@ -118,6 +118,7 @@ typedef struct syncinfo_s { int si_got; int si_strict_refresh; /* stop listening during fallback refresh */ int si_too_old; + int si_has_syncprov; ber_int_t si_msgid; Avlnode *si_presentlist; LDAP *si_ld; @@ -147,7 +148,7 @@ static int syncrepl_entry( struct berval *cookieCSN ); static int syncrepl_updateCookie( syncinfo_t *, Operation *, - struct sync_cookie * ); + struct sync_cookie *, int save ); static struct berval * slap_uuidstr_from_normalized( struct berval *, struct berval *, void * ); static int syncrepl_add_glue_ancestors( @@ -554,6 +555,7 @@ check_syncprov( ber_bvarray_free( a.a_nvals ); } ber_bvarray_free( a.a_vals ); + si->si_has_syncprov = 1; } /* See if the cookieState has changed due to anything outside * this particular consumer. That includes other consumers in @@ -718,6 +720,8 @@ do_syncrep1( si->si_syncCookie.sids[i] = si->si_cookieState->cs_sids[i]; } ldap_pvt_thread_mutex_unlock( &si->si_cookieState->cs_mutex ); + /* Also look in syncprov overlay, if it was already active */ + check_syncprov( op, si ); } ch_free( si->si_syncCookie.octet_str.bv_val ); @@ -1015,7 +1019,7 @@ do_syncrep2( if ( ( rc = syncrepl_message_to_op( si, op, msg ) ) == LDAP_SUCCESS && syncCookie.ctxcsn ) { - rc = syncrepl_updateCookie( si, op, &syncCookie ); + rc = syncrepl_updateCookie( si, op, &syncCookie, 0 ); } else switch ( rc ) { case LDAP_ALREADY_EXISTS: case LDAP_NO_SUCH_OBJECT: @@ -1043,7 +1047,7 @@ do_syncrep2( syncstate, syncUUID, syncCookie.ctxcsn ) ) == LDAP_SUCCESS && syncCookie.ctxcsn ) { - rc = syncrepl_updateCookie( si, op, &syncCookie ); + rc = syncrepl_updateCookie( si, op, &syncCookie, 0 ); } } if ( punlock >= 0 ) { @@ -1189,7 +1193,7 @@ do_syncrep2( } if ( syncCookie.ctxcsn && match < 0 && err == LDAP_SUCCESS ) { - rc = syncrepl_updateCookie( si, op, &syncCookie ); + rc = syncrepl_updateCookie( si, op, &syncCookie, 1 ); } if ( err == LDAP_SUCCESS && si->si_logstate == SYNCLOG_FALLBACK ) { @@ -1361,7 +1365,7 @@ do_syncrep2( if ( syncCookie.ctxcsn ) { - rc = syncrepl_updateCookie( si, op, &syncCookie); + rc = syncrepl_updateCookie( si, op, &syncCookie, 1 ); } if ( si->si_presentlist ) { presentlist_free( si->si_presentlist ); @@ -3860,7 +3864,8 @@ static int syncrepl_updateCookie( syncinfo_t *si, Operation *op, - struct sync_cookie *syncCookie ) + struct sync_cookie *syncCookie, + int save ) { Backend *be = op->o_bd; Modifications mod; @@ -3952,40 +3957,47 @@ syncrepl_updateCookie( si->si_cookieState->cs_updating = 1; ldap_pvt_thread_mutex_unlock( &si->si_cookieState->cs_mutex ); - op->o_bd = si->si_wbe; - slap_queue_csn( op, &first ); + if ( save || !si->si_has_syncprov ) { + op->o_bd = si->si_wbe; + slap_queue_csn( op, &first ); - op->o_tag = LDAP_REQ_MODIFY; + op->o_tag = LDAP_REQ_MODIFY; - cb.sc_response = syncrepl_null_callback; - cb.sc_private = si; + cb.sc_response = syncrepl_null_callback; + cb.sc_private = si; - op->o_callback = &cb; - op->o_req_dn = si->si_contextdn; - op->o_req_ndn = si->si_contextdn; + op->o_callback = &cb; + op->o_req_dn = si->si_contextdn; + op->o_req_ndn = si->si_contextdn; - /* update contextCSN */ - op->o_dont_replicate = 1; + /* update contextCSN */ + op->o_dont_replicate = 1; - mod.sml_numvals = sc.numcsns; - mod.sml_values = sc.ctxcsn; + mod.sml_numvals = sc.numcsns; + mod.sml_values = sc.ctxcsn; - op->orm_modlist = &mod; - op->orm_no_opattrs = 1; - rc = op->o_bd->be_modify( op, &rs_modify ); + op->orm_modlist = &mod; + op->orm_no_opattrs = 1; + rc = op->o_bd->be_modify( op, &rs_modify ); + + if ( rs_modify.sr_err == LDAP_NO_SUCH_OBJECT && + SLAP_SYNC_SUBENTRY( op->o_bd )) { + const char *text; + char txtbuf[SLAP_TEXT_BUFLEN]; + size_t textlen = sizeof txtbuf; + Entry *e = slap_create_context_csn_entry( op->o_bd, NULL ); + rs_reinit( &rs_modify, REP_RESULT ); + rc = slap_mods2entry( &mod, &e, 0, 1, &text, txtbuf, textlen); + op->ora_e = e; + rc = op->o_bd->be_add( op, &rs_modify ); + if ( e == op->ora_e ) + be_entry_release_w( op, op->ora_e ); + } - if ( rs_modify.sr_err == LDAP_NO_SUCH_OBJECT && - SLAP_SYNC_SUBENTRY( op->o_bd )) { - const char *text; - char txtbuf[SLAP_TEXT_BUFLEN]; - size_t textlen = sizeof txtbuf; - Entry *e = slap_create_context_csn_entry( op->o_bd, NULL ); - rs_reinit( &rs_modify, REP_RESULT ); - rc = slap_mods2entry( &mod, &e, 0, 1, &text, txtbuf, textlen); - op->ora_e = e; - rc = op->o_bd->be_add( op, &rs_modify ); - if ( e == op->ora_e ) - be_entry_release_w( op, op->ora_e ); + op->orm_no_opattrs = 0; + op->o_dont_replicate = 0; + } else { + rc = 0; } op->orm_no_opattrs = 0; @@ -4028,7 +4040,8 @@ syncrepl_updateCookie( ldap_pvt_thread_mutex_unlock( &si->si_cookieState->cs_mutex ); op->o_bd = be; - op->o_tmpfree( op->o_csn.bv_val, op->o_tmpmemctx ); + if ( op->o_csn.bv_val ) + op->o_tmpfree( op->o_csn.bv_val, op->o_tmpmemctx ); BER_BVZERO( &op->o_csn ); if ( mod.sml_next ) slap_mods_free( mod.sml_next, 1 ); -- GitLab