支持的 PostgreSQL 驱动程序

支持的驱动程序

pgdriver

Bun 自带一个名为 pgdriver在新窗口中打开 的 PostgreSQL 驱动程序,它允许使用 DSN(连接字符串)连接到 PostgreSQL 数据库

import (
	"github.com/uptrace/bun"
	"github.com/uptrace/bun/dialect/pgdialect"
	"github.com/uptrace/bun/driver/pgdriver"
)

dsn := "postgres://postgres:@localhost:5432/test?sslmode=disable"
// dsn := "unix://user:pass@dbname/var/run/postgresql/.s.PGSQL.5432"
sqldb := sql.OpenDB(pgdriver.NewConnector(pgdriver.WithDSN(dsn)))

db := bun.NewDB(sqldb, pgdialect.New())

您可以在 DSN 中指定以下选项

  • ?sslmode=verify-full - 启用 TLS。
  • ?sslmode=disable - 禁用 TLS。
  • ?dial_timeout=5s - 建立新连接的超时时间。
  • ?read_timeout=5s - 套接字读取的超时时间。
  • ?write_timeout=5s - 套接字写入的超时时间。
  • ?timeout=5s - 设置上面描述的所有三个超时时间。
  • ?application_name=myapp - PostgreSQL 应用程序名称。

pgdriver 将所有未知选项视为 PostgreSQL 配置参数,例如,?search_path=my_search_path 在每次创建连接时执行以下查询

SET search_path TO 'my_search_path'

除了 DSN 之外,您还可以使用 pgdriver.Option在新窗口中打开 来配置驱动程序

pgconn := pgdriver.NewConnector(
	pgdriver.WithNetwork("tcp"),
	pgdriver.WithAddr("localhost:5437"),
	pgdriver.WithTLSConfig(&tls.Config{InsecureSkipVerify: true}),
	pgdriver.WithUser("test"),
	pgdriver.WithPassword("test"),
	pgdriver.WithDatabase("test"),
	pgdriver.WithApplicationName("myapp"),
	pgdriver.WithTimeout(5 * time.Second),
	pgdriver.WithDialTimeout(5 * time.Second),
	pgdriver.WithReadTimeout(5 * time.Second),
	pgdriver.WithWriteTimeout(5 * time.Second),
	pgdriver.WithConnParams(map[string]interface{}{
		"search_path": "my_search_path",
	}),
)

或者一起使用 DSN 和驱动程序选项

pgconn := pgdriver.NewConnector(
    pgdriver.WithDSN("postgres://postgres:@localhost:5432/test?sslmode=verify-full"),
    pgdriver.WithTLSConfig(tlsConfig),
)

pgdriver.Error

pgdriver 公开 Error在新窗口中打开 类型来处理 PostgreSQL 错误

import "github.com/jackc/pgerrcode"

_, err := db.NewInsert().Model(&model).Exec(ctx)
if err != nil {
    if err, ok := err.(pgdriver.Error); ok && err.IntegrityViolation() {
        // ...
    } else if err.Field('C') == pgerrcode.InvalidTransactionState {
        // ...
    } else {
        // ...
    }
}

调试

如果您怀疑 pgdriver 存在问题,请尝试用 pgx 替换它,并检查问题是否消失。

pgx

作为 pgdriver 的替代方案,您也可以使用 pgx在新窗口中打开pgdialect。使用 pgx,您可以禁用隐式准备好的语句,因为 Bun 不受益于使用它们

import (
	"github.com/uptrace/bun"
	"github.com/uptrace/bun/dialect/pgdialect"
	"github.com/jackc/pgx/v5/stdlib"
)

config, err := pgx.ParseConfig("postgres://postgres:@localhost:5432/test?sslmode=disable")
if err != nil {
	panic(err)
}
config.PreferSimpleProtocol = true

sqldb := stdlib.OpenDB(*config)
db := bun.NewDB(sqldb, pgdialect.New())

从 v5 开始,您也可以使用 pgxpool,如下所示

import "github.com/jackc/pgx/v5/stdlib"

pool, err := pgxpool.NewWithConfig(context.Background(), config)
if err != nil {
	panic(err)
}

sqldb := stdlib.OpenDBFromPool(pool)
db := bun.NewDB(db, pgdialect.New())

PgBouncer

为了获得更好的性能,您可以使用服务器端连接池,例如 PgBouncer在新窗口中打开sql.DB 附带的池是客户端池,它不会替换 PgBouncer 提供的服务器端池。

ZFS

如果您存储大量数据(> 100 GB),请考虑使用 ZFS 文件系统,它可以实现 2-3 倍的数据压缩和高效的 ARC 缓存。见

备份

要备份 PostgreSQL 数据库,请考虑使用 PgBackRest 与 S3

另请参阅