2010-09-22 11:16:44 -04:00
|
|
|
// @file d_logic.cpp
|
2009-03-11 17:28:49 -04:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 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/>.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
these are commands that live in mongod
|
|
|
|
|
mostly around shard management and checking
|
|
|
|
|
*/
|
|
|
|
|
|
2010-04-27 15:27:52 -04:00
|
|
|
#include "pch.h"
|
2009-03-11 17:28:49 -04:00
|
|
|
#include <map>
|
|
|
|
|
#include <string>
|
|
|
|
|
|
|
|
|
|
#include "../db/commands.h"
|
|
|
|
|
#include "../db/jsobj.h"
|
2009-03-17 17:25:10 -04:00
|
|
|
#include "../db/dbmessage.h"
|
2011-06-22 15:51:08 -04:00
|
|
|
#include "../db/ops/query.h"
|
2009-03-11 17:28:49 -04:00
|
|
|
|
2009-04-06 15:57:17 -04:00
|
|
|
#include "../client/connpool.h"
|
|
|
|
|
|
2009-04-17 17:11:32 -04:00
|
|
|
#include "../util/queue.h"
|
|
|
|
|
|
2010-04-19 16:59:50 -04:00
|
|
|
#include "shard.h"
|
2010-06-11 15:12:25 -04:00
|
|
|
#include "d_logic.h"
|
2010-09-22 11:16:44 -04:00
|
|
|
#include "d_writeback.h"
|
2010-04-19 16:59:50 -04:00
|
|
|
|
2009-03-11 17:28:49 -04:00
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
|
|
namespace mongo {
|
2010-06-14 18:44:51 -04:00
|
|
|
|
2011-01-12 16:11:47 -05:00
|
|
|
bool _handlePossibleShardedMessage( Message &m, DbResponse* dbresponse ) {
|
|
|
|
|
DEV assert( shardingState.enabled() );
|
2009-12-27 00:41:39 -05:00
|
|
|
|
2010-05-12 15:26:00 -07:00
|
|
|
int op = m.operation();
|
2011-01-04 00:40:41 -05:00
|
|
|
if ( op < 2000
|
|
|
|
|
|| op >= 3000
|
|
|
|
|
|| op == dbGetMore // cursors are weird
|
|
|
|
|
)
|
2009-03-17 17:25:10 -04:00
|
|
|
return false;
|
2011-01-04 00:40:41 -05:00
|
|
|
|
|
|
|
|
DbMessage d(m);
|
2010-07-22 23:05:02 -04:00
|
|
|
const char *ns = d.getns();
|
2009-03-17 17:25:10 -04:00
|
|
|
string errmsg;
|
2011-03-25 09:59:50 -04:00
|
|
|
if ( shardVersionOk( ns , errmsg ) ) {
|
2009-03-17 17:25:10 -04:00
|
|
|
return false;
|
2009-11-24 17:28:57 -05:00
|
|
|
}
|
2010-07-23 13:41:21 -04:00
|
|
|
|
2011-08-08 17:37:04 -04:00
|
|
|
LOG(1) << "connection meta data too old - will retry ns:(" << ns << ") op:(" << opToString(op) << ") " << errmsg << endl;
|
2011-01-04 00:40:41 -05:00
|
|
|
|
|
|
|
|
if ( doesOpGetAResponse( op ) ) {
|
2010-07-23 13:41:21 -04:00
|
|
|
assert( dbresponse );
|
2009-03-17 17:25:10 -04:00
|
|
|
BufBuilder b( 32768 );
|
|
|
|
|
b.skip( sizeof( QueryResult ) );
|
|
|
|
|
{
|
|
|
|
|
BSONObj obj = BSON( "$err" << errmsg );
|
2010-07-19 09:56:24 -04:00
|
|
|
b.appendBuf( obj.objdata() , obj.objsize() );
|
2009-03-17 17:25:10 -04:00
|
|
|
}
|
2011-01-04 00:40:41 -05:00
|
|
|
|
2009-03-17 17:25:10 -04:00
|
|
|
QueryResult *qr = (QueryResult*)b.buf();
|
2010-07-18 13:34:16 -04:00
|
|
|
qr->_resultFlags() = ResultFlag_ErrSet | ResultFlag_ShardConfigStale;
|
2009-03-17 17:25:10 -04:00
|
|
|
qr->len = b.len();
|
|
|
|
|
qr->setOperation( opReply );
|
|
|
|
|
qr->cursorId = 0;
|
|
|
|
|
qr->startingFrom = 0;
|
|
|
|
|
qr->nReturned = 1;
|
|
|
|
|
b.decouple();
|
|
|
|
|
|
|
|
|
|
Message * resp = new Message();
|
|
|
|
|
resp->setData( qr , true );
|
2011-01-04 00:40:41 -05:00
|
|
|
|
2010-07-23 13:41:21 -04:00
|
|
|
dbresponse->response = resp;
|
|
|
|
|
dbresponse->responseTo = m.header()->id;
|
2009-03-17 17:25:10 -04:00
|
|
|
return true;
|
|
|
|
|
}
|
2011-07-08 13:23:25 -04:00
|
|
|
|
|
|
|
|
uassert( 9517 , "writeback" , ( d.reservedField() & DbMessage::Reserved_FromWriteback ) == 0 );
|
2011-01-04 00:40:41 -05:00
|
|
|
|
2010-07-22 13:52:42 -04:00
|
|
|
OID writebackID;
|
|
|
|
|
writebackID.init();
|
|
|
|
|
lastError.getSafe()->writeback( writebackID );
|
|
|
|
|
|
2010-06-14 18:44:51 -04:00
|
|
|
const OID& clientID = ShardedConnectionInfo::get(false)->getID();
|
|
|
|
|
massert( 10422 , "write with bad shard config and no server id!" , clientID.isSet() );
|
2011-01-04 00:40:41 -05:00
|
|
|
|
2011-08-08 17:37:04 -04:00
|
|
|
LOG(1) << "got write with an old config - writing back ns: " << ns << endl;
|
2011-09-28 08:14:46 -04:00
|
|
|
LOG(1) << m.toString() << endl;
|
2010-07-23 17:14:49 -04:00
|
|
|
|
2009-04-18 21:55:34 -04:00
|
|
|
BSONObjBuilder b;
|
|
|
|
|
b.appendBool( "writeBack" , true );
|
|
|
|
|
b.append( "ns" , ns );
|
2010-07-22 13:52:42 -04:00
|
|
|
b.append( "id" , writebackID );
|
2011-01-03 14:12:32 -05:00
|
|
|
b.append( "connectionId" , cc().getConnectionId() );
|
2011-05-11 13:30:12 -04:00
|
|
|
b.append( "instanceIdent" , prettyHostName() );
|
2010-07-14 14:31:14 -04:00
|
|
|
b.appendTimestamp( "version" , shardingState.getVersion( ns ) );
|
2011-09-28 13:10:51 -04:00
|
|
|
|
|
|
|
|
ShardedConnectionInfo* info = ShardedConnectionInfo::get( false );
|
|
|
|
|
b.appendTimestamp( "yourVersion" , info ? info->getVersion(ns) : (ConfigVersion)0 );
|
|
|
|
|
|
2010-05-12 15:26:00 -07:00
|
|
|
b.appendBinData( "msg" , m.header()->len , bdtCustom , (char*)(m.singleData()) );
|
2011-08-08 17:37:04 -04:00
|
|
|
LOG(2) << "writing back msg with len: " << m.header()->len << " op: " << m.operation() << endl;
|
2010-09-22 11:16:44 -04:00
|
|
|
writeBackManager.queueWriteBack( clientID.str() , b.obj() );
|
2009-04-18 21:55:34 -04:00
|
|
|
|
2009-03-17 17:25:10 -04:00
|
|
|
return true;
|
|
|
|
|
}
|
2009-11-03 10:35:48 -05:00
|
|
|
|
2009-03-11 17:28:49 -04:00
|
|
|
}
|