Ejemplo n.º 1
0
/**
 * Special internal logic to run reduced version handshake for empty namespace operations to
 * shards.
 *
 * Eventually this should go completely away, but for now many commands rely on unversioned but
 * mongos-specific behavior on mongod (auditing and replication information in commands)
 */
static bool initShardVersionEmptyNS(DBClientBase* conn_in) {
    bool ok;
    BSONObj result;
    DBClientBase* conn = NULL;
    try {
        // May throw if replica set primary is down
        conn = getVersionable(conn_in);
        dassert(conn);  // errors thrown above

        // Check to see if we've already initialized this connection
        if (connectionShardStatus.hasAnySequenceSet(conn))
            return false;

        // Check to see if this is actually a shard and not a single config server
        // NOTE: Config servers are registered only by the name "config" in the shard cache, not
        // by host, so lookup by host will fail unless the host is also a shard.
        const auto shard = grid.shardRegistry()->getShard(conn->getServerAddress());
        if (!shard) {
            return false;
        }

        LOG(1) << "initializing shard connection to " << shard->toString() << endl;

        ok = setShardVersion(*conn,
                             "",
                             grid.catalogManager()->connectionString().toString(),
                             ChunkVersion(),
                             NULL,
                             true,
                             result);
    } catch (const DBException&) {
        // NOTE: Replica sets may fail to initShardVersion because future calls relying on
        // correct versioning must later call checkShardVersion on the primary.
        // Secondary queries and commands may not call checkShardVersion, but secondary ops
        // aren't versioned at all.
        if (conn_in->type() != ConnectionString::SET) {
            throw;
        }

        // NOTE: Only old-style cluster operations will talk via DBClientReplicaSets - using
        // checkShardVersion is required (which includes initShardVersion information) if these
        // connections are used.

        OCCASIONALLY {
            warning() << "failed to initialize new replica set connection version, "
                      << "will initialize on first use" << endl;
        }

        return false;
    }

    // Record the connection wire version if sent in the response, initShardVersion is a
    // handshake for mongos->mongod connections.
    if (!result["minWireVersion"].eoo()) {
        int minWireVersion = result["minWireVersion"].numberInt();
        int maxWireVersion = result["maxWireVersion"].numberInt();
        conn->setWireVersions(minWireVersion, maxWireVersion);
    }

    LOG(3) << "initial sharding result : " << result << endl;

    connectionShardStatus.setSequence(conn, "", 0);
    return ok;
}
Ejemplo n.º 2
0
    bool VersionManager::initShardVersionCB( DBClientBase * conn_in, BSONObj& result ){

        WriteBackListener::init( *conn_in );

        bool ok;
        DBClientBase* conn = NULL;
        try {
            // May throw if replica set primary is down
            conn = getVersionable( conn_in );
            dassert( conn ); // errors thrown above

            BSONObjBuilder cmdBuilder;

            cmdBuilder.append( "setShardVersion" , "" );
            cmdBuilder.appendBool( "init", true );
            cmdBuilder.append( "configdb" , configServer.modelServer() );
            cmdBuilder.appendOID( "serverID" , &serverID );
            cmdBuilder.appendBool( "authoritative" , true );

            BSONObj cmd = cmdBuilder.obj();

            LOG(1) << "initializing shard connection to " << conn->toString() << endl;
            LOG(2) << "initial sharding settings : " << cmd << endl;

            ok = conn->runCommand("admin", cmd, result, 0);
        }
        catch( const DBException& ) {

            if ( conn_in->type() != ConnectionString::SET ) {
                throw;
            }

            // NOTE: Only old-style cluster operations will talk via DBClientReplicaSets - using
            // checkShardVersion is required (which includes initShardVersion information) if these
            // connections are used.

            OCCASIONALLY {
                warning() << "failed to initialize new replica set connection version, "
                          << "will initialize on first use" << endl;
            }

            return true;
        }

        // HACK for backwards compatibility with v1.8.x, v2.0.0 and v2.0.1
        // Result is false, but will still initialize serverID and configdb
        if( ! ok && ! result["errmsg"].eoo() && ( result["errmsg"].String() == "need to specify namespace"/* 2.0.1/2 */ ||
                                                  result["errmsg"].String() == "need to speciy namespace" /* 1.8 */ ))
        {
            ok = true;
        }

        // Record the connection wire version if sent in the response, initShardVersion is a
        // handshake for mongos->mongod connections.
        if ( !result["minWireVersion"].eoo() ) {

            int minWireVersion = result["minWireVersion"].numberInt();
            int maxWireVersion = result["maxWireVersion"].numberInt();
            conn->setWireVersions( minWireVersion, maxWireVersion );
        }

        LOG(3) << "initial sharding result : " << result << endl;

        return ok;

    }