Get MDB txn before acquiring a CSN

Since MDB writes are fully serialized in txn_begin, we can use CSNs as
commit sequence numbers, not just change sequence numbers. This will
prevent most instances of out-of-order writes, so syncprov will almost
never need to transmit a change without a cookieCSN. (Out-of-order is
still possible, if the write was received via syncrepl.)
This commit is contained in:
Howard Chu 2012-12-13 07:13:39 -08:00
parent 9ed5ca4f7a
commit d3087229d5
4 changed files with 33 additions and 37 deletions

View File

@ -101,6 +101,19 @@ txnReturn:
goto return_results;
}
/* begin transaction */
rs->sr_err = mdb_opinfo_get( op, mdb, 0, &moi );
rs->sr_text = NULL;
if( rs->sr_err != 0 ) {
Debug( LDAP_DEBUG_TRACE,
LDAP_XSTRING(mdb_add) ": txn_begin failed: %s (%d)\n",
mdb_strerror(rs->sr_err), rs->sr_err, 0 );
rs->sr_err = LDAP_OTHER;
rs->sr_text = "internal error";
goto return_results;
}
txn = moi->moi_txn;
/* add opattrs to shadow as well, only missing attrs will actually
* be added; helps compatibility with older OL versions */
rs->sr_err = slap_add_opattrs( op, &rs->sr_text, textbuf, textlen, 1 );
@ -120,20 +133,6 @@ txnReturn:
subentry = is_entry_subentry( op->ora_e );
/* begin transaction */
rs->sr_err = mdb_opinfo_get( op, mdb, 0, &moi );
rs->sr_text = NULL;
if( rs->sr_err != 0 ) {
Debug( LDAP_DEBUG_TRACE,
LDAP_XSTRING(mdb_add) ": txn_begin failed: %s (%d)\n",
mdb_strerror(rs->sr_err), rs->sr_err, 0 );
rs->sr_err = LDAP_OTHER;
rs->sr_text = "internal error";
goto return_results;
}
txn = moi->moi_txn;
/*
* Get the parent dn and see if the corresponding entry exists.
*/

View File

@ -90,16 +90,6 @@ txnReturn:
ctrls[num_ctrls] = 0;
/* allocate CSN */
if ( BER_BVISNULL( &op->o_csn ) ) {
struct berval csn;
char csnbuf[LDAP_PVT_CSNSTR_BUFSIZE];
csn.bv_val = csnbuf;
csn.bv_len = sizeof(csnbuf);
slap_get_csn( op, &csn, 1 );
}
/* begin transaction */
rs->sr_err = mdb_opinfo_get( op, mdb, 0, &moi );
rs->sr_text = NULL;
@ -111,9 +101,18 @@ txnReturn:
rs->sr_text = "internal error";
goto return_results;
}
txn = moi->moi_txn;
/* allocate CSN */
if ( BER_BVISNULL( &op->o_csn ) ) {
struct berval csn;
char csnbuf[LDAP_PVT_CSNSTR_BUFSIZE];
csn.bv_val = csnbuf;
csn.bv_len = sizeof(csnbuf);
slap_get_csn( op, &csn, 1 );
}
if ( !be_issuffix( op->o_bd, &op->o_req_ndn ) ) {
dnParent( &op->o_req_ndn, &pdn );
}

View File

@ -457,14 +457,6 @@ txnReturn:
ctrls[num_ctrls] = NULL;
/* Don't touch the opattrs, if this is a contextCSN update
* initiated from updatedn */
if ( !be_isupdate(op) || !op->orm_modlist || op->orm_modlist->sml_next ||
op->orm_modlist->sml_desc != slap_schema.si_ad_contextCSN ) {
slap_mods_opattrs( op, &op->orm_modlist, 1 );
}
/* begin transaction */
rs->sr_err = mdb_opinfo_get( op, mdb, 0, &moi );
rs->sr_text = NULL;
@ -476,9 +468,16 @@ txnReturn:
rs->sr_text = "internal error";
goto return_results;
}
txn = moi->moi_txn;
/* Don't touch the opattrs, if this is a contextCSN update
* initiated from updatedn */
if ( !be_isupdate(op) || !op->orm_modlist || op->orm_modlist->sml_next ||
op->orm_modlist->sml_desc != slap_schema.si_ad_contextCSN ) {
slap_mods_opattrs( op, &op->orm_modlist, 1 );
}
/* get entry or ancestor */
rs->sr_err = mdb_dn2entry( op, txn, NULL, &op->o_req_ndn, &e, 1 );

View File

@ -103,8 +103,6 @@ txnReturn:
ctrls[num_ctrls] = NULL;
slap_mods_opattrs( op, &op->orr_modlist, 1 );
/* begin transaction */
rs->sr_err = mdb_opinfo_get( op, mdb, 0, &moi );
rs->sr_text = NULL;
@ -116,9 +114,10 @@ txnReturn:
rs->sr_text = "internal error";
goto return_results;
}
txn = moi->moi_txn;
slap_mods_opattrs( op, &op->orr_modlist, 1 );
if ( be_issuffix( op->o_bd, &op->o_req_ndn ) ) {
#ifdef MDB_MULTIPLE_SUFFIXES
/* Allow renaming one suffix entry to another */