void logPosition() const { if (_player) { if (_player->thisTime() != OpTime()) { log() << "Exiting while processing operation with OpTime " << _player->thisTimeStr() << endl; } report(); OpTime t = _player->maxOpTimeSynced(); string tsString = mongoutils::str::stream() << t.getSecs() << ":" << t.getInc(); log() << "Use --ts=" << tsString << " to resume." << endl; try { std::ofstream tsFile; tsFile.exceptions(std::ifstream::badbit | std::ifstream::failbit); tsFile.open(_tsFilename, std::ofstream::trunc); tsFile << tsString; tsFile.close(); log() << "Saved timestamp to file " << (boost::filesystem::current_path() / _tsFilename).string() << "." << endl; log() << "I'll automatically use this value next time if you run from this directory " << "and don't pass --ts." << endl; } catch (std::exception &e) { warning() << "Error saving timestamp to file " << _tsFilename << ": " << e.what() << endl; warning() << "Make sure you save the timestamp somewhere, because I couldn't!" << endl; } } }
static string fmtOpTime(const OpTime &t) { stringstream ss; ss << t.getSecs() << ":" << t.getInc(); return ss.str(); }
virtual int doRun() { // authenticate enum Auth::Level authLevel = Auth::NONE; auth("", &authLevel); uassert(15935, "user does not have write access", authLevel == Auth::WRITE); boost::filesystem::path root = getParam("dir"); // check if we're actually talking to a machine that can write if (!isMaster()) { return -1; } if (isMongos() && _db == "" && exists(root / "config")) { log() << "Cannot do a full restore on a sharded system" << endl; return -1; } _drop = hasParam( "drop" ); _keepIndexVersion = hasParam("keepIndexVersion"); _restoreOptions = !hasParam("noOptionsRestore"); _restoreIndexes = !hasParam("noIndexRestore"); _w = getParam( "w" , 1 ); bool doOplog = hasParam( "oplogReplay" ); if (doOplog) { // fail early if errors if (_db != "") { log() << "Can only replay oplog on full restore" << endl; return -1; } if ( ! exists(root / "oplog.bson") ) { log() << "No oplog file to replay. Make sure you run mongodump with --oplog." << endl; return -1; } BSONObj out; if (! conn().simpleCommand("admin", &out, "buildinfo")) { log() << "buildinfo command failed: " << out["errmsg"].String() << endl; return -1; } StringData version = out["version"].valuestr(); if (versionCmp(version, "1.7.4-pre-") < 0) { log() << "Can only replay oplog to server version >= 1.7.4" << endl; return -1; } string oplogLimit = getParam( "oplogLimit", "" ); string oplogInc = "0"; if(!oplogLimit.empty()) { size_t i = oplogLimit.find_first_of(':'); if ( i != string::npos ) { if ( i + 1 < oplogLimit.length() ) { oplogInc = oplogLimit.substr(i + 1); } oplogLimit = oplogLimit.substr(0, i); } try { _oplogLimitTS.reset(new OpTime( boost::lexical_cast<unsigned long>(oplogLimit.c_str()), boost::lexical_cast<unsigned long>(oplogInc.c_str()))); } catch( const boost::bad_lexical_cast& error) { log() << "Could not parse oplogLimit into Timestamp from values ( " << oplogLimit << " , " << oplogInc << " )" << endl; return -1; } if (!oplogLimit.empty()) { // Only for a replica set as master will have no-op entries so we would need to // skip them all to find the real op scoped_ptr<DBClientCursor> cursor( conn().query("local.oplog.rs", Query().sort(BSON("$natural" << -1)), 1 /*return first*/)); OpTime tsOptime; // get newest oplog entry and make sure it is older than the limit to apply. if (cursor->more()) { tsOptime = cursor->next().getField("ts")._opTime(); if (tsOptime > *_oplogLimitTS.get()) { log() << "The oplogLimit is not newer than" << " the last oplog entry on the server." << endl; return -1; } } BSONObjBuilder tsRestrictBldr; if (!tsOptime.isNull()) tsRestrictBldr.appendTimestamp("$gt", tsOptime.asDate()); tsRestrictBldr.appendTimestamp("$lt", _oplogLimitTS->asDate()); BSONObj query = BSON("ts" << tsRestrictBldr.obj()); if (!tsOptime.isNull()) { log() << "Latest oplog entry on the server is " << tsOptime.getSecs() << ":" << tsOptime.getInc() << endl; log() << "Only applying oplog entries matching this criteria: " << query.jsonString() << endl; } _opmatcher.reset(new Matcher(query)); } } } /* If _db is not "" then the user specified a db name to restore as. * * In that case we better be given either a root directory that * contains only .bson files or a single .bson file (a db). * * In the case where a collection name is specified we better be * given either a root directory that contains only a single * .bson file, or a single .bson file itself (a collection). */ drillDown(root, _db != "", _coll != "", !(_oplogLimitTS.get() == NULL), true); // should this happen for oplog replay as well? conn().getLastError(_db == "" ? "admin" : _db); if (doOplog) { log() << "\t Replaying oplog" << endl; _curns = OPLOG_SENTINEL; processFile( root / "oplog.bson" ); log() << "Applied " << _oplogEntryApplies << " oplog entries out of " << _oplogEntryApplies + _oplogEntrySkips << " (" << _oplogEntrySkips << " skipped)." << endl; } return EXIT_CLEAN; }
void BuilderObj::append(const OpTime& ot) { pBuilder->appendTimestamp(fieldName, ot.getSecs(), ot.getInc()); }
void BuilderArray::append(const OpTime& ot) { pBuilder->appendTimestamp(ot.getSecs(), ot.getInc()); }