summaryrefslogtreecommitdiff
path: root/src/mongo/db/session.h
diff options
context:
space:
mode:
authorKaloian Manassiev <kaloian.manassiev@mongodb.com>2018-09-27 06:05:54 -0400
committerKaloian Manassiev <kaloian.manassiev@mongodb.com>2018-10-08 02:38:48 -0400
commitb272bf351c39677d1e87d5c7fcd8b15b61465012 (patch)
tree9a92c09de2c9eb4244ca4b97d320f9d1e70637af /src/mongo/db/session.h
parent07066a49b935a538ed54716fdd9a98d40c31fba4 (diff)
downloadmongo-b272bf351c39677d1e87d5c7fcd8b15b61465012.tar.gz
SERVER-36799 Move all transactions and retryable writes functionality from Session into TransactionParticipant
This change leaves the Session class to be a plain decorable structure only used for serialization of operations on the same logical session.
Diffstat (limited to 'src/mongo/db/session.h')
-rw-r--r--src/mongo/db/session.h245
1 files changed, 7 insertions, 238 deletions
diff --git a/src/mongo/db/session.h b/src/mongo/db/session.h
index 2f79b3784f8..7b0c1a86857 100644
--- a/src/mongo/db/session.h
+++ b/src/mongo/db/session.h
@@ -28,196 +28,32 @@
#pragma once
-#include <boost/optional.hpp>
-
#include "mongo/base/disallow_copying.h"
-#include "mongo/bson/timestamp.h"
#include "mongo/db/logical_session_id.h"
-#include "mongo/db/operation_context.h"
-#include "mongo/db/repl/oplog.h"
-#include "mongo/db/repl/oplog_entry.h"
-#include "mongo/db/session_txn_record_gen.h"
-#include "mongo/platform/atomic_word.h"
-#include "mongo/stdx/unordered_map.h"
-#include "mongo/util/concurrency/with_lock.h"
+#include "mongo/util/decorable.h"
namespace mongo {
class OperationContext;
-class UpdateRequest;
/**
- * A write through cache for the state of a particular session. All modifications to the underlying
- * session transactions collection must be performed through an object of this class.
- *
- * The cache state can be 'up-to-date' (it is in sync with the persistent contents) or 'needs
- * refresh' (in which case refreshFromStorageIfNeeded needs to be called in order to make it
- * up-to-date).
+ * A decorable container for state associated with an active session running on a MongoD or MongoS
+ * server. Refer to SessionCatalog for more information on the semantics of sessions.
*/
class Session : public Decorable<Session> {
MONGO_DISALLOW_COPYING(Session);
public:
- using CommittedStatementTimestampMap = stdx::unordered_map<StmtId, repl::OpTime>;
-
- static const BSONObj kDeadEndSentinel;
-
explicit Session(LogicalSessionId sessionId);
- const LogicalSessionId& getSessionId() const {
- return _sessionId;
- }
-
- struct RefreshState {
- long long refreshCount{0};
- TxnNumber txnNumber{kUninitializedTxnNumber};
- bool isCommitted{false};
- };
-
- /**
- * Blocking method, which loads the transaction state from storage if it has been marked as
- * needing refresh.
- *
- * In order to avoid the possibility of deadlock, this method must not be called while holding a
- * lock.
- */
- void refreshFromStorageIfNeeded(OperationContext* opCtx);
-
- /**
- * Starts a new transaction on the session, or continues an already active transaction. In this
- * context, a "transaction" is a sequence of operations associated with a transaction number.
- *
- * Throws an exception if:
- * - An attempt is made to start a transaction with number less than the latest
- * transaction this session has seen.
- * - The session has been invalidated.
- *
- * In order to avoid the possibility of deadlock, this method must not be called while holding a
- * lock. This method must also be called after refreshFromStorageIfNeeded has been called.
- */
- void beginOrContinueTxn(OperationContext* opCtx, TxnNumber txnNumber);
-
- /**
- * Called after a write under the specified transaction completes while the node is a primary
- * and specifies the statement ids which were written. Must be called while the caller is still
- * in the write's WUOW. Updates the on-disk state of the session to match the specified
- * transaction/opTime and keeps the cached state in sync.
- *
- * 'txnState' is 'none' for retryable writes.
- *
- * Must only be called with the session checked-out.
- *
- * Throws if the session has been invalidated or the active transaction number doesn't match.
- */
- void onWriteOpCompletedOnPrimary(OperationContext* opCtx,
- TxnNumber txnNumber,
- std::vector<StmtId> stmtIdsWritten,
- const repl::OpTime& lastStmtIdWriteOpTime,
- Date_t lastStmtIdWriteDate,
- boost::optional<DurableTxnStateEnum> txnState);
-
/**
- * Helper function to begin a migration on a primary node.
- *
- * Returns whether the specified statement should be migrated at all or skipped.
- *
- * Not called with session checked out.
+ * The logical session id that this object represents.
*/
- bool onMigrateBeginOnPrimary(OperationContext* opCtx, TxnNumber txnNumber, StmtId stmtId);
-
- /**
- * Called after an entry for the specified session and transaction has been written to the oplog
- * during chunk migration, while the node is still primary. Must be called while the caller is
- * still in the oplog write's WUOW. Updates the on-disk state of the session to match the
- * specified transaction/opTime and keeps the cached state in sync.
- *
- * May be called concurrently with onWriteOpCompletedOnPrimary or onMigrateCompletedOnPrimary
- * and doesn't require the session to be checked-out.
- *
- * Throws if the session has been invalidated or the active transaction number is newer than the
- * one specified.
- */
- void onMigrateCompletedOnPrimary(OperationContext* opCtx,
- TxnNumber txnNumber,
- std::vector<StmtId> stmtIdsWritten,
- const repl::OpTime& lastStmtIdWriteOpTime,
- Date_t oplogLastStmtIdWriteDate);
-
- /**
- * Marks the session as requiring refresh. Used when the session state has been modified
- * externally, such as through a direct write to the transactions table.
- */
- void invalidate();
-
- /**
- * Returns the op time of the last committed write for this session and transaction. If no write
- * has completed yet, returns an empty timestamp.
- *
- * Throws if the session has been invalidated or the active transaction number doesn't match.
- */
- repl::OpTime getLastWriteOpTime(TxnNumber txnNumber) const;
-
- /**
- * Checks whether the given statementId for the specified transaction has already executed and
- * if so, returns the oplog entry which was generated by that write. If the statementId hasn't
- * executed, returns boost::none.
- *
- * Must only be called with the session checked-out.
- *
- * Throws if the session has been invalidated or the active transaction number doesn't match.
- */
- boost::optional<repl::OplogEntry> checkStatementExecuted(OperationContext* opCtx,
- TxnNumber txnNumber,
- StmtId stmtId) const;
-
- /**
- * Checks whether the given statementId for the specified transaction has already executed
- * without fetching the oplog entry which was generated by that write.
- *
- * Must only be called with the session checked-out.
- *
- * Throws if the session has been invalidated or the active transaction number doesn't match.
- */
- bool checkStatementExecutedNoOplogEntryFetch(TxnNumber txnNumber, StmtId stmtId) const;
-
- TxnNumber getActiveTxnNumber() const {
- stdx::lock_guard<stdx::mutex> lk(_mutex);
- return _activeTxnNumber;
+ const LogicalSessionId& getSessionId() const {
+ return _sessionId;
}
/**
- * Returns a new oplog entry if the given entry has transaction state embedded within in.
- * The new oplog entry will contain the operation needed to replicate the transaction
- * table.
- * Returns boost::none if the given oplog doesn't have any transaction state or does not
- * support update to the transaction table.
- */
- static boost::optional<repl::OplogEntry> createMatchingTransactionTableUpdate(
- const repl::OplogEntry& entry);
-
- /**
- * Returns the state of the session from storage the last time a refresh occurred.
- */
- boost::optional<RefreshState> getLastRefreshState() const;
-
- /**
- * Attempt to lock the active TxnNumber of this session to the given number. This operation
- * can only succeed if it is equal to the current active TxnNumber. Also sets the error status
- * for any callers trying to modify the TxnNumber.
- */
- void lockTxnNumber(const TxnNumber lockThisNumber, Status conflictError);
-
- /**
- * Release the lock on the active TxnNumber and allow it to be modified.
- */
- void unlockTxnNumber();
-
- /**
- * Returns if the given TxnNumber is locked.
- */
- bool isLockedTxnNumber(const TxnNumber expectedLockedNumber) const;
-
- /**
* Sets the current operation running on this Session.
*/
void setCurrentOperation(OperationContext* currentOperation);
@@ -234,40 +70,7 @@ public:
OperationContext* getCurrentOperation() const;
private:
- void _beginOrContinueTxn(WithLock, TxnNumber txnNumber);
-
- // Checks if there is a conflicting operation on the current Session
- void _checkValid(WithLock) const;
-
- // Checks that a new txnNumber is higher than the activeTxnNumber so
- // we don't start a txn that is too old.
- void _checkTxnValid(WithLock, TxnNumber txnNumber) const;
-
- void _setActiveTxn(WithLock, TxnNumber txnNumber);
-
- void _checkIsActiveTransaction(WithLock, TxnNumber txnNumber) const;
-
- boost::optional<repl::OpTime> _checkStatementExecuted(WithLock,
- TxnNumber txnNumber,
- StmtId stmtId) const;
-
- // Returns the write date of the last committed write for this session and transaction. If no
- // write has completed yet, returns an empty date.
- //
- // Throws if the session has been invalidated or the active transaction number doesn't match.
- Date_t _getLastWriteDate(WithLock, TxnNumber txnNumber) const;
-
- UpdateRequest _makeUpdateRequest(WithLock,
- TxnNumber newTxnNumber,
- const repl::OpTime& newLastWriteTs,
- Date_t newLastWriteDate,
- boost::optional<DurableTxnStateEnum> newState) const;
-
- void _registerUpdateCacheOnCommit(OperationContext* opCtx,
- TxnNumber newTxnNumber,
- std::vector<StmtId> stmtIdsWritten,
- const repl::OpTime& lastStmtIdWriteTs);
-
+ // The id of the session with which this object is associated
const LogicalSessionId _sessionId;
// Protects the member variables below.
@@ -276,40 +79,6 @@ private:
// A pointer back to the currently running operation on this Session, or nullptr if there
// is no operation currently running for the Session.
OperationContext* _currentOperation{nullptr};
-
- // Specifies whether the session information needs to be refreshed from storage
- bool _isValid{false};
-
- // Counter, incremented with each call to invalidate in order to discern invalidations, which
- // happen during refresh
- int _numInvalidations{0};
-
- // Set to true if incomplete history is detected. For example, when the oplog to a write was
- // truncated because it was too old.
- bool _hasIncompleteHistory{false};
-
- // Caches what is known to be the last written transaction record for the session
- boost::optional<SessionTxnRecord> _lastWrittenSessionRecord;
-
- // Tracks the last seen txn number for the session and is always >= to the transaction number in
- // the last written txn record. When it is > than that in the last written txn record, this
- // means a new transaction has begun on the session, but it hasn't yet performed any writes.
- TxnNumber _activeTxnNumber{kUninitializedTxnNumber};
-
- // For the active txn, tracks which statement ids have been committed and at which oplog
- // opTime. Used for fast retryability check and retrieving the previous write's data without
- // having to scan through the oplog.
- CommittedStatementTimestampMap _activeTxnCommittedStatements;
-
- // Stores the state from last refresh.
- boost::optional<RefreshState> _lastRefreshState;
-
- // True if txnNumber cannot be modified.
- bool _isTxnNumberLocked{false};
-
- // The status to return when an operation tries to modify the active TxnNumber while it is
- // locked.
- boost::optional<Status> _txnNumberLockConflictStatus;
};
} // namespace mongo