Description
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 theID
of ajob
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];
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.