Updated on 2024-09-11 GMT+08:00

What Are Logical Sessions?

Overview

In DDS, server sessions or logical sessions are used to maintain and manage the client operation status on the server. An application uses client sessions to interact with server sessions.

Session Lifecycle

  1. Creating a Session
    • Explicitly creating a session

      A session is created by the server when the client sends a request. Sessions are usually created by the driver through APIs. For example, run the following commands to create a session using mongo shell:

      // Start a session.
      session = db.getMongo().startSession( { readPreference: { mode: "primary" } } );

      The created session maintains a unique session ID on the server to identify and manage the session.

      session { "id" : UUID("1c6480a3-8e8d-4726-9f1b-6bf2f6b2b606") }
    • Implicitly creating a session

      Implicitly creating a session means that when certain operations are performed, the driver automatically creates a session without explicitly calling startSession. Implicit sessions are mainly used to simplify code and make operations more convenient. When a client performs a database operation without explicitly providing session parameters, the driver automatically creates a session. For example, when a document is inserted or data is queried, the driver implicitly creates a session in the background and automatically ends the session after the operation is complete.

      By default, the maximum number of sessions that can be cached on the server is 1,000,000. When the number of sessions exceeds the value, sessions cannot be created explicitly or implicitly.

      The following scenarios may occur when the number of sessions reaches the upper limit:

      • New session rejected: If the number of sessions reaches the upper limit, DDS cannot create new sessions. This means that new operation requests will be rejected or blocked until existing sessions are released.
      • Resource contention: A large number of sessions may cause resource contention, for example, increasing memory and CPU usage. This may affect the performance and response time of a database.
      • Transaction failure: If you attempt to start a new transaction when the number of sessions reaches the upper limit, the transaction may fail. The client receives an error message indicating that the session resources are exhausted.
    • Using sessions

      When a session is used, all database operations including read, write, and transaction operations in the session context are bound to the session. Example:

      coll1 = session.getDatabase("mydb1").foo;
      coll2 = session.getDatabase("mydb2").bar;
      coll1.insertOne( { abc: 1 } );
      coll2.insertOne( { xyz: 999 } ).
    • Terminating a session

      A session can be terminated explicitly or automatically after timeout. You can call endSession to explicitly terminate a session.

      session.endSession();

      The server automatically clears the resources occupied by the terminated session.

  2. Managing Sessions
    • Transaction management

      Sessions are the core of transaction management. At the beginning of a transaction, the server records the transaction operations in the session context to ensure that these operations are either all committed or all rolled back. Example:

      db.getSiblingDB("mydb1").foo.insertOne(
      {abc: 0},
      { writeConcern: { w: "majority", wtimeout: 2000 } }
      )
      db.getSiblingDB("mydb2").bar.insertOne(
      {xyz: 0},
      { writeConcern: { w: "majority", wtimeout: 2000 } }
      )
      // Start a session.
      session = db.getMongo().startSession( { readPreference: { mode: "primary" } } );
      coll1 = session.getDatabase("mydb1").foo;
      coll2 = session.getDatabase("mydb2").bar;
      // Start a transaction
      session.startTransaction( { readConcern: { level: "local" }, writeConcern: { w: "majority" } } );
      // Operations inside the transaction
      try {
      coll1.insertOne( { abc: 1 } );
      coll2.insertOne( { xyz: 999 } );
      } catch (error) {
      // Abort transaction on error
      session.abortTransaction();
      throw error;
      }
      // Commit the transaction using write concern set at transaction start
      session.commitTransaction();
      session.endSession();
    • Session timeout

      A session has a default timeout interval, which is 30 minutes by default. The server automatically terminates inactive sessions after timeout to release resources.

How Do Logical Sessions Work

  1. Session ID

    Each session has a unique session ID, which remains unchanged throughout the life cycle of the session. A session ID is used to trace and manage operations within a session.

  2. Session resource management

    The server dynamically allocates resources based on session activities. Unused session metadata is automatically cleared. When writeConcern for clearing session metadata is set to majority, residual session metadata cannot be cleared if the majority of standby nodes have a latency. This can result in accumulated session metadata on the server and increase the number of sessions, even after the session has been terminated. To prevent excessive resource usage, the server periodically checks the status of sessions that have been running for a long time.

Best Practices

  1. You are advised to specify w to majority when connecting to a DDS instance to prevent implicit residual sessions caused by long primary/secondary latency. In addition, if data is not written using w=majority, the data that is not synchronized to the secondary node may be lost when a primary/secondary switchover occurs.
  2. Explicitly invoke endSession after operations are complete to terminate a session to release resources.
  3. Minimize operations performed within a transaction to reduce locking and resource usage.