summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--SConstruct2
-rw-r--r--tools/oplog.cpp104
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 );
+}