当对一个数据库使用 pgbouncer 而不是另一个数据库时,PDO 会引发有关“信任”身份验证的连接错误。设置相同

Posted

技术标签:

【中文标题】当对一个数据库使用 pgbouncer 而不是另一个数据库时,PDO 会引发有关“信任”身份验证的连接错误。设置相同【英文标题】:PDO throws connection error about "trust" authentication when using pgbouncer for one database, but not another. Settings are identical 【发布时间】:2021-10-16 01:46:07 【问题描述】:

这个问题让我发疯。我有一个连接到 postgresql 数据库的 php 脚本,并且我正在运行 pgbouncer 以进行连接池。

我已经使用两个数据库对其进行了测试,当我直接连接时,两者都可以正常工作。这是我的连接代码:

        $dbuser='db1'; $dbpass='db1'; $dbname='db1';

        $dsn="pgsql:port=5432;host=/var/run/postgresql;dbname=$dbname";

        $options = [
                PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
                PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
                PDO::ATTR_EMULATE_PREPARES   => false,
        ];
        try 
                $pg_pdo=new PDO($dsn, $dbuser, $dbpass, $options); 
         catch (\PDOException $e) 
                throw new \PDOException($e->getMessage(), (int)$e->getCode());
        

这段代码,db1,无论我保留端口 5432,还是将端口更改为 6432,都可以正常工作。当我将数据库名称、用户和密码更改为 db2 时,它在端口上也可以正常工作5432.

但是当我连接到第二个数据库将端口设置为 6432 时,我收到以下错误:

PHP Fatal error:  Uncaught PDOException: SQLSTATE[08006] [7] ERROR:  "trust" authentication failed

现在,我已经检查了我的/etc/pgbouncer/pgbouncer.ini,它包含以下几行:

[databases]
* =

这意味着任何数据库的连接信息都只是被转发。文件中没有提到 db1 和 db2。

另外,我的/var/lib/pgsql/11/data/pg_hba.conf 文件:

# "local" is for Unix domain socket connections only
local   all              postgres                                peer
local   db1              db1                                     md5
local   db2              db2                                     md5
# IPv4 local connections:
host    all             all             127.0.0.1/32            ident
# IPv6 local connections:
host    all             all             ::1/128                 ident
# Allow replication connections from localhost, by a user with the
# replication privilege.
local   replication     all                                     peer
host    replication     all             127.0.0.1/32            ident
host    replication     all             ::1/128                 ident

是的,我已经重新启动了 pgbouncer.service 和 postgresql-11.service。

我一辈子都想不通为什么 PHP 的 PDO 依赖于“信任”身份验证方法,我不希望它这样做,我希望它能够正常发送密码。

为什么它会使用一个数据库而不是另一个?这是db2 角色缺少db1 被授予的某种特权的问题,还是数据库不同的问题?

如果相关,我的环境是 PHP 7.4、PostgreSQL 11.12 和 pgbouncer 1.15。

【问题讨论】:

【参考方案1】:

我最终自己解决了这个问题。显然还需要编辑/etc/pgbouncer/userlist.txt文件:

该文件有 db1 的列表,但没有 db2。添加第二行(格式为“用户名”“密码”):

"db2" "db2"

但是,这不足以解决问题。显然,我已经以 root 身份创建了这个文件。它需要被 pgbouncer 拥有,所以这个命令是必要的:

chown pgbouncer:pgbouncer /etc/pgbouncer/userlist.txt

这两个更改解决了问题。感谢 this link 对我的帮助,感谢 this thread 对 pgbouncer 配置如何工作的更全面的解释。

【讨论】:

以上是关于当对一个数据库使用 pgbouncer 而不是另一个数据库时,PDO 会引发有关“信任”身份验证的连接错误。设置相同的主要内容,如果未能解决你的问题,请参考以下文章

使用PgBouncer连接池

多个端口上的 pgBouncer?

greenplum 连接池pgbouncer的使用

安装配置PGBouncer连接池

Kubernetes 上带有 Pgbouncer 的 Npgsql - 高延迟

linux ---pgbouncer的安装和配置