// This free function is used by the writer threads to apply each op void multiSyncApply(const std::vector<BSONObj>& ops, SyncTail* st) { initializeWriterThread(); OperationContextImpl txn; txn.setReplicatedWrites(false); DisableDocumentValidation validationDisabler(&txn); // allow us to get through the magic barrier txn.lockState()->setIsBatchWriter(true); bool convertUpdatesToUpserts = true; for (std::vector<BSONObj>::const_iterator it = ops.begin(); it != ops.end(); ++it) { try { const Status s = SyncTail::syncApply(&txn, *it, convertUpdatesToUpserts); if (!s.isOK()) { severe() << "Error applying operation (" << it->toString() << "): " << s; fassertFailedNoTrace(16359); } } catch (const DBException& e) { severe() << "writer worker caught exception: " << causedBy(e) << " on: " << it->toString(); if (inShutdown()) { return; } fassertFailedNoTrace(16360); } } }
static void logStartup() { BSONObjBuilder toLog; stringstream id; id << getHostNameCached() << "-" << jsTime().asInt64(); toLog.append("_id", id.str()); toLog.append("hostname", getHostNameCached()); toLog.appendTimeT("startTime", time(0)); toLog.append("startTimeLocal", dateToCtimeString(Date_t::now())); toLog.append("cmdLine", serverGlobalParams.parsedOpts); toLog.append("pid", ProcessId::getCurrent().asLongLong()); BSONObjBuilder buildinfo(toLog.subobjStart("buildinfo")); appendBuildInfo(buildinfo); appendStorageEngineList(&buildinfo); buildinfo.doneFast(); BSONObj o = toLog.obj(); OperationContextImpl txn; ScopedTransaction transaction(&txn, MODE_X); Lock::GlobalWrite lk(txn.lockState()); AutoGetOrCreateDb autoDb(&txn, "local", mongo::MODE_X); Database* db = autoDb.getDb(); const std::string ns = "local.startup_log"; Collection* collection = db->getCollection(ns); WriteUnitOfWork wunit(&txn); if (!collection) { BSONObj options = BSON("capped" << true << "size" << 10 * 1024 * 1024); bool shouldReplicateWrites = txn.writesAreReplicated(); txn.setReplicatedWrites(false); ON_BLOCK_EXIT(&OperationContext::setReplicatedWrites, &txn, shouldReplicateWrites); uassertStatusOK(userCreateNS(&txn, db, ns, options)); collection = db->getCollection(ns); } invariant(collection); uassertStatusOK(collection->insertDocument(&txn, o, false).getStatus()); wunit.commit(); }
// This free function is used by the initial sync writer threads to apply each op void multiInitialSyncApply(const std::vector<BSONObj>& ops, SyncTail* st) { initializeWriterThread(); OperationContextImpl txn; txn.setReplicatedWrites(false); DisableDocumentValidation validationDisabler(&txn); // allow us to get through the magic barrier txn.lockState()->setIsBatchWriter(true); bool convertUpdatesToUpserts = false; for (std::vector<BSONObj>::const_iterator it = ops.begin(); it != ops.end(); ++it) { try { const Status s = SyncTail::syncApply(&txn, *it, convertUpdatesToUpserts); if (!s.isOK()) { if (st->shouldRetry(&txn, *it)) { const Status s2 = SyncTail::syncApply(&txn, *it, convertUpdatesToUpserts); if (!s2.isOK()) { severe() << "Error applying operation (" << it->toString() << "): " << s2; fassertFailedNoTrace(15915); } } // If shouldRetry() returns false, fall through. // This can happen if the document that was moved and missed by Cloner // subsequently got deleted and no longer exists on the Sync Target at all } } catch (const DBException& e) { severe() << "writer worker caught exception: " << causedBy(e) << " on: " << it->toString(); if (inShutdown()) { return; } fassertFailedNoTrace(16361); } } }