fix: raise MySQL pool 8->16 — 8 starved the instance's own live-sync polling (revision + grid refresh + live_status + chat), so the grid stopped showing other operators' QSOs; 16 avoids the stall and still fits ~15 ops under max_connections=300

This commit is contained in:
2026-07-21 16:50:48 +02:00
parent 40d0ca57c3
commit 9e5868b839
+14 -12
View File
@@ -129,19 +129,21 @@ func translateTextColumns(s string) string {
// OpenMySQL opens the shared MySQL logbook, creating the database if needed,
// then applies the (translated) embedded migrations. multiStatements is enabled
// so multi-statement migration files run in a single Exec.
// tuneMySQLPool sizes the connection pool for a SHARED server. A multi-operator
// special event runs many OpsLog instances against ONE MySQL, whose max_connections
// is a hard global limit (often 100151). A big per-instance pool (we used 50) let
// a handful of ops exhaust the server — "Error 1040: Too many connections" — after
// which queries (the on-air widget, award_refs, the grid) fail silently and the UI
// looks frozen. A modest cap with brisk idle reaping keeps each instance's server
// footprint small so ~10+ ops fit, while still absorbing the UI's concurrent
// logbook queries. No max lifetime: a slow first migration can run for minutes on a
// single connection and reaping it mid-migration drops the selected database.
// tuneMySQLPool sizes the connection pool for a SHARED server. Two opposing needs:
// - A big per-instance pool (we shipped 50) let a handful of ops exhaust the
// server's global max_connections — "Error 1040: Too many connections".
// - Too SMALL a pool starves this instance's OWN concurrent UI queries — the live
// multi-op sync (revision poll every 2s + a 3-query grid refresh), live_status,
// chat, stats, cluster — so the grid stops showing other operators' QSOs. (8 was
// too tight and reintroduced this "deadlock-like stall".)
// 16 is the balance: plenty for the UI's bursts, and ~15 ops still fit under a
// raised max_connections=300 (advise operators to raise it for a big multi-op).
// Brisk idle reaping returns slots to the server; no max lifetime so a slow first
// migration on one connection isn't reaped mid-run (drops the selected database).
func tuneMySQLPool(conn *sql.DB) {
conn.SetMaxOpenConns(8)
conn.SetMaxIdleConns(3)
conn.SetConnMaxIdleTime(30 * time.Second) // return idle connections to the server promptly
conn.SetMaxOpenConns(16)
conn.SetMaxIdleConns(6)
conn.SetConnMaxIdleTime(30 * time.Second)
conn.SetConnMaxLifetime(0)
}