Files
ttstd-infinite-canvas/backend/internal/database/database.go
Catlaxy AI 6dedc5973c fix(database): 数据库连接 - 消费 libpq keepalive 参数并默认限制闲置事务 (#737)
pgx 不识别 DSN 中 libpq 的 keepalives* 参数,会作为服务端运行参数发送导致连接被拒;改为在建连前消费并应用到 TCP 拨号器。
未显式配置时为每条连接默认设置 idle_in_transaction_session_timeout=5min,避免卡住的事务长期持锁;DSN 显式配置时以 DSN 为准。
建连钩子先复制共享的 RuntimeParams,避免多条连接之间累积修改。

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 22:04:27 +08:00

66 lines
1.5 KiB
Go

package database
import (
"errors"
"fmt"
"os"
"strings"
"yingce/backend/internal/logging"
"github.com/jackc/pgx/v5/stdlib"
"gorm.io/driver/postgres"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
)
type Config struct {
Driver string
DSN string
DataDir string
}
func Open(config Config) (*gorm.DB, error) {
driver := strings.ToLower(strings.TrimSpace(config.Driver))
if driver == "" {
driver = "sqlite"
}
switch driver {
case "sqlite":
dsn := strings.TrimSpace(config.DSN)
if dsn == "" {
if err := os.MkdirAll(config.DataDir, 0o755); err != nil {
return nil, err
}
dsn = config.DataDir + "/open_ai_canvas.db?_busy_timeout=5000&_journal_mode=WAL&_foreign_keys=on&_synchronous=NORMAL"
}
return gorm.Open(sqlite.Open(dsn), &gorm.Config{Logger: logging.GormLogger()})
case "postgres", "postgresql":
dsn := strings.TrimSpace(config.DSN)
if dsn == "" {
return nil, errors.New("PostgreSQL 模式必须配置 DATABASE_URL")
}
return gorm.Open(postgres.New(postgres.Config{
DSN: dsn,
OptionOpenDB: []stdlib.OptionOpenDB{stdlib.OptionBeforeConnect(configurePostgresConnection)},
}), &gorm.Config{Logger: logging.GormLogger()})
default:
return nil, fmt.Errorf("不支持的数据库驱动:%s", driver)
}
}
func ConfigurePool(db *gorm.DB) error {
sqlDB, err := db.DB()
if err != nil {
return err
}
if db.Dialector.Name() == "postgres" {
sqlDB.SetMaxOpenConns(30)
sqlDB.SetMaxIdleConns(10)
return nil
}
sqlDB.SetMaxOpenConns(8)
sqlDB.SetMaxIdleConns(4)
return nil
}