mirror of https://gitee.com/bigwinds/arangodb
Sort out race for update in configuration collection in Agency.
This only came up in the RocksDB engine, since only there can two write operations report a conflict if transactions are running concurrently.
This commit is contained in:
parent
fb40a0c0ec
commit
9df8b5835b
|
@ -513,8 +513,9 @@ bool Agent::activateAgency() {
|
|||
}
|
||||
bool persisted = false;
|
||||
try {
|
||||
persisted = _state.persistActiveAgents(_config.activeToBuilder(),
|
||||
_config.poolToBuilder());
|
||||
_state.persistActiveAgents(_config.activeToBuilder(),
|
||||
_config.poolToBuilder());
|
||||
persisted = true;
|
||||
} catch (std::exception const& e) {
|
||||
LOG_TOPIC(FATAL, Logger::AGENCY)
|
||||
<< "Failed to persist active agency: " << e.what();
|
||||
|
|
|
@ -605,6 +605,8 @@ bool State::loadOrPersistConfiguration() {
|
|||
|
||||
} else { // Fresh start
|
||||
|
||||
MUTEX_LOCKER(guard, _configurationWriteLock);
|
||||
|
||||
LOG_TOPIC(DEBUG, Logger::AGENCY) << "New agency!";
|
||||
|
||||
TRI_ASSERT(_agent != nullptr);
|
||||
|
@ -830,28 +832,39 @@ bool State::persistReadDB(arangodb::consensus::index_t cind) {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool State::persistActiveAgents(query_t const& active, query_t const& pool) {
|
||||
auto bindVars = std::make_shared<VPackBuilder>();
|
||||
bindVars->openObject();
|
||||
bindVars->close();
|
||||
void State::persistActiveAgents(query_t const& active, query_t const& pool) {
|
||||
TRI_ASSERT(_vocbase != nullptr);
|
||||
|
||||
std::stringstream aql;
|
||||
aql << "FOR c IN configuration UPDATE {_key:c._key} WITH {cfg:{active:";
|
||||
aql << active->slice().toJson();
|
||||
aql << ", pool:";
|
||||
aql << pool->slice().toJson();
|
||||
aql << "}} IN configuration";
|
||||
std::string aqlStr = aql.str();
|
||||
|
||||
arangodb::aql::Query query(false, _vocbase, aqlStr.c_str(), aqlStr.size(),
|
||||
bindVars, nullptr, arangodb::aql::PART_MAIN);
|
||||
|
||||
auto queryResult = query.execute(QueryRegistryFeature::QUERY_REGISTRY);
|
||||
if (queryResult.code != TRI_ERROR_NO_ERROR) {
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(queryResult.code, queryResult.details);
|
||||
Builder builder;
|
||||
{ VPackObjectBuilder guard(&builder);
|
||||
builder.add("_key", VPackValue("0"));
|
||||
builder.add(VPackValue("cfg"));
|
||||
{ VPackObjectBuilder guard2(&builder);
|
||||
builder.add("active", active->slice());
|
||||
builder.add("pool", pool->slice());
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
MUTEX_LOCKER(guard, _configurationWriteLock);
|
||||
|
||||
auto transactionContext =
|
||||
std::make_shared<transaction::StandaloneContext>(_vocbase);
|
||||
SingleCollectionTransaction trx(
|
||||
transactionContext, "configuration", AccessMode::Type::WRITE);
|
||||
|
||||
Result res = trx.begin();
|
||||
if (!res.ok()) {
|
||||
THROW_ARANGO_EXCEPTION(res);
|
||||
}
|
||||
|
||||
auto result = trx.update("configuration", builder.slice(), _options);
|
||||
if (!result.successful()) {
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(result.code, result.errorMessage);
|
||||
}
|
||||
res = trx.finish(result.code);
|
||||
if (!res.ok()) {
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(res.errorNumber(), res.errorMessage());
|
||||
}
|
||||
}
|
||||
|
||||
query_t State::allLogs() const {
|
||||
|
|
|
@ -134,8 +134,8 @@ class State {
|
|||
/// exists are overwritten
|
||||
size_t removeConflicts(query_t const&);
|
||||
|
||||
/// @brief Persist active agency in pool
|
||||
bool persistActiveAgents(query_t const& active, query_t const& pool);
|
||||
/// @brief Persist active agency in pool, throws an exception in case of error
|
||||
void persistActiveAgents(query_t const& active, query_t const& pool);
|
||||
|
||||
/// @brief Get everything from the state machine
|
||||
query_t allLogs() const;
|
||||
|
@ -205,6 +205,8 @@ class State {
|
|||
/// @brief Empty log entry;
|
||||
static log_t emptyLog;
|
||||
|
||||
/// @brief Protect writing into configuration collection
|
||||
arangodb::Mutex _configurationWriteLock;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue