summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDwight <dwight@10gen.com>2010-06-30 17:28:57 -0400
committerDwight <dwight@10gen.com>2010-06-30 17:28:57 -0400
commit12663be3f934feaf4443708188f6c8f2aef37f36 (patch)
treefcce0258659dd3b9bc19fc89e009ce3ee4b1637c
parent6aaa45ae24008f269b6b35a38dbbcaea068569ea (diff)
downloadmongo-12663be3f934feaf4443708188f6c8f2aef37f36.tar.gz
defer creating the id index on a clone until we first insert all the data
-rw-r--r--db/cloner.cpp23
-rw-r--r--db/oplog.cpp2
-rw-r--r--db/pdfile.cpp27
-rw-r--r--db/pdfile.h2
4 files changed, 42 insertions, 12 deletions
diff --git a/db/cloner.cpp b/db/cloner.cpp
index c23a3d5f32b..a84b238fee5 100644
--- a/db/cloner.cpp
+++ b/db/cloner.cpp
@@ -165,6 +165,9 @@ namespace mongo {
}
}
+ extern bool inDBRepair;
+ void ensureIdIndexForNewNs(const char *ns);
+
bool Cloner::go(const char *masterHost, string& errmsg, const string& fromdb, bool logForRepl, bool slaveOk, bool useReplAuth, bool snapshot) {
massert( 10289 , "useReplAuth is not written to replication log", !useReplAuth || !logForRepl );
@@ -256,19 +259,37 @@ namespace mongo {
assert(p);
string to_name = todb + p;
+ bool wantIdIndex = false;
{
string err;
const char *toname = to_name.c_str();
- userCreateNS(toname, options, err, logForRepl);
+ /* we defer building id index for performance - building it in batch is much faster */
+ userCreateNS(toname, options, err, logForRepl, &wantIdIndex);
}
log(1) << "\t\t cloning " << from_name << " -> " << to_name << endl;
Query q;
if( snapshot )
q.snapshot();
copy(from_name, to_name.c_str(), false, logForRepl, masterSameProcess, slaveOk, q);
+
+ if( wantIdIndex ) {
+ /* we need dropDups to be true as we didn't do a true snapshot and this is before applying oplog operations
+ that occur during the initial sync. inDBRepair makes dropDups be true.
+ */
+ bool old = inDBRepair;
+ try {
+ inDBRepair = true;
+ ensureIdIndexForNewNs(to_name.c_str());
+ }
+ catch(...) {
+ inDBRepair = old;
+ throw;
+ }
+ }
}
// now build the indexes
+
string system_indexes_from = fromdb + ".system.indexes";
string system_indexes_to = todb + ".system.indexes";
/* [dm]: is the ID index sometimes not called "_id_"? There is other code in the system that looks for a "_id" prefix
diff --git a/db/oplog.cpp b/db/oplog.cpp
index 71cb8863c44..c2727d64970 100644
--- a/db/oplog.cpp
+++ b/db/oplog.cpp
@@ -231,7 +231,7 @@ namespace mongo {
}
/*@ @param opstr:
- c userCreateNs
+ c userCreateNS
i insert
n no-op / keepalive
d delete / remove
diff --git a/db/pdfile.cpp b/db/pdfile.cpp
index d00c51545cb..2da558c5f82 100644
--- a/db/pdfile.cpp
+++ b/db/pdfile.cpp
@@ -123,7 +123,7 @@ namespace mongo {
void ensureIdIndexForNewNs(const char *ns) {
if ( ( strstr( ns, ".system." ) == 0 || legalClientSystemNS( ns , false ) ) &&
strstr( ns, ".$freelist" ) == 0 ){
- log( 1 ) << "adding _id index for new collection" << endl;
+ log( 1 ) << "adding _id index for collection " << ns << endl;
ensureHaveIdIndex( ns );
}
}
@@ -161,7 +161,7 @@ namespace mongo {
return z;
}
- bool _userCreateNS(const char *ns, const BSONObj& options, string& err) {
+ bool _userCreateNS(const char *ns, const BSONObj& options, string& err, bool *deferIdIndex) {
if ( nsdetails(ns) ) {
err = "collection already exists";
return false;
@@ -223,15 +223,22 @@ namespace mongo {
NamespaceDetails *d = nsdetails(ns);
assert(d);
+ bool ensure = false;
if ( options.getField( "autoIndexId" ).type() ) {
if ( options["autoIndexId"].trueValue() ){
- ensureIdIndexForNewNs( ns );
+ ensure = true;
}
} else {
if ( !newCapped ) {
- ensureIdIndexForNewNs( ns );
+ ensure=true;
}
}
+ if( ensure ) {
+ if( deferIdIndex )
+ *deferIdIndex = true;
+ else
+ ensureIdIndexForNewNs( ns );
+ }
if ( mx > 0 )
d->max = mx;
@@ -239,14 +246,16 @@ namespace mongo {
return true;
}
- // { ..., capped: true, size: ..., max: ... }
- // returns true if successful
- bool userCreateNS(const char *ns, BSONObj options, string& err, bool logForReplication) {
+ /** { ..., capped: true, size: ..., max: ... }
+ @param deferIdIndex - if not not, defers id index creation. sets the bool value to true if we wanted to create the id index.
+ @return true if successful
+ */
+ bool userCreateNS(const char *ns, BSONObj options, string& err, bool logForReplication, bool *deferIdIndex) {
const char *coll = strchr( ns, '.' ) + 1;
massert( 10356 , "invalid ns", coll && *coll );
char cl[ 256 ];
nsToDatabase( ns, cl );
- bool ok = _userCreateNS(ns, options, err);
+ bool ok = _userCreateNS(ns, options, err, deferIdIndex);
if ( logForReplication && ok ) {
if ( options.getField( "create" ).eoo() ) {
BSONObjBuilder b;
@@ -679,7 +688,7 @@ namespace mongo {
NamespaceDetails *freeExtents = nsdetails(s.c_str());
if( freeExtents == 0 ) {
string err;
- _userCreateNS(s.c_str(), BSONObj(), err);
+ _userCreateNS(s.c_str(), BSONObj(), err, 0);
freeExtents = nsdetails(s.c_str());
massert( 10361 , "can't create .$freelist", freeExtents);
}
diff --git a/db/pdfile.h b/db/pdfile.h
index 5cef15bd927..0c1293e6f19 100644
--- a/db/pdfile.h
+++ b/db/pdfile.h
@@ -48,7 +48,7 @@ namespace mongo {
/* deletes this ns, indexes and cursors */
void dropCollection( const string &name, string &errmsg, BSONObjBuilder &result );
- bool userCreateNS(const char *ns, BSONObj j, string& err, bool logForReplication);
+ bool userCreateNS(const char *ns, BSONObj j, string& err, bool logForReplication, bool *deferIdIndex = 0);
shared_ptr<Cursor> findTableScan(const char *ns, const BSONObj& order, const DiskLoc &startLoc=DiskLoc());
// -1 if library unavailable.