i.van
i.van

Reputation: 826

Go MongoDB (mgo) - doesn't release closed connections

My MongoDB database has a fast-growing amount of active connections.

I wrote a code to test how connection creation/closing flow works. This code sums up how I use the mgo library in my project.

package main

import (
    "time"

    "fmt"

    "gopkg.in/mgo.v2"
)

func main() {
    // No connections
    // db.serverStatus().connections.current = 6

    mongoSession := connectMGO("localhost", "27017", "admin")
    // 1 new connection created
    //db.serverStatus().connections.current = 7

    produceDataMGO(mongoSession)
    produceDataMGO(mongoSession)
    produceDataMGO(mongoSession)
    produceDataMGO(mongoSession)
    // 4 new connections created and closed
    // db.serverStatus().connections.current = 7

    go produceDataMGO(mongoSession)
    go produceDataMGO(mongoSession)
    go produceDataMGO(mongoSession)
    go produceDataMGO(mongoSession)
    // 4 new connections created and closed concurrently
    // db.serverStatus().connections.current = 10

    time.Sleep(time.Hour * 24) // wait any amount of time
    // db.serverStatus().connections.current = 10
}

func connectMGO(host, port, dbName string) *mgo.Session {
    session, _ := mgo.DialWithInfo(&mgo.DialInfo{
        Addrs:    []string{fmt.Sprintf("%s:%s", host, port)},
        Timeout:  10 * time.Second,
        Database: dbName,
        Username: "",
        Password: "",
    })
    return session
}

func produceDataMGO(conn *mgo.Session) {
    dbConn := conn.Copy()
    dbConn.DB("").C("test").Insert("")
    dbConn.Close()
}

I detected a pretty weird thing that I don't understand. Behaviour is somehow different depending on how we create new connections (sync/async).

If we create connection synchronously - mongo closes this new connection immediately after calling .Close() method.

If we create connection asynchronously - mongo keeps this new connection alive even after calling .Close() method.

  1. Why is it so?

  2. Is there any other way to force-close connection socket?

  3. Will it auto-close these open connections after a certain amount of time?

  4. Is there any way to set a limit for the amount of connections MongoDB can expand its pool to?
  5. Is there any way to setup an auto-truncate after a certain amount of time without high load?

Upvotes: 0

Views: 1745

Answers (1)

Adrian
Adrian

Reputation: 46572

It's connection pooling. When you "close" a session, it isn't necessarily closed; it may just be returned to the pool for re-use. In the synchronous example, it doesn't need to expand the pool; you're only using one connection at a time. In the concurrent example, you're using several connections at a time, so it may decide it does need to expand the pool. I would not consider 10 open connections to be cause for concern.

Try it with a larger test - say, 10 batches of 10 goroutines - and see how many connections are open afterward. If you have 100 connections open, something has gone wrong; if you have 10~20, then pooling is working correctly.

Upvotes: 2

Related Questions