mirror of
https://github.com/mongodb/mongo.git
synced 2024-11-30 00:56:44 +01:00
SERVER-2060 allow an index to be validated for sharding
This commit is contained in:
parent
3907c971ee
commit
95883498e5
40
jstests/check_shard_index.js
Normal file
40
jstests/check_shard_index.js
Normal file
@ -0,0 +1,40 @@
|
||||
// -------------------------
|
||||
// CHECKSHARDINGINDEX TEST UTILS
|
||||
// -------------------------
|
||||
|
||||
f = db.jstests_shardingindex;
|
||||
f.drop();
|
||||
|
||||
|
||||
// -------------------------
|
||||
// Case 1: all entries filled or empty should make a valid index
|
||||
//
|
||||
|
||||
f.drop();
|
||||
f.ensureIndex( { x: 1 , y: 1 } );
|
||||
assert.eq( 0 , f.count() , "1. initial count should be zero" );
|
||||
|
||||
res = db.runCommand( { checkShardingIndex: "test.jstests_shardingindex" , keyPattern: {x:1, y:1} , force: true });
|
||||
assert.eq( true , res.ok, "1a" );
|
||||
|
||||
f.save( { x: 1 , y : 1 } );
|
||||
assert.eq( 1 , f.count() , "1. count after initial insert should be 1" );
|
||||
res = db.runCommand( { checkShardingIndex: "test.jstests_shardingindex" , keyPattern: {x:1, y:1} , force: true });
|
||||
assert.eq( true , res.ok , "1b" );
|
||||
|
||||
|
||||
// -------------------------
|
||||
// Case 2: entry with null values would make an index unsuitable
|
||||
//
|
||||
|
||||
f.drop();
|
||||
f.ensureIndex( { x: 1 , y: 1 } );
|
||||
assert.eq( 0 , f.count() , "2. initial count should be zero" );
|
||||
|
||||
f.save( { x: 1 , y : 1 } );
|
||||
f.save( { y: 2 } );
|
||||
assert.eq( 2 , f.count() , "2. count after initial insert should be 2" );
|
||||
res = db.runCommand( { checkShardingIndex: "test.jstests_shardingindex" , keyPattern: {x:1, y:1} , force: true });
|
||||
assert.eq( false , res.ok , "2a" );
|
||||
|
||||
print("PASSED");
|
@ -124,6 +124,80 @@ namespace mongo {
|
||||
}
|
||||
} cmdMedianKey;
|
||||
|
||||
class CheckShardingIndex : public Command {
|
||||
public:
|
||||
CheckShardingIndex() : Command( "checkShardingIndex" , false ) {}
|
||||
virtual bool slaveOk() const { return false; }
|
||||
virtual LockType locktype() const { return READ; }
|
||||
virtual void help( stringstream &help ) const {
|
||||
help << "Internal command.\n";
|
||||
}
|
||||
|
||||
bool run(const string& dbname, BSONObj& jsobj, string& errmsg, BSONObjBuilder& result, bool fromRepl ) {
|
||||
|
||||
const char* ns = jsobj.getStringField( "checkShardingIndex" );
|
||||
BSONObj keyPattern = jsobj.getObjectField( "keyPattern" );
|
||||
|
||||
// If min and max are not provided use the "minKey" and "maxKey" for the sharding key pattern.
|
||||
BSONObj min = jsobj.getObjectField( "min" );
|
||||
BSONObj max = jsobj.getObjectField( "max" );
|
||||
if ( min.isEmpty() && max.isEmpty() ) {
|
||||
BSONObjBuilder minBuilder;
|
||||
BSONObjBuilder maxBuilder;
|
||||
BSONForEach(key, keyPattern) {
|
||||
minBuilder.appendMinKey( key.fieldName() );
|
||||
maxBuilder.appendMaxKey( key.fieldName() );
|
||||
}
|
||||
min = minBuilder.obj();
|
||||
max = maxBuilder.obj();
|
||||
}
|
||||
else if ( min.isEmpty() || max.isEmpty() ) {
|
||||
errmsg = "either provide both min and max or leave both empty";
|
||||
return false;
|
||||
}
|
||||
|
||||
Client::Context ctx( ns );
|
||||
NamespaceDetails *d = nsdetails( ns );
|
||||
if ( ! d ) {
|
||||
errmsg = "ns not found";
|
||||
return false;
|
||||
}
|
||||
|
||||
IndexDetails *idx = cmdIndexDetailsForRange( ns , errmsg , min , max , keyPattern );
|
||||
if ( idx == NULL ) {
|
||||
errmsg = "couldn't find index over splitting key";
|
||||
return false;
|
||||
}
|
||||
|
||||
BtreeCursor * bc = new BtreeCursor( d , d->idxNo(*idx) , *idx , min , max , false , 1 );
|
||||
shared_ptr<Cursor> c( bc );
|
||||
scoped_ptr<ClientCursor> cc( new ClientCursor( QueryOption_NoCursorTimeout , c , ns ) );
|
||||
if ( ! cc->ok() ) {
|
||||
// range is empty
|
||||
return true;
|
||||
}
|
||||
|
||||
// for now, the only check is that all shard keys are filled
|
||||
// TODO if $exist for nulls were picking the index, it could be used instead efficiently
|
||||
while ( cc->ok() ) {
|
||||
BSONObj currKey = c->currKey();
|
||||
BSONForEach(key, currKey) {
|
||||
if ( key.type() == jstNULL ) {
|
||||
ostringstream os;
|
||||
os << "found null value in key " << bc->prettyKey( currKey );
|
||||
log() << "checkShardingIndex for '" << ns << "' failed: " << os.str() << endl;
|
||||
|
||||
errmsg = os.str();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
cc->advance();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
} cmdCheckShardingIndex;
|
||||
|
||||
class SplitVector : public Command {
|
||||
public:
|
||||
SplitVector() : Command( "splitVector" , false ) {}
|
||||
|
Loading…
Reference in New Issue
Block a user