1
0
Fork 0

fix deadlocks in cluster traversals (#3198)

This commit is contained in:
Jan 2017-09-04 17:35:24 +02:00 committed by Frank Celler
parent f49e0ca237
commit cd2dfdfd0d
7 changed files with 19 additions and 16 deletions

View File

@ -201,8 +201,8 @@ void BaseEngine::getVertexData(VPackSlice vertex, VPackBuilder& builder) {
auto shards = _vertexShards.find(shardName);
if (shards == _vertexShards.end()) {
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_QUERY_COLLECTION_LOCK_FAILED,
"Collection not known to Traversal " +
shardName + " please add 'WITH " + shardName +
"collection not known to traversal: '" +
shardName + "'. please add 'WITH " + shardName +
"' as the first line in your AQL");
// The collection is not known here!
// Maybe handle differently
@ -210,11 +210,11 @@ void BaseEngine::getVertexData(VPackSlice vertex, VPackBuilder& builder) {
StringRef vertex = id.substr(pos+1);
for (std::string const& shard : shards->second) {
Result res = _trx->documentFastPathLocal(shard, vertex, mmdr);
Result res = _trx->documentFastPathLocal(shard, vertex, mmdr, false);
if (res.ok()) {
// FOUND short circuit.
builder.add(v);
mmdr.addToBuilder(builder, true);
mmdr.addToBuilder(builder, false);
break;
} else if (res.isNot(TRI_ERROR_ARANGO_DOCUMENT_NOT_FOUND)) {
// We are in a very bad condition here...
@ -317,8 +317,8 @@ void BaseTraverserEngine::getVertexData(VPackSlice vertex, size_t depth,
auto shards = _vertexShards.find(shardName);
if (shards == _vertexShards.end()) {
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_QUERY_COLLECTION_LOCK_FAILED,
"Collection not known to Traversal " +
shardName + " please add 'WITH " + shardName +
"collection not known to traversal: '" +
shardName + "'. please add 'WITH " + shardName +
"' as the first line in your AQL");
// The collection is not known here!
// Maybe handle differently
@ -326,12 +326,12 @@ void BaseTraverserEngine::getVertexData(VPackSlice vertex, size_t depth,
StringRef vertex = id.substr(pos+1);
for (std::string const& shard : shards->second) {
Result res = _trx->documentFastPathLocal(shard, vertex, mmdr);
Result res = _trx->documentFastPathLocal(shard, vertex, mmdr, false);
if (res.ok()) {
// FOUND short circuit.
read++;
builder.add(v);
mmdr.addToBuilder(builder, true);
mmdr.addToBuilder(builder, false);
break;
} else if (res.isNot(TRI_ERROR_ARANGO_DOCUMENT_NOT_FOUND)) {
// We are in a very bad condition here...

View File

@ -64,7 +64,7 @@ VPackSlice TraverserCache::lookupInCollection(StringRef id) {
return basics::VelocyPackHelper::NullValue();
}
Result res = _trx->documentFastPathLocal(id.substr(0, pos).toString(),
id.substr(pos + 1), *_mmdr);
id.substr(pos + 1), *_mmdr, true);
if (res.ok()) {
++_insertedDocuments;
return VPackSlice(_mmdr->vpack());

View File

@ -259,7 +259,7 @@ static AqlValue buildGeoResult(transaction::Methods* trx,
} else {
for (auto& it : distances) {
if (collection->readDocument(trx, it._token, mmdr)) {
mmdr.addToBuilder(*builder.get(), true);
mmdr.addToBuilder(*builder.get(), false);
}
}
}

View File

@ -407,7 +407,7 @@ Result RocksDBFulltextIndex::executeQuery(transaction::Methods* trx,
while (maxResults > 0 && it != resultSet.cend()) {
RocksDBToken token(*it);
if (token.revisionId() && physical->readDocument(trx, token, mmdr)) {
mmdr.addToBuilder(builder, true);
mmdr.addToBuilder(builder, false);
maxResults--;
}
++it;

View File

@ -1028,7 +1028,7 @@ Result transaction::Methods::documentFastPath(std::string const& collectionName,
/// Must only be called on a local server, not in cluster case!
Result transaction::Methods::documentFastPathLocal(
std::string const& collectionName, StringRef const& key,
ManagedDocumentResult& result) {
ManagedDocumentResult& result, bool shouldLock) {
TRI_ASSERT(_state->status() == transaction::Status::RUNNING);
TRI_voc_cid_t cid = addCollectionAtRuntime(collectionName);
@ -1043,7 +1043,7 @@ Result transaction::Methods::documentFastPathLocal(
bool isLocked = trxColl->isLocked(AccessMode::Type::READ,
_state->nestingLevel());
Result res = collection->read(this, key, result, !isLocked);
Result res = collection->read(this, key, result, shouldLock && !isLocked);
TRI_ASSERT(res.fail() || isPinned(cid));
return res;
}

View File

@ -255,7 +255,8 @@ class Methods {
/// Must only be called on a local server, not in cluster case!
Result documentFastPathLocal(std::string const& collectionName,
StringRef const& key,
ManagedDocumentResult& result);
ManagedDocumentResult& result,
bool shouldLock);
/// @brief return one or multiple documents from a collection
OperationResult document(std::string const& collectionName,

View File

@ -105,9 +105,11 @@ void ManagedDocumentResult::reset() noexcept {
void ManagedDocumentResult::addToBuilder(velocypack::Builder& builder, bool allowExternals) const {
TRI_ASSERT(!empty());
auto slice = velocypack::Slice(_vpack);
TRI_ASSERT(!slice.isExternal());
if (allowExternals && canUseInExternal()) {
builder.add(velocypack::Slice(_vpack));
builder.addExternal(slice.begin());
} else {
builder.add(velocypack::Slice(_vpack));
builder.add(slice);
}
}