static void _logOpRS(OperationContext* txn, const char *opstr, const char *ns, const char *logNS, const BSONObj& obj, BSONObj *o2, bool *bb, bool fromMigrate ) { Lock::DBLock lk1(txn->lockState(), "local", newlm::MODE_X); WriteUnitOfWork wunit(txn); if ( strncmp(ns, "local.", 6) == 0 ) { if ( strncmp(ns, "local.slaves", 12) == 0 ) resetSlaveCache(); return; } ReplicationCoordinator* replCoord = getGlobalReplicationCoordinator(); mutex::scoped_lock lk2(newOpMutex); OpTime ts(getNextGlobalOptime()); newOptimeNotifier.notify_all(); long long hashNew = BackgroundSync::get()->getLastAppliedHash(); // Check to make sure logOp() is legal at this point. if (*opstr == 'n') { // 'n' operations are always logged invariant(*ns == '\0'); // 'n' operations do not advance the hash, since they are not rolled back } else { if (!replCoord->canAcceptWritesForDatabase(nsToDatabaseSubstring(ns))) { severe() << "replSet error : logOp() but can't accept write to collection " << ns; fassertFailed(17405); } // Advance the hash hashNew = (hashNew * 131 + ts.asLL()) * 17 + replCoord->getMyId(); } /* we jump through a bunch of hoops here to avoid copying the obj buffer twice -- instead we do a single copy to the destination position in the memory mapped file. */ logopbufbuilder.reset(); BSONObjBuilder b(logopbufbuilder); b.appendTimestamp("ts", ts.asDate()); b.append("h", hashNew); b.append("v", OPLOG_VERSION); b.append("op", opstr); b.append("ns", ns); if (fromMigrate) b.appendBool("fromMigrate", true); if ( bb ) b.appendBool("b", *bb); if ( o2 ) b.append("o2", *o2); BSONObj partial = b.done(); DEV verify( logNS == 0 ); // check this was never a master/slave master if ( localOplogRSCollection == 0 ) { Client::Context ctx(txn, rsoplog); localDB = ctx.db(); verify( localDB ); localOplogRSCollection = localDB->getCollection( txn, rsoplog ); massert(13347, "local.oplog.rs missing. did you drop it? if so restart server", localOplogRSCollection); } Client::Context ctx(txn, rsoplog, localDB); OplogDocWriter writer( partial, obj ); checkOplogInsert( localOplogRSCollection->insertDocument( txn, &writer, false ) ); BackgroundSync::get()->setLastAppliedHash(hashNew); ctx.getClient()->setLastOp( ts ); replCoord->setMyLastOptime(txn, ts); wunit.commit(); }