]> git.sur5r.net Git - openldap/commitdiff
ITS#8789 avoid unnecessary writes of context entry
authorHoward Chu <hyc@openldap.org>
Wed, 31 Jan 2018 15:19:58 +0000 (15:19 +0000)
committerHoward Chu <hyc@openldap.org>
Wed, 21 Feb 2018 19:51:59 +0000 (19:51 +0000)
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

index 60e5e7c13e820d9ec963ffb8396adc9b76ec3ac8..a0b87a9ec47be30a45b198d6b6ca3e487dd8044c 100644 (file)
@@ -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 );