Skip to content

Potential memory leak on Sql.Db.Close() #1319

Open
@Harmos274

Description

@Harmos274

sqlite3 version: github.com/mattn/go-sqlite3 v1.14.22

Hello, i would like to know if i'm doing something wrong here... It seems that sql.Db.Close() does not release allocated memory when called.

In fact, i suspect it to cause a memory leak.

I have a project that is a net/http api that exposes a GET /instances/{instance}/jobs/{jobID}/status route.

  • instance is a hash string that i get the name of an sqlite database file from.
  • jobID is the ID of a job in the given database.

My service will take the database {instance}.sqlite, opens it and query the status of the job {jobID}, Afterward it will close the given database.

flowchart LR;
    A[Http GET]-->B[net/http API];
    B-->C[Sql.Open instance.sqlite];
    C-->D[Query Job status];
    D-->E[Sql.DB.Close instance.sqlite];
    E-->F[Http response];
Loading

Here's a code sample that shows how i open and close both of my databases.

func onDatabaseContext[T any](ctx context.Context, dbManager SetupDB, instance string, onDBFunc func(ctx context.Context, writeDB, readDB *sql.DB) (T, error)) (written T, err error) {
	var writeDB, readDB *sql.DB

        // Compute sqlite db path from instance number
	path := dbManager.dbPath(instance)

	// Write in sqlite is mono threaded, therefore we use a multithreaded read db and mono threaded write db
	writeDB, err = sql.Open("sqlite3", fmt.Sprintf("file:%s?mode=rw&_journal=WAL&_timeout=5000&_txlock=immediate", path))
	if err != nil {
		return
	}

	readDB, err = sql.Open("sqlite3", fmt.Sprintf("file:%s?mode=ro&_timeout=5000&parseTime=true", path))
	if err != nil {
		return
	}

	err = initDB(ctx, writeDB)

	if err != nil {
		return
	}

	res, err := onDBFunc(ctx, writeDB, readDB)

	writeDB.Close()
	readDB.Close()

	return res, err
}

The problem is that when i close my Sql.Db handles, the allocated memory is not released, even after some time. I actually work on a lot of different sql databases which causes my service to crash from OOM error eventually.

I'm sure my pattern is not efficient, it is a proof of concept. But i would expect resources to be released when i close my handles, or at least be garbage collected after some time, which does not happen.

Could someone explain to me what i am doing wrong please ?

Thank you for your time.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions