mirror of https://gitee.com/bigwinds/arangodb
fix deadlocks in cluster traversals (#3198)
This commit is contained in:
parent
f49e0ca237
commit
cd2dfdfd0d
|
@ -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...
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue