#php #postgresql #pdo #postgresql-11 #pgbouncer
Вопрос:
Эта проблема сводит меня с ума. У меня есть PHP-скрипт, который подключается к базе данных postgresql, и у меня работает 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.
Я ни за что на свете не могу понять, почему PDO PHP возвращается к методу аутентификации «доверие», я не хочу, чтобы он это делал, я хочу, чтобы он обычно отправлял пароль.
И почему он должен работать с одной базой данных, а не с другой? Является ли это вопросом 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
Эти два изменения устранили проблему. Спасибо этой ссылке за помощь мне и за эту тему для более подробного объяснения того, как работает конфигурация pgbouncer.