diff --git a/arangod/VocBase/transaction.cpp b/arangod/VocBase/transaction.cpp index 69c1aa1dee..1db2f42b7a 100644 --- a/arangod/VocBase/transaction.cpp +++ b/arangod/VocBase/transaction.cpp @@ -58,14 +58,30 @@ static triagens::wal::LogfileManager* GetLogfileManager () { return triagens::wal::LogfileManager::instance(); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief whether or not a transaction is read-only +//////////////////////////////////////////////////////////////////////////////// + +static inline bool IsReadOnlyTransaction (TRI_transaction_t const* trx) { + return (trx->_type == TRI_TRANSACTION_READ); +} + //////////////////////////////////////////////////////////////////////////////// /// @brief whether or not a transaction consists of a single operation //////////////////////////////////////////////////////////////////////////////// -static bool IsSingleOperationTransaction (TRI_transaction_t const* trx) { +static inline bool IsSingleOperationTransaction (TRI_transaction_t const* trx) { return ((trx->_hints & (TRI_transaction_hint_t) TRI_TRANSACTION_HINT_SINGLE_OPERATION) != 0); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief whether or not a marker needs to be written +//////////////////////////////////////////////////////////////////////////////// + +static inline bool NeedWriteMarker (TRI_transaction_t const* trx) { + return (trx->_nestingLevel == 0 && ! IsReadOnlyTransaction(trx) && ! IsSingleOperationTransaction(trx)); +} + //////////////////////////////////////////////////////////////////////////////// /// @brief compares two transaction ids //////////////////////////////////////////////////////////////////////////////// @@ -443,8 +459,8 @@ static int ReleaseCollections (TRI_transaction_t* const trx, /// @brief write WAL begin marker //////////////////////////////////////////////////////////////////////////////// -static int WriteBeginMarker (TRI_transaction_t* trx) { - if (trx->_nestingLevel != 0 || IsSingleOperationTransaction(trx)) { +static int WriteBeginMarker (TRI_transaction_t* trx) { + if (! NeedWriteMarker(trx)) { return TRI_ERROR_NO_ERROR; } @@ -457,8 +473,8 @@ static int WriteBeginMarker (TRI_transaction_t* trx) { /// @brief write WAL abort marker //////////////////////////////////////////////////////////////////////////////// -static int WriteAbortMarker (TRI_transaction_t* trx) { - if (trx->_nestingLevel != 0 || IsSingleOperationTransaction(trx)) { +static int WriteAbortMarker (TRI_transaction_t* trx) { + if (! NeedWriteMarker(trx)) { return TRI_ERROR_NO_ERROR; } @@ -471,8 +487,8 @@ static int WriteAbortMarker (TRI_transaction_t* trx) { /// @brief write WAL commit marker //////////////////////////////////////////////////////////////////////////////// -static int WriteCommitMarker (TRI_transaction_t* trx) { - if (trx->_nestingLevel != 0 || IsSingleOperationTransaction(trx)) { +static int WriteCommitMarker (TRI_transaction_t* trx) { + if (! NeedWriteMarker(trx)) { return TRI_ERROR_NO_ERROR; } @@ -485,8 +501,8 @@ static int WriteCommitMarker (TRI_transaction_t* trx) { /// @brief update the status of a transaction //////////////////////////////////////////////////////////////////////////////// -static int UpdateTransactionStatus (TRI_transaction_t* const trx, - TRI_transaction_status_e status) { +static void UpdateTransactionStatus (TRI_transaction_t* const trx, + TRI_transaction_status_e status) { assert(trx->_status == TRI_TRANSACTION_CREATED || trx->_status == TRI_TRANSACTION_RUNNING); if (trx->_status == TRI_TRANSACTION_CREATED) { @@ -496,32 +512,7 @@ static int UpdateTransactionStatus (TRI_transaction_t* const trx, assert(status == TRI_TRANSACTION_COMMITTED || status == TRI_TRANSACTION_ABORTED); } - int res = TRI_ERROR_NO_ERROR; - - if (status == TRI_TRANSACTION_RUNNING) { - // write a begin marker - res = WriteBeginMarker(trx); - } - else if (status == TRI_TRANSACTION_COMMITTED) { - res = WriteCommitMarker(trx); - } - - // an error might have happened until now. if yes, then we'll abort the transaction - if (res != TRI_ERROR_NO_ERROR) { - status = TRI_TRANSACTION_FAILED; - - // reset the error, because we have set status "failed" already - res = TRI_ERROR_NO_ERROR; - } - - // if the transaction has failed or was aborted, we'll write an abort marker - if (status == TRI_TRANSACTION_ABORTED || status == TRI_TRANSACTION_FAILED) { - res = WriteAbortMarker(trx); - } - trx->_status = status; - - return res; } //////////////////////////////////////////////////////////////////////////////// @@ -920,8 +911,6 @@ TRI_voc_tid_t TRI_GetIdTransaction (TRI_transaction_t const* trx) { int TRI_BeginTransaction (TRI_transaction_t* trx, TRI_transaction_hint_t hints, int nestingLevel) { - int res; - LOG_TRX(trx, nestingLevel, "%s transaction", "beginning"); if (nestingLevel == 0) { @@ -937,21 +926,22 @@ int TRI_BeginTransaction (TRI_transaction_t* trx, assert(trx->_status == TRI_TRANSACTION_RUNNING); } - res = UseCollections(trx, nestingLevel); + int res = UseCollections(trx, nestingLevel); if (res == TRI_ERROR_NO_ERROR) { // all valid if (nestingLevel == 0) { - res = UpdateTransactionStatus(trx, TRI_TRANSACTION_RUNNING); + UpdateTransactionStatus(trx, TRI_TRANSACTION_RUNNING); + + res = WriteBeginMarker(trx); } } - else { + + + if (res != TRI_ERROR_NO_ERROR) { // something is wrong if (nestingLevel == 0) { UpdateTransactionStatus(trx, TRI_TRANSACTION_FAILED); - - // res contains an error anyway, so we don't need the return value of UpdateTransactionStatus - assert(res != TRI_ERROR_NO_ERROR); } // free what we have got so far @@ -974,7 +964,16 @@ int TRI_CommitTransaction (TRI_transaction_t* trx, int res = TRI_ERROR_NO_ERROR; if (nestingLevel == 0) { - res = UpdateTransactionStatus(trx, TRI_TRANSACTION_COMMITTED); + res = WriteCommitMarker(trx); + + if (res != TRI_ERROR_NO_ERROR) { + TRI_AbortTransaction(trx, nestingLevel); + + // return original error + return res; + } + + UpdateTransactionStatus(trx, TRI_TRANSACTION_COMMITTED); FreeOperations(trx); } @@ -997,7 +996,9 @@ int TRI_AbortTransaction (TRI_transaction_t* trx, int res = TRI_ERROR_NO_ERROR; if (nestingLevel == 0) { - res = UpdateTransactionStatus(trx, TRI_TRANSACTION_ABORTED); + res = WriteAbortMarker(trx); + + UpdateTransactionStatus(trx, TRI_TRANSACTION_ABORTED); FreeOperations(trx); } diff --git a/arangod/Wal/Marker.cpp b/arangod/Wal/Marker.cpp index 36bad0aac1..595ed6ca79 100644 --- a/arangod/Wal/Marker.cpp +++ b/arangod/Wal/Marker.cpp @@ -56,7 +56,7 @@ Marker::Marker (TRI_df_marker_type_e type, m->_crc = 0; m->_tick = 0; -// std::cout << "CREATED A MARKER OF SIZE: " << size << ", type: " << type << " (" << TRI_NameMarker(m) << "), buffer: " << (void*) _buffer << "\n"; + // std::cout << "CREATED A MARKER OF SIZE: " << size << ", type: " << type << " (" << TRI_NameMarker(m) << "), buffer: " << (void*) _buffer << "\n"; } //////////////////////////////////////////////////////////////////////////////// @@ -122,6 +122,8 @@ AttributeMarker::AttributeMarker (TRI_voc_tick_t databaseId, m->_attributeId = attributeId; storeSizedString(sizeof(attribute_marker_t), attributeName); + + dump(); } //////////////////////////////////////////////////////////////////////////////// @@ -131,6 +133,21 @@ AttributeMarker::AttributeMarker (TRI_voc_tick_t databaseId, AttributeMarker::~AttributeMarker () { } +//////////////////////////////////////////////////////////////////////////////// +/// @brief dump marker +//////////////////////////////////////////////////////////////////////////////// + +void AttributeMarker::dump () const { + attribute_marker_t* m = reinterpret_cast(begin()); + + std::cout << "WAL ATTRIBUTE MARKER FOR DB " << m->_databaseId + << ", COLLECTION " << m->_collectionId + << ", ATTRIBUTE ID: " << m->_attributeId + << ", ATTRIBUTE: " << attributeName() + << ", SIZE: " << size() + << "\n"; +} + // ----------------------------------------------------------------------------- // --SECTION-- ShapeMarker // ----------------------------------------------------------------------------- @@ -154,6 +171,8 @@ ShapeMarker::ShapeMarker (TRI_voc_tick_t databaseId, m->_collectionId = collectionId; memcpy(this->shape(), shape, shape->_size); + + dump(); } //////////////////////////////////////////////////////////////////////////////// @@ -163,6 +182,20 @@ ShapeMarker::ShapeMarker (TRI_voc_tick_t databaseId, ShapeMarker::~ShapeMarker () { } +//////////////////////////////////////////////////////////////////////////////// +/// @brief dump marker +//////////////////////////////////////////////////////////////////////////////// + +void ShapeMarker::dump () const { + shape_marker_t* m = reinterpret_cast(begin()); + + std::cout << "WAL SHAPE MARKER FOR DB " << m->_databaseId + << ", COLLECTION " << m->_collectionId + << ", SHAPE ID: " << shapeId() + << ", SIZE: " << size() + << "\n"; +} + // ----------------------------------------------------------------------------- // --SECTION-- BeginTransactionMarker // ----------------------------------------------------------------------------- @@ -183,6 +216,8 @@ BeginTransactionMarker::BeginTransactionMarker (TRI_voc_tick_t databaseId, m->_databaseId = databaseId; m->_transactionId = transactionId; + + dump(); } //////////////////////////////////////////////////////////////////////////////// @@ -192,6 +227,19 @@ BeginTransactionMarker::BeginTransactionMarker (TRI_voc_tick_t databaseId, BeginTransactionMarker::~BeginTransactionMarker () { } +//////////////////////////////////////////////////////////////////////////////// +/// @brief dump marker +//////////////////////////////////////////////////////////////////////////////// + +void BeginTransactionMarker::dump () const { + transaction_begin_marker_t* m = reinterpret_cast(begin()); + + std::cout << "WAL TRANSACTION BEGIN MARKER FOR DB " << m->_databaseId + << ", TRANSACTION " << m->_transactionId + << ", SIZE: " << size() + << "\n"; +} + // ----------------------------------------------------------------------------- // --SECTION-- CommitTransactionMarker // ----------------------------------------------------------------------------- @@ -212,6 +260,8 @@ CommitTransactionMarker::CommitTransactionMarker (TRI_voc_tick_t databaseId, m->_databaseId = databaseId; m->_transactionId = transactionId; + + dump(); } //////////////////////////////////////////////////////////////////////////////// @@ -221,6 +271,19 @@ CommitTransactionMarker::CommitTransactionMarker (TRI_voc_tick_t databaseId, CommitTransactionMarker::~CommitTransactionMarker () { } +//////////////////////////////////////////////////////////////////////////////// +/// @brief dump marker +//////////////////////////////////////////////////////////////////////////////// + +void CommitTransactionMarker::dump () const { + transaction_commit_marker_t* m = reinterpret_cast(begin()); + + std::cout << "WAL TRANSACTION COMMIT MARKER FOR DB " << m->_databaseId + << ", TRANSACTION " << m->_transactionId + << ", SIZE: " << size() + << "\n"; +} + // ----------------------------------------------------------------------------- // --SECTION-- AbortTransactionMarker // ----------------------------------------------------------------------------- @@ -241,6 +304,8 @@ AbortTransactionMarker::AbortTransactionMarker (TRI_voc_tick_t databaseId, m->_databaseId = databaseId; m->_transactionId = transactionId; + + dump(); } //////////////////////////////////////////////////////////////////////////////// @@ -250,6 +315,19 @@ AbortTransactionMarker::AbortTransactionMarker (TRI_voc_tick_t databaseId, AbortTransactionMarker::~AbortTransactionMarker () { } +//////////////////////////////////////////////////////////////////////////////// +/// @brief dump marker +//////////////////////////////////////////////////////////////////////////////// + +void AbortTransactionMarker::dump () const { + transaction_commit_marker_t* m = reinterpret_cast(begin()); + + std::cout << "WAL TRANSACTION ABORT MARKER FOR DB " << m->_databaseId + << ", TRANSACTION " << m->_transactionId + << ", SIZE: " << size() + << "\n"; +} + // ----------------------------------------------------------------------------- // --SECTION-- DocumentMarker // ----------------------------------------------------------------------------- @@ -322,7 +400,7 @@ void DocumentMarker::dump () const { << ", OFFSETJSON: " << m->_offsetJson << ", SIZE: " << size() << "\n"; - +return; std::cout << "BINARY: '" << stringifyPart(begin(), size()) << "'\n"; std::cout << "LEGEND: '" << stringifyPart(legend(), legendLength()) << "'\n"; std::cout << "LEGEND HEX: '" << hexifyPart(legend(), legendLength()) << "'\n"; @@ -461,6 +539,7 @@ void EdgeMarker::dump () const { << ", SIZE: " << size() << "\n"; +return; std::cout << "BINARY: '" << stringifyPart(begin(), size()) << "'\n"; std::cout << "LEGEND: '" << stringifyPart(legend(), legendLength()) << "'\n"; std::cout << "LEGEND HEX: '" << hexifyPart(legend(), legendLength()) << "'\n"; @@ -574,8 +653,7 @@ void RemoveMarker::dump () const { << ", KEY: " << key() << "\n"; - std::cout << "BEGIN: " << begin() << ", SIZE: " << size() << "\n"; - +return; std::cout << "BINARY: '" << stringifyPart(begin(), size()) << "'\n"; } diff --git a/arangod/Wal/Marker.h b/arangod/Wal/Marker.h index f46c7255fe..4ab6c7bcb2 100644 --- a/arangod/Wal/Marker.h +++ b/arangod/Wal/Marker.h @@ -261,6 +261,8 @@ namespace triagens { // pointer to attribute name return begin() + sizeof(attribute_marker_t); } + + void dump () const; }; // ----------------------------------------------------------------------------- @@ -282,6 +284,12 @@ namespace triagens { inline char* shape () const { return begin() + sizeof(shape_marker_t); } + + inline TRI_shape_sid_t shapeId () const { + return reinterpret_cast(shape())->_sid; + } + + void dump () const; }; // ----------------------------------------------------------------------------- @@ -296,6 +304,10 @@ namespace triagens { TRI_voc_tid_t); ~BeginTransactionMarker (); + + public: + + void dump () const; }; // ----------------------------------------------------------------------------- @@ -310,6 +322,10 @@ namespace triagens { TRI_voc_tid_t); ~CommitTransactionMarker (); + + public: + + void dump () const; }; // ----------------------------------------------------------------------------- @@ -324,6 +340,10 @@ namespace triagens { TRI_voc_tid_t); ~AbortTransactionMarker (); + + public: + + void dump () const; }; // -----------------------------------------------------------------------------