High CPU Usage During Server Selection in MongoDB Go Driver

XMLWordPrintableJSON

    • Type: Bug
    • Resolution: Unresolved
    • Priority: Unknown
    • None
    • Affects Version/s: 2.3.0
    • Component/s: Server Selection
    • None
    • None
    • Go Drivers
    • None
    • None
    • None
    • None
    • None
    • None

      The MongoDB Go Driver exhibits excessive CPU consumption during server selection when no suitable servers are available, due to a non-blocking loop in the topology selection logic.

      Detailed steps to reproduce the problem?

      1. Setup a MongoDB cluster with no available servers:
      • Either use a non-existent MongoDB instance
      • Or configure a cluster where all servers are down/unreachable
      • Or use invalid connection strings
      1. Create a Go application with the MongoDB driver:
          package main
           
           import (
               "context"
               "log"
               "time"
               
               "go.mongodb.org/mongo-driver/mongo"
               "go.mongodb.org/mongo-driver/mongo/options"
           )
           
           func main() {
               // Configure client with unreachable MongoDB
               clientOptions := options.Client().
                   ApplyURI("mongodb://invalid-host:27017").
                   SetServerSelectionTimeout(5 * time.Second).
                   SetHeartbeatInterval(10 * time.Second)
               
               client, err := mongo.Connect(context.Background(), clientOptions)
               if err != nil {
                   log.Fatal(err)
               }
               defer client.Disconnect(context.Background())
               
               // Attempt to perform an operation
               collection := client.Database("test").Collection("test")
               
               // This will trigger the high CPU usage
               _, err = collection.InsertOne(context.Background(), map[string]interface{}{"test": "data"})
               if err != nil {
                   log.Printf("Error: %v", err)
               }
               
               // Keep the program running to observe CPU usage
               time.Sleep(600 * time.Second)
           } 

         

      2. Run the application and observe:
      • Monitor CPU usage with top, htop, or system monitor
      • Observe 100% CPU consumption in the Go process
      • The issue persists indefinitely until the process is killed
      1. Alternative reproduction method:
      • Start a MongoDB instance
      • Run the application successfully
      • Stop the MongoDB instance
      • Attempt any operation - CPU usage will spike to 100%

      Definition of done: what must be done to consider the task complete?

      1. Fix the infinite loop in SelectServer method to respect ServerSelectionTimeout
      1. Add context cancellation check in the main selection loop
      1. Ensure the driver exits gracefully when no servers are available within the configured timeout

      The exact Go version used, with patch level:

      go version go1.23.7 darwin/arm64

      The exact version of the Go driver used:

      go.mongodb.org/mongo-driver/v2@v2.3.0

      Describe how MongoDB is set up. Local vs Hosted, version, topology, load balanced, etc.

      Local Development Environment:

      • MongoDB Version: MongoDB Community Server 7.0.2
      • Topology: Standalone instance
      • Load Balanced: No
      • Authentication: None (development setup)
      • Connection: Localhost:27017

      The operating system and version (e.g. Windows 7, OSX 10.8, ...)

      • OS: macOS 14.0 (Darwin 23.0.0)
      • Architecture: x86_64
      • Kernel: Darwin 23.0.0

            Assignee:
            Matt Dale
            Reporter:
            Javier Alvarez Losada
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated: