-
Notifications
You must be signed in to change notification settings - Fork 21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
HA: Limit max open database connections to 1
#828
Conversation
The HA transaction is rolled back correctly with: |
528b7a1
to
39502b3
Compare
1
1
39502b3
to
4c1fbac
Compare
This is the proof that we actually leak database connections but only for as long as the context is not cancelled. package main
import (
"context"
"github.com/icinga/icinga-go-library/logging"
"github.com/icinga/icingadb/internal/command"
"go.uber.org/zap"
"log"
"time"
)
func main() {
cmd := command.New()
db, err := cmd.Database(logging.NewLogger(zap.NewNop().Sugar(), time.Second))
if err != nil {
log.Fatal(err)
}
db.SetMaxOpenConns(3)
go func() {
time.Sleep(1 * time.Second)
ctx, _ := context.WithDeadline(context.Background(), time.Now().Add(10*time.Second))
_, _ = db.BeginTxx(ctx, nil)
return
}()
go func() {
time.Sleep(1 * time.Second)
ctx, _ := context.WithDeadline(context.Background(), time.Now().Add(10*time.Second))
_, _ = db.BeginTxx(ctx, nil)
return
}()
time.Sleep(3 * time.Second)
ctx, cancelFunc := context.WithDeadline(context.Background(), time.Now().Add(2*time.Second))
defer cancelFunc()
_ = db.PingContext(ctx)
log.Printf("OpenConnections: %v", db.Stats().OpenConnections)
log.Printf("InUse: %v", db.Stats().InUse)
}
~/Workspace/go/icingadb (set-ha-conn-limit ✗) go run ./cmd/decoder/decoder.go --config config.example.yml
2024/10/23 16:19:59 OpenConnections: 3
2024/10/23 16:19:59 InUse: 2 |
4c1fbac
to
2fb6c52
Compare
doc/03-Configuration.md
Outdated
@@ -63,6 +63,12 @@ do not need any manual adjustments. | |||
| max_rows_per_transaction | **Optional.** Maximum number of rows Icinga DB is allowed to `SELECT`,`DELETE`,`UPDATE` or `INSERT` in a single transaction. Defaults to `8192`. | | |||
| wsrep_sync_wait | **Optional.** Enforce [Galera cluster](#galera-cluster) nodes to perform strict cluster-wide causality checks. Defaults to `7`. | | |||
|
|||
!!! info |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would remove this information as it is an implementation detail. Sure, users might be surprised if there are 17 database connections, but I doubt anyone will ever count them.
Instead, we could reduce the size of the main pool by one. But I wouldn't attach too much importance to that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the size of the main pool is initialized in the library, we don't want to adjust it just because of Icinga DB's HA feature. Thus, I removed the highlighted info box.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The example configuration would also have to be adjusted. But please just remove it completely. It is irrelevant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As we discussed offline, I have completely removed the extra info.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I want to summarize our discussion: With this PR, we currently have only one connection that isn't tied to max_connections
. However, there's a chance more could be added or changed, leaving it up to the user to determine and maintain the correct max_connections
value if the goal is to truly limit Icinga DB database connections to that number. Therefore, if max_connections
is intended to represent the actual maximum connections, it should be implemented accordingly, rather than documented that some connections are unaffected by that setting.
2fb6c52
to
3217538
Compare
3217538
to
4062f86
Compare
This bug is being addressed in #800. In spite of other changes over there, I am a bit critical about reducing the amount of database connections to a single one. Currently, there is still the possibility of a long-running |
With a long-running commit and more than one database connection, successive transactions would be blocked during the SELECT. With only one database connection, the code waits at the begin transaction point. To me this is a valid change as we are not opening new database connections unnecessarily. But since PR #800 was merged, the PR and commit description should reflect that this change is only about that. @yhabteab Would you please adjust that accordingly? |
4062f86
to
14c3c17
Compare
@yhabteab With both MySQL and PostgreSQL integration tests failing, I think something is wrong 😆 |
I followed @yhabteab's statement that this PR breaks when used together with #800 and tried a bisect with this PR's change on each commit of my PR. Indeed, dd0ca8f broke it. Let me debug it further :)
|
During #800, the commit dd0ca8f inlined the HA.insertEnvironment method into the retryable realization function. However, while doing so, I forgot to change the query execution context from h.db to tx. This resulted in an error when being used together with a single database connection, as introduced in #828. Co-Authored-By: Yonas Habteab <[email protected]>
@yhabteab: Could you please rebase again. Thanks :) |
Previously, the HA feature was allowed to open `max_connections` database connection in parallel to other Icinga DB components. Meaning, Icinga DB wasn't limited to the configured `max_connections`, but effectively to `2 * max_connections`.
14c3c17
to
ce3309f
Compare
Already did. |
Previously, the HA feature was allowed to open
max_connections
database connection in parallel to other Icinga DB components. Meaning, Icinga DB wasn't limited to the configuredmax_connections
, but effectively to2 * max_connections
.