diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | SConstruct | 2 | ||||
-rw-r--r-- | tools/oplog.cpp | 104 |
3 files changed, 106 insertions, 1 deletions
diff --git a/.gitignore b/.gitignore index 26afcdef478..ebfc7f44527 100644 --- a/.gitignore +++ b/.gitignore @@ -79,6 +79,7 @@ mongosniff mongobridge mongostat mongotop +mongooplog bsondump *.tgz diff --git a/SConstruct b/SConstruct index 4e46052a6d8..fb3a85ce166 100644 --- a/SConstruct +++ b/SConstruct @@ -1081,7 +1081,7 @@ Default( mongod ) # tools allToolFiles = commonFiles + coreDbFiles + coreServerFiles + serverOnlyFiles + [ "client/gridfs.cpp", "tools/tool.cpp" ] -normalTools = [ "dump" , "restore" , "export" , "import" , "files" , "stat" , "top" ] +normalTools = [ "dump" , "restore" , "export" , "import" , "files" , "stat" , "top" , "oplog" ] env.Alias( "tools" , [ add_exe( "mongo" + x ) for x in normalTools ] ) for x in normalTools: env.Program( "mongo" + x , allToolFiles + [ "tools/" + x + ".cpp" ] ) diff --git a/tools/oplog.cpp b/tools/oplog.cpp new file mode 100644 index 00000000000..5ebb38e4096 --- /dev/null +++ b/tools/oplog.cpp @@ -0,0 +1,104 @@ +// oplog.cpp + +/** +* Copyright (C) 2008 10gen Inc. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Affero General Public License, version 3, +* as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Affero General Public License for more details. +* +* You should have received a copy of the GNU Affero General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "pch.h" +#include "client/dbclient.h" +#include "db/json.h" +#include "db/oplogreader.h" + +#include "tool.h" + +#include <fstream> +#include <iostream> + +#include <boost/program_options.hpp> + +using namespace mongo; + +namespace po = boost::program_options; + +class OplogTool : public Tool { +public: + OplogTool() : Tool( "oplog" ) { + addFieldOptions(); + add_options() + ("seconds,s" , po::value<int>() , "seconds to go back default:86400" ) + ("from", po::value<string>() , "host to pull from" ) + ("oplogns", po::value<string>()->default_value( "local.oplog.rs" ) , "ns to pull from" ) + ; + } + + int run() { + + if ( ! hasParam( "from" ) ) { + log() << "need to specify --from" << endl; + return -1; + } + + Client::initThread( "oplogreplay" ); + + log() << "going to connect" << endl; + + OplogReader r; + r.connect( getParam( "from" ) ); + + log() << "connected" << endl; + + OpTime start( time(0) - getParam( "seconds" , 86400 ) , 0 ); + log() << "starting from " << start.toStringPretty() << endl; + + string ns = getParam( "oplogns" ); + r.tailingQueryGTE( ns.c_str() , start ); + + int num = 0; + while ( r.more() ) { + BSONObj o = r.next(); + + bool print = ++num % 100000 == 0; + if ( print ) + cout << num << "\t" << o << endl; + + if ( o["op"].String() == "n" ) + continue; + + if ( o["op"].String() == "c" ) { + cout << "skipping: " << o << endl; + continue; + } + + BSONObjBuilder b( o.objsize() + 32 ); + BSONArrayBuilder updates( b.subarrayStart( "applyOps" ) ); + updates.append( o ); + updates.done(); + + BSONObj c = b.obj(); + + BSONObj res; + conn().runCommand( "admin" , c , res ); + if ( print ) + cout << res << endl; + } + + return 0; + } +}; + +int main( int argc , char** argv ) { + OplogTool t; + return t.main( argc , argv ); +} |