From e0cc94a0b72d1fb866c406dc7c940bba9010c84f Mon Sep 17 00:00:00 2001 From: Howard Chu 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 60e5e7c13e..a0b87a9ec4 100644 --- a/servers/slapd/syncrepl.c +++ b/servers/slapd/syncrepl.c @@ -123,6 +123,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; @@ -152,7 +153,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( @@ -563,6 +564,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 @@ -727,6 +729,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 ); @@ -1029,7 +1033,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: @@ -1057,7 +1061,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 ) { @@ -1203,7 +1207,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 ( si->si_refreshCount ) { LDAP_SLIST_REMOVE( &op->o_extra, si->si_refreshTxn, OpExtra, oe_next ); @@ -1393,7 +1397,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 ); @@ -3931,7 +3935,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; @@ -4023,40 +4028,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; @@ -4099,7 +4111,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 ); -- 2.39.2