diff options
Diffstat (limited to 'src/mongo/client/dbclient_rs.cpp')
-rw-r--r-- | src/mongo/client/dbclient_rs.cpp | 263 |
1 files changed, 6 insertions, 257 deletions
diff --git a/src/mongo/client/dbclient_rs.cpp b/src/mongo/client/dbclient_rs.cpp index 4b130c36142..a48fe50a2fa 100644 --- a/src/mongo/client/dbclient_rs.cpp +++ b/src/mongo/client/dbclient_rs.cpp @@ -27,15 +27,13 @@ * it in the license file. */ - -#include "mongo/platform/basic.h" - #include "mongo/client/dbclient_rs.h" #include <memory> #include <utility> #include "mongo/bson/util/builder.h" +#include "mongo/client/client_deprecated.h" #include "mongo/client/connpool.h" #include "mongo/client/dbclient_cursor.h" #include "mongo/client/global_conn_pool.h" @@ -87,42 +85,6 @@ public: */ const size_t MAX_RETRY = 3; -/** - * Extracts the read preference settings from the query document. Note that this method - * assumes that the query is ok for secondaries so it defaults to - * ReadPreference::SecondaryPreferred when nothing is specified. Supports the following - * format: - * - * Format A (official format): - * { query: <actual query>, $readPreference: <read pref obj> } - * - * Format B (unofficial internal format from mongos): - * { <actual query>, $queryOptions: { $readPreference: <read pref obj> }} - * - * @param query the raw query document - * - * @return the read preference setting if a read preference exists, otherwise the default read - * preference of Primary_Only. If the tags field was not present, it will contain one - * empty tag document {} which matches any tag. - * - * @throws AssertionException if the read preference object is malformed - */ -std::unique_ptr<ReadPreferenceSetting> _extractReadPref(const Query& querySettings, - int queryOptions) { - // Default read pref is primary only or secondary preferred with secondaryOK - const auto defaultReadPref = queryOptions & QueryOption_SecondaryOk - ? ReadPreference::SecondaryPreferred - : ReadPreference::PrimaryOnly; - - BSONObj readPrefContainingObj = querySettings.getFullSettingsDeprecated(); - if (auto elem = readPrefContainingObj["$queryOptions"]) { - // The readPreference is embedded in the $queryOptions field. - readPrefContainingObj = elem.Obj(); - } - return std::make_unique<ReadPreferenceSetting>(uassertStatusOK( - ReadPreferenceSetting::fromContainingBSON(readPrefContainingObj, defaultReadPref))); -} - } // namespace // -------------------------------- @@ -538,7 +500,8 @@ void DBClientReplicaSet::remove(const string& ns, } std::unique_ptr<DBClientCursor> DBClientReplicaSet::find(FindCommandRequest findRequest, - const ReadPreferenceSetting& readPref) { + const ReadPreferenceSetting& readPref, + ExhaustMode exhaustMode) { invariant(findRequest.getNamespaceOrUUID().nss()); const std::string nss = findRequest.getNamespaceOrUUID().nss()->ns(); if (_isSecondaryQuery(nss, findRequest.toBSON(BSONObj{}), readPref)) { @@ -562,7 +525,8 @@ std::unique_ptr<DBClientCursor> DBClientReplicaSet::find(FindCommandRequest find break; } - std::unique_ptr<DBClientCursor> cursor = conn->find(findRequest, readPref); + std::unique_ptr<DBClientCursor> cursor = + conn->find(findRequest, readPref, exhaustMode); return checkSecondaryQueryResult(std::move(cursor)); } catch (const DBException& ex) { @@ -587,90 +551,7 @@ std::unique_ptr<DBClientCursor> DBClientReplicaSet::find(FindCommandRequest find "dbclient_rs query to primary node", "replicaSet"_attr = _getMonitor()->getName()); - return checkPrimary()->find(std::move(findRequest), readPref); -} - -unique_ptr<DBClientCursor> DBClientReplicaSet::query_DEPRECATED( - const NamespaceStringOrUUID& nsOrUuid, - const BSONObj& filter, - const Query& querySettings, - int limit, - int nToSkip, - const BSONObj* fieldsToReturn, - int queryOptions, - int batchSize, - boost::optional<BSONObj> readConcernObj) { - shared_ptr<ReadPreferenceSetting> readPref(_extractReadPref(querySettings, queryOptions)); - invariant(nsOrUuid.nss()); - const string ns = nsOrUuid.nss()->ns(); - if (_isSecondaryQuery(ns, filter, *readPref)) { - LOGV2_DEBUG(20133, - 3, - "dbclient_rs query using secondary or tagged node selection in {replicaSet}, " - "read pref is {readPref} " - "(primary : {primary}, lastTagged : {lastTagged})", - "dbclient_rs query using secondary or tagged node selection", - "replicaSet"_attr = _getMonitor()->getName(), - "readPref"_attr = readPref->toString(), - "primary"_attr = - (_primary.get() != nullptr ? _primary->getServerAddress() : "[not cached]"), - "lastTagged"_attr = (_lastSecondaryOkConn.get() != nullptr - ? _lastSecondaryOkConn->getServerAddress() - : "[not cached]")); - - string lastNodeErrMsg; - - for (size_t retry = 0; retry < MAX_RETRY; retry++) { - try { - DBClientConnection* conn = selectNodeUsingTags(readPref); - - if (conn == nullptr) { - break; - } - - unique_ptr<DBClientCursor> cursor = conn->query_DEPRECATED(nsOrUuid, - filter, - querySettings, - limit, - nToSkip, - fieldsToReturn, - queryOptions, - batchSize, - readConcernObj); - - return checkSecondaryQueryResult(std::move(cursor)); - } catch (const DBException& ex) { - const Status status = ex.toStatus(str::stream() << "can't query replica set node " - << _lastSecondaryOkHost); - lastNodeErrMsg = status.reason(); - _invalidateLastSecondaryOkCache(status); - } - } - - StringBuilder assertMsg; - assertMsg << "Failed to do query, no good nodes in " << _getMonitor()->getName(); - if (!lastNodeErrMsg.empty()) { - assertMsg << ", last error: " << lastNodeErrMsg; - } - - uasserted(16370, assertMsg.str()); - } - - LOGV2_DEBUG(20134, - 3, - "dbclient_rs query to primary node in {replicaSet}", - "dbclient_rs query to primary node", - "replicaSet"_attr = _getMonitor()->getName()); - - return checkPrimary()->query_DEPRECATED(nsOrUuid, - filter, - querySettings, - limit, - nToSkip, - fieldsToReturn, - queryOptions, - batchSize, - readConcernObj); + return checkPrimary()->find(std::move(findRequest), readPref, exhaustMode); } void DBClientReplicaSet::killCursor(const NamespaceString& ns, long long cursorID) { @@ -817,70 +698,6 @@ void DBClientReplicaSet::say(Message& toSend, bool isRetry, string* actualServer if (!isRetry) _lastClient = nullptr; - const int lastOp = toSend.operation(); - - if (lastOp == dbQuery) { - // TODO: might be possible to do this faster by changing api - DbMessage dm(toSend); - QueryMessage qm(dm); - - shared_ptr<ReadPreferenceSetting> readPref( - _extractReadPref(Query::fromBSONDeprecated(qm.query), qm.queryOptions)); - if (_isSecondaryQuery(qm.ns, qm.query, *readPref)) { - LOGV2_DEBUG(20141, - 3, - "dbclient_rs say using secondary or tagged node selection in {replicaSet}, " - "read pref is {readPref} " - "(primary : {primary}, lastTagged : {lastTagged})", - "dbclient_rs say using secondary or tagged node selection", - "replicaSet"_attr = _getMonitor()->getName(), - "readPref"_attr = readPref->toString(), - "primary"_attr = (_primary.get() != nullptr ? _primary->getServerAddress() - : "[not cached]"), - "lastTagged"_attr = (_lastSecondaryOkConn.get() != nullptr - ? _lastSecondaryOkConn->getServerAddress() - : "[not cached]")); - - string lastNodeErrMsg; - - for (size_t retry = 0; retry < MAX_RETRY; retry++) { - try { - DBClientConnection* conn = selectNodeUsingTags(readPref); - - if (conn == nullptr) { - break; - } - - if (actualServer != nullptr) { - *actualServer = conn->getServerAddress(); - } - - conn->say(toSend); - - _lastClient = conn; - } catch (const DBException& ex) { - const Status status = - ex.toStatus(str::stream() << "can't callLazy replica set node " - << _lastSecondaryOkHost.toString()); - lastNodeErrMsg = status.reason(); - _invalidateLastSecondaryOkCache(status); - - continue; - } - - return; - } - - StringBuilder assertMsg; - assertMsg << "Failed to call say, no good nodes in " << _getMonitor()->getName(); - if (!lastNodeErrMsg.empty()) { - assertMsg << ", last error: " << lastNodeErrMsg; - } - - uasserted(16380, assertMsg.str()); - } - } - LOGV2_DEBUG(20142, 3, "dbclient_rs say to primary node in {replicaSet}", @@ -982,60 +799,6 @@ bool DBClientReplicaSet::call(Message& toSend, Message& response, bool assertOk, string* actualServer) { - const char* ns = nullptr; - - if (toSend.operation() == dbQuery) { - // TODO: might be possible to do this faster by changing api - DbMessage dm(toSend); - QueryMessage qm(dm); - ns = qm.ns; - - shared_ptr<ReadPreferenceSetting> readPref( - _extractReadPref(Query::fromBSONDeprecated(qm.query), qm.queryOptions)); - if (_isSecondaryQuery(ns, qm.query, *readPref)) { - LOGV2_DEBUG( - 20145, - 3, - "dbclient_rs call using secondary or tagged node selection in {replicaSet}, " - "read pref is {readPref} " - "(primary : {primary}, lastTagged : {lastTagged})", - "dbclient_rs call using secondary or tagged node selection", - "replicaSet"_attr = _getMonitor()->getName(), - "readPref"_attr = readPref->toString(), - "primary"_attr = - (_primary.get() != nullptr ? _primary->getServerAddress() : "[not cached]"), - "lastTagged"_attr = (_lastSecondaryOkConn.get() != nullptr - ? _lastSecondaryOkConn->getServerAddress() - : "[not cached]")); - - for (size_t retry = 0; retry < MAX_RETRY; retry++) { - try { - DBClientConnection* conn = selectNodeUsingTags(readPref); - - if (conn == nullptr) { - return false; - } - - if (actualServer != nullptr) { - *actualServer = conn->getServerAddress(); - } - - return conn->call(toSend, response, assertOk, nullptr); - } catch (const DBException& ex) { - if (actualServer) - *actualServer = ""; - - const Status status = ex.toStatus(); - _invalidateLastSecondaryOkCache(status.withContext( - str::stream() << "can't call replica set node " << _lastSecondaryOkHost)); - } - } - - // Was not able to successfully send after max retries - return false; - } - } - LOGV2_DEBUG(20146, 3, "dbclient_rs call to primary node in {replicaSet}", @@ -1049,20 +812,6 @@ bool DBClientReplicaSet::call(Message& toSend, if (!m->call(toSend, response, assertOk, nullptr)) return false; - if (ns) { - QueryResult::View res = response.singleData().view2ptr(); - if (res.getNReturned() == 1) { - BSONObj x(res.data()); - if (str::contains(ns, "$cmd")) { - if (isNotPrimaryErrorString(x["errmsg"])) - isNotPrimary(); - } else { - if (isNotPrimaryErrorString(getErrField(x))) - isNotPrimary(); - } - } - } - return true; } |