I have found another corner case which can cause this behavior.
If syncprov_findcsn() cannot find an entry with CSN matching the cookie mincsn, it tries to search for an entry with CSN less than or equal to the mincsn. For this search, it sets the unchecked limit to 1.
If the scope of the search is not the whole database, this can cause the search to fail. The entryCSN filter identifies one candidate, and if that candidate is out of scope the search will fail, causing a full refresh.
Two potential fixes here would be:
1) Set the hard or soft limits to 1 instead of the unchecked limit. This search is used to determine if an expensive full refresh is necessary, so a more expensive check may be acceptable.
2) Search the overlaid database for the desired entryCSN instead of just the replicated subtree. This is what I've implemented locally. The patch (against 2.4.24):
diff --git a/servers/slapd/overlays/syncprov.c b/servers/slapd/overlays/syncprov.c index 349b580..a7147a2 100644 --- a/servers/slapd/overlays/syncprov.c +++ b/servers/slapd/overlays/syncprov.c @@ -679,6 +679,8 @@ again: fop.ors_limit = &fc_limits; memset( &fc_limits, 0, sizeof( fc_limits )); fc_limits.lms_s_unchecked = 1; + fop.o_req_dn = si->si_contextdn; + fop.o_req_ndn = si->si_contextdn; fop.ors_filterstr.bv_len = snprintf( buf, sizeof( buf ), "(entryCSN<=%s)", cf.f_av_value.bv_val ); }