summaryrefslogtreecommitdiff
path: root/src/mongo/s/chunk_version.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/s/chunk_version.cpp')
-rw-r--r--src/mongo/s/chunk_version.cpp189
1 files changed, 2 insertions, 187 deletions
diff --git a/src/mongo/s/chunk_version.cpp b/src/mongo/s/chunk_version.cpp
index 8da764c2080..ca260776a34 100644
--- a/src/mongo/s/chunk_version.cpp
+++ b/src/mongo/s/chunk_version.cpp
@@ -30,7 +30,6 @@
#include "mongo/s/chunk_version.h"
#include "mongo/s/chunk_version_gen.h"
-#include "mongo/s/pm2583_feature_flags_gen.h"
#include "mongo/util/str.h"
namespace mongo {
@@ -57,165 +56,12 @@ std::string CollectionGeneration::toString() const {
return str::stream() << _epoch << "|" << _timestamp;
}
-ChunkVersion ChunkVersion::_parseArrayOrObjectPositionalFormat(const BSONObj& obj) {
- BSONObjIterator it(obj);
- uassert(ErrorCodes::BadValue, "Unexpected empty version array", it.more());
-
- // Expect the major and minor versions (must be present)
- uint64_t combined;
- {
- BSONElement tsPart = it.next();
- uassert(ErrorCodes::TypeMismatch,
- str::stream() << "Invalid type " << tsPart.type()
- << " for version major and minor part.",
- tsPart.type() == bsonTimestamp);
- combined = tsPart.timestamp().asULL();
- }
-
- // Expect the epoch OID (must be present)
- boost::optional<OID> epoch;
- {
- BSONElement epochPart = it.next();
- uassert(ErrorCodes::TypeMismatch,
- str::stream() << "Invalid type " << epochPart.type() << " for version epoch part.",
- epochPart.type() == jstOID);
- epoch = epochPart.OID();
- }
-
- BSONElement nextElem = it.next();
-
- // TODO SERVER-59105: remove once 6.0 is last-lts. For backward compatibility reasons 5.0
- // routers sends canThrowSSVOnIgnored even though it is not used, so we attempt to parse and
- // ignore it.
- if (nextElem.type() == BSONType::Bool) {
- nextElem = it.next();
- }
-
- // Check for timestamp
- boost::optional<Timestamp> timestamp;
- if (nextElem.type() == bsonTimestamp) {
- timestamp = nextElem.timestamp();
- } else if (nextElem.eoo() && (epoch == UNSHARDED().epoch() || epoch == IGNORED().epoch())) {
- // In 5.0 binaries, the timestamp is not present in UNSHARDED and IGNORED versions
- timestamp =
- (epoch == UNSHARDED().epoch() ? UNSHARDED().getTimestamp() : IGNORED().getTimestamp());
- } else {
- uasserted(ErrorCodes::TypeMismatch,
- str::stream() << "Invalid type " << nextElem.type()
- << " for version timestamp part.");
- }
-
- ChunkVersion version;
- version._combined = combined;
- version._epoch = *epoch;
- version._timestamp = *timestamp;
- return version;
-}
-
-StatusWith<ChunkVersion> ChunkVersion::_parseLegacyWithField(const BSONObj& obj, StringData field) {
- // Expect the major and minor (must always exist)
- uint64_t combined;
- {
- auto versionElem = obj[field];
- if (versionElem.eoo())
- return {ErrorCodes::NoSuchKey,
- str::stream() << "Expected field " << field << " not found."};
-
- if (versionElem.type() == bsonTimestamp || versionElem.type() == Date) {
- combined = versionElem._numberLong();
- } else {
- return {ErrorCodes::TypeMismatch,
- str::stream() << "Invalid type " << versionElem.type()
- << " for version major and minor part."};
- }
- }
-
- // Expect the epoch OID
- //
- // TODO: Confirm whether the epoch can still be missing in upgrade chains that started from
- // pre-2.4 versions anymore (after FCV 4.4 -> 5.0 upgrade) ?
- boost::optional<OID> epoch;
- {
- const auto epochField = field + "Epoch";
- auto epochElem = obj[epochField];
- if (epochElem.type() == jstOID) {
- epoch = epochElem.OID();
- } else if (!epochElem.eoo()) {
- return {ErrorCodes::TypeMismatch,
- str::stream() << "Invalid type " << epochElem.type()
- << " for version epoch part."};
- }
- }
-
- // Expect the timestamp (can be missing only in the case of pre-5.0 UNSHARDED and IGNORED
- // versions)
- boost::optional<Timestamp> timestamp;
- {
- const auto timestampField = field + "Timestamp";
- auto timestampElem = obj[timestampField];
- if (timestampElem.type() == bsonTimestamp) {
- timestamp = timestampElem.timestamp();
- } else if (!timestampElem.eoo()) {
- return {ErrorCodes::TypeMismatch,
- str::stream() << "Invalid type " << timestampElem.type()
- << " for version timestamp part."};
- }
- }
-
- if (epoch && timestamp) {
- // Expected situation
- } else if (epoch && !timestamp) {
- if (epoch == UNSHARDED().epoch() || epoch == IGNORED().epoch()) {
- // In 5.0 binaries, the timestamp is not present in UNSHARDED and IGNORED versions
- timestamp = (epoch == UNSHARDED().epoch() ? UNSHARDED().getTimestamp()
- : IGNORED().getTimestamp());
- } else {
- uasserted(6278300, "Timestamp must be present if epoch exists.");
- }
- } else if (!epoch && timestamp) {
- uasserted(6278301, "Epoch must be present if timestamp exists.");
- } else {
- // Can happen in upgrade chains that started from pre-2.4 versions or in the case of
- // persistence for ShardCollectionType
- }
-
- ChunkVersion version;
- version._combined = combined;
- version._epoch = epoch.value_or(OID());
- version._timestamp = timestamp.value_or(Timestamp());
- return version;
-}
-
-ChunkVersion ChunkVersion::fromBSONLegacyOrNewerFormat(const BSONObj& obj, StringData field) {
- // New format.
- if (obj[field].isABSONObj()) {
- return parse(obj[field]);
- }
-
- // Legacy format.
- return uassertStatusOK(ChunkVersion::_parseLegacyWithField(obj, field));
-}
-
-ChunkVersion ChunkVersion::fromBSONPositionalOrNewerFormat(const BSONElement& element) {
- auto obj = element.Obj();
-
- // Positional or wrongly encoded format.
- if (obj.couldBeArray()) {
- return ChunkVersion::_parseArrayOrObjectPositionalFormat(obj);
- }
-
- // New format.
- return parse(element);
-}
-
ChunkVersion ChunkVersion::parse(const BSONElement& element) {
auto parsedVersion =
ChunkVersion60Format::parse(IDLParserErrorContext("ChunkVersion"), element.Obj());
auto version = parsedVersion.getVersion();
- return ChunkVersion(version.getSecs(),
- version.getInc(),
- parsedVersion.getEpoch(),
- parsedVersion.getTimestamp());
+ return ChunkVersion({parsedVersion.getEpoch(), parsedVersion.getTimestamp()},
+ {version.getSecs(), version.getInc()});
}
void ChunkVersion::serializeToBSON(StringData field, BSONObjBuilder* builder) const {
@@ -225,40 +71,9 @@ void ChunkVersion::serializeToBSON(StringData field, BSONObjBuilder* builder) co
builder->append(field, version.toBSON());
}
-void ChunkVersion::appendLegacyWithField(BSONObjBuilder* out, StringData field) const {
- if (feature_flags::gFeatureFlagNewPersistedChunkVersionFormat.isEnabled(
- serverGlobalParams.featureCompatibility)) {
- ChunkVersion60Format version;
- version.setGeneration({_epoch, _timestamp});
- version.setPlacement(Timestamp(majorVersion(), minorVersion()));
- out->append(field, version.toBSON());
- } else {
- out->appendTimestamp(field, _combined);
- out->append(field + "Epoch", _epoch);
- out->append(field + "Timestamp", _timestamp);
- }
-}
-
std::string ChunkVersion::toString() const {
return str::stream() << majorVersion() << "|" << minorVersion() << "||" << _epoch << "||"
<< _timestamp.toString();
}
-ChunkVersion ChunkVersion::parseMajorMinorVersionOnlyFromShardCollectionType(
- const BSONElement& element) {
- uassert(ErrorCodes::TypeMismatch,
- str::stream() << "Invalid type " << element.type()
- << " for version major and minor part.",
- element.type() == bsonTimestamp || element.type() == Date);
-
- ChunkVersion version;
- version._combined = element._numberLong();
- return version;
-}
-
-void ChunkVersion::serialiseMajorMinorVersionOnlyForShardCollectionType(StringData field,
- BSONObjBuilder* out) const {
- out->appendTimestamp(field, toLong());
-}
-
} // namespace mongo