1
0
Fork 0

Fix handling of index name conflicts during replication. (#8571)

This commit is contained in:
Dan Larkin-York 2019-03-28 13:53:43 -04:00 committed by Jan
parent 2d5bf58c94
commit ffc05c05c0
3 changed files with 40 additions and 9 deletions

View File

@ -2238,6 +2238,14 @@ std::shared_ptr<Index> MMFilesCollection::createIndex(transaction::Methods& trx,
if (other) {
// definition shares an identifier with an existing index with a
// different definition
#ifdef ARANGODB_ENABLE_MAINTAINER_MODE
VPackBuilder builder;
other->toVelocyPack(builder, static_cast<std::underlying_type<Index::Serialize>::type>(
Index::Serialize::Basics));
LOG_TOPIC("928ae", WARN, Logger::ENGINES)
<< "attempted to create index '" << info.toJson()
<< "' but found conflicting index '" << builder.slice().toJson() << "'";
#endif
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_ARANGO_DUPLICATE_IDENTIFIER,
"duplicate value for `" +
arangodb::StaticStrings::IndexId +

View File

@ -1285,7 +1285,7 @@ Result DatabaseInitialSyncer::handleCollection(VPackSlice const& parameters,
}
}
// delete any conflicts first
// check any identifier conflicts first
{
// check ID first
TRI_idx_iid_t iid = 0;
@ -1295,9 +1295,13 @@ Result DatabaseInitialSyncer::handleCollection(VPackSlice const& parameters,
// lookup by id
auto byId = physical->lookupIndex(iid);
auto byDef = physical->lookupIndex(idxDef);
if (byId != nullptr && byId != byDef) {
// drop existing byId
physical->dropIndex(byId->id());
if (byId != nullptr) {
if (byDef == nullptr || byId != byDef) {
// drop existing byId
physical->dropIndex(byId->id());
} else {
idx = byId;
}
}
}
@ -1309,15 +1313,26 @@ Result DatabaseInitialSyncer::handleCollection(VPackSlice const& parameters,
// lookup by name
auto byName = physical->lookupIndex(name);
auto byDef = physical->lookupIndex(idxDef);
if (byName != nullptr && byName != byDef) {
// drop existing byName
physical->dropIndex(byName->id());
if (byName != nullptr) {
if (byDef == nullptr || byName != byDef) {
// drop existing byName
physical->dropIndex(byName->id());
} else if (idx != nullptr && byName != idx) {
// drop existing byName and byId
physical->dropIndex(byName->id());
physical->dropIndex(idx->id());
idx = nullptr;
} else {
idx = byName;
}
}
}
}
bool created = false;
idx = physical->createIndex(idxDef, /*restore*/ true, created);
if (idx == nullptr) {
bool created = false;
idx = physical->createIndex(idxDef, /*restore*/ true, created);
}
TRI_ASSERT(idx != nullptr);
}
} catch (arangodb::basics::Exception const& ex) {

View File

@ -367,6 +367,14 @@ std::shared_ptr<Index> RocksDBCollection::createIndex(VPackSlice const& info,
if (other->id() == idx->id() || other->name() == idx->name()) {
// definition shares an identifier with an existing index with a
// different definition
#ifdef ARANGODB_ENABLE_MAINTAINER_MODE
VPackBuilder builder;
other->toVelocyPack(builder, static_cast<std::underlying_type<Index::Serialize>::type>(
Index::Serialize::Basics));
LOG_TOPIC("29d1c", WARN, Logger::ENGINES)
<< "attempted to create index '" << info.toJson()
<< "' but found conflicting index '" << builder.slice().toJson() << "'";
#endif
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_ARANGO_DUPLICATE_IDENTIFIER,
"duplicate value for `" +
arangodb::StaticStrings::IndexId +