8000 Lower priority of AQL lanes by goedderz · Pull Request #14695 · arangodb/arangodb · GitHub
[go: up one dir, main page]

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
devel
-----

* Reduce internal priority of AQL execution. This prevents possible deadlocks
with modification operations in a cluster and replicationFactor >= 2, and can
also improve responsiveness under high load of AQL queries.

* Updated arangosync to 2.6.0.

* Fix a potential multi-threading issue in index creation on coordinators,
Expand Down
2 changes: 1 addition & 1 deletion arangod/Aql/Query.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1265,7 +1265,7 @@ futures::Future<Result> finishDBServerParts(Query& query, ErrorCode errorCode) {
network::RequestOptions options;
options.database = query.vocbase().name();
options.timeout = network::Timeout(60.0); // Picked arbitrarily
options.continuationLane = RequestLane::CLUSTER_AQL_CONTINUATION;
options.continuationLane = RequestLane::CLUSTER_AQL_INTERNAL_COORDINATOR;
// options.skipScheduler = true;

VPackBuffer<uint8_t> body;
Expand Down
8 changes: 8 additions & 0 deletions
Original file line number Diff line number Diff line change
Expand Up @@ -857,3 +857,11 @@ RestStatus RestAqlHandler::handleFinishQuery(std::string const& idString) {
generateResult(rest::ResponseCode::OK, std::move(buffer));
}));
}

RequestLane RestAqlHandler::lane() const {
if (ServerState::instance()->isCoordinator()) {
return RequestLane::CLUSTER_AQL_INTERNAL_COORDINATOR;
} else {
return RequestLane::CLUSTER_AQL;
}
}
2 changes: 1 addition & 1 deletion arangod/Aql/RestAqlHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class RestAqlHandler : public RestVocbaseBaseHandler {

public:
char const* name() const override final { return "RestAqlHandler"; }
RequestLane lane() const override final { return RequestLane::CLUSTER_AQL; }
RequestLane lane() const override final;
RestStatus execute() override;
RestStatus continueExecute() override;
void shutdownExecute(bool isFinalized) noexcept override;
Expand Down
62 changes: 33 additions & 29 deletions arangod/Aql/SharedQueryState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "ApplicationFeatures/ApplicationServer.h"
#include "Basics/Exceptions.h"
#include "Basics/ScopeGuard.h"
#include "Cluster/ServerState.h"
#include "RestServer/QueryRegistryFeature.h"
#include "Scheduler/Scheduler.h"
#include "Scheduler/SchedulerFeature.h"
Expand Down Expand Up @@ -129,34 +130,37 @@ void SharedQueryState::queueHandler() {
return;
}

bool queued =
scheduler->queue(RequestLane::CLUSTER_AQL_CONTINUATION,
[self = shared_from_this(), cb = _wakeupCb, v = _cbVersion]() {
std::unique_lock<std::mutex> lck(self->_mutex, std::defer_lock);

do {
bool cntn = false;
try {
cntn = cb();
} catch (...) {
}

lck.lock();
if (v == self->_cbVersion) {
unsigned c = self->_numWakeups--;
TRI_ASSERT(c > 0);
if (c == 1 || !cntn || !self->_valid) {
break;
}
} else {
return;
}
lck.unlock();
} while (true);

TRI_ASSERT(lck);
self->queueHandler();
});
auto const lane = ServerState::instance()->isCoordinator()
? RequestLane::CLUSTER_AQL_INTERNAL_COORDINATOR
: RequestLane::CLUSTER_AQL;

bool queued = scheduler->queue(lane, [self = shared_from_this(),
cb = _wakeupCb, v = _cbVersion]() {
std::unique_lock<std::mutex> lck(self->_mutex, std::defer_lock);

do {
bool cntn = false;
try {
cntn = cb();
} catch (...) {
}

lck.lock();
if (v == self->_cbVersion) {
unsigned c = self->_numWakeups--;
TRI_ASSERT(c > 0);
if (c == 1 || !cntn || !self->_valid) {
break;
}
} else {
return;
}
lck.unlock();
} while (true);

TRI_ASSERT(lck);
self->queueHandler();
});

if (!queued) { // just invalidate
_wakeupCb = nullptr;
Expand All @@ -168,7 +172,7 @@ void SharedQueryState::queueHandler() {
bool SharedQueryState::queueAsyncTask(fu2::unique_function<void()> cb) {
Scheduler* scheduler = SchedulerFeature::SCHEDULER;
if (scheduler) {
return scheduler->queue(RequestLane::CLIENT_AQL, std::move(cb));
return scheduler->queue(RequestLane::CLUSTER_AQL, std::move(cb));
}
return false;
}
19 changes: 10 additions & 9 deletions arangod/GeneralServer/RequestLane.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,16 @@ enum class RequestLane {
// V8 or having high priority.
CLUSTER_INTERNAL,

// For requests from the DBserver to the Coordinator or
// from the Coordinator to the DBserver. Using AQL
// these have Medium priority.
// Internal AQL requests, or continuations. Low priority.
CLUSTER_AQL,

// For future continuations initiated as part of an AQL request from the
// DBserver to the Coordinator or from the Coordinator to the DBserver.
// These have High priority.
CLUSTER_AQL_CONTINUATION,
// For requests from the DBserver to the Coordinator, and continuations on the
// Coordinator.
// These have medium priority. Because client requests made against the
// RestCursorHandler (with lane CLIENT_AQL) might block and need these to
// finish. Ongoing low priority requests can also prevent low priority lanes
// from being worked on, having the same effect.
CLUSTER_AQL_INTERNAL_COORDINATOR,

// For requests from the from the Coordinator to the
// DBserver using V8.
Expand Down Expand Up @@ -141,9 +142,9 @@ inline RequestPriority PriorityRequestLane(RequestLane lane) {
case RequestLane::CLUSTER_INTERNAL:
return RequestPriority::HIGH;
case RequestLane::CLUSTER_AQL:
return RequestPriority::LOW;
case RequestLane::CLUSTER_AQL_INTERNAL_COORDINATOR:
return RequestPriority::MED;
case RequestLane::CLUSTER_AQL_CONTINUATION:
return RequestPriority::HIGH;
case RequestLane::CLUSTER_V8:
return RequestPriority::LOW;
case RequestLane::CLUSTER_ADMIN:
Expand Down
0