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

问题描述

这个问题让我发疯。我有一个连接到 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。

标签: phppostgresqlpdopostgresql-11pgbouncer

解决方案


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

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

"db2" "db2"

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

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

这两个变化解决了这个问题。感谢此链接对我的帮助,并感谢此线程对 pgbouncer 配置如何工作的更彻底的解释。


推荐阅读