diff --git a/CHANGELOG b/CHANGELOG index 86812d1474..abfd1b858e 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,9 @@ +devel +----- + +* don't let read-only transactions block the WAL collector + + v3.2.alpha2 (2017-02-20) ------------------------ diff --git a/arangod/MMFiles/MMFilesLogfileManager.cpp b/arangod/MMFiles/MMFilesLogfileManager.cpp index 9e778f7907..b1f7cac313 100644 --- a/arangod/MMFiles/MMFilesLogfileManager.cpp +++ b/arangod/MMFiles/MMFilesLogfileManager.cpp @@ -535,7 +535,7 @@ void MMFilesLogfileManager::unprepare() { } // registers a transaction -int MMFilesLogfileManager::registerTransaction(TRI_voc_tid_t transactionId) { +int MMFilesLogfileManager::registerTransaction(TRI_voc_tid_t transactionId, bool isReadOnlyTransaction) { auto lastCollectedId = _lastCollectedId.load(); auto lastSealedId = _lastSealedId.load(); @@ -546,6 +546,16 @@ int MMFilesLogfileManager::registerTransaction(TRI_voc_tid_t transactionId) { TRI_ASSERT(lastCollectedId <= lastSealedId); + if (isReadOnlyTransaction) { + // in case this is a read-only transaction, we are sure that the transaction can + // only see committed data (as itself it will not write anything, and write transactions + // run exclusively). we thus can allow the WAL collector to already seal and collect + // logfiles. the only thing that needs to be ensured for read-only transactions is + // that a logfile does not get thrown away while the read-only transaction is + // ongoing + lastSealedId = 0; + } + try { auto data = std::make_unique(lastCollectedId, lastSealedId); TransactionManagerFeature::MANAGER->registerTransaction(transactionId, std::move(data)); diff --git a/arangod/MMFiles/MMFilesLogfileManager.h b/arangod/MMFiles/MMFilesLogfileManager.h index 00995adc8b..1b96176ae3 100644 --- a/arangod/MMFiles/MMFilesLogfileManager.h +++ b/arangod/MMFiles/MMFilesLogfileManager.h @@ -68,8 +68,8 @@ struct MMFilesTransactionData final : public TransactionData { MMFilesTransactionData() = delete; MMFilesTransactionData(MMFilesWalLogfile::IdType lastCollectedId, MMFilesWalLogfile::IdType lastSealedId) : lastCollectedId(lastCollectedId), lastSealedId(lastSealedId) {} - MMFilesWalLogfile::IdType lastCollectedId; - MMFilesWalLogfile::IdType lastSealedId; + MMFilesWalLogfile::IdType const lastCollectedId; + MMFilesWalLogfile::IdType const lastSealedId; }; struct MMFilesLogfileManagerState { @@ -218,7 +218,7 @@ class MMFilesLogfileManager final : public application_features::ApplicationFeat } // registers a transaction - int registerTransaction(TRI_voc_tid_t); + int registerTransaction(TRI_voc_tid_t id, bool isReadOnlyTransaction); // return the set of dropped collections /// this is used during recovery and not used afterwards @@ -459,8 +459,8 @@ class MMFilesLogfileManager final : public application_features::ApplicationFeat bool _allowOversizeEntries = true; bool _useMLock = false; - std::string _directory = ""; - uint32_t _historicLogfiles = 10; + std::string _directory; + uint32_t _historicLogfiles = 10; bool _ignoreLogfileErrors = false; bool _ignoreRecoveryErrors = false; uint64_t _flushTimeout = 15000; diff --git a/arangod/MMFiles/MMFilesTransactionState.cpp b/arangod/MMFiles/MMFilesTransactionState.cpp index bb8ce48509..a769ee866d 100644 --- a/arangod/MMFiles/MMFilesTransactionState.cpp +++ b/arangod/MMFiles/MMFilesTransactionState.cpp @@ -104,8 +104,8 @@ int MMFilesTransactionState::beginTransaction(transaction::Hints hints, int nest _id = TRI_NewTickServer(); // register a protector - int res = logfileManager->registerTransaction(_id); - + int res = logfileManager->registerTransaction(_id, isReadOnlyTransaction()); + if (res != TRI_ERROR_NO_ERROR) { return res; }