成功将PostgreSQL 9.6.5与Pgbouncer 1.7.2连接。

4

问题:

我无法将pgbouncer 1.7.2连接到运行中的postgresql 9.6.5数据库(Django/Python Web应用程序,Ubuntu 14.04操作系统)。

您能帮助我解决这个问题吗?


背景:

没有pgbouncer时,PostgreSQL完美地工作。我正在使用官方指南来设置pgbouncer。数据库以前是从另一台机器恢复过来的。

所有的东西都在一台机器上。我正尝试使用Unix套接字连接。没有尝试TCP(但接受这种方式)。

数据库名为mydb。我的Django项目已经设置好了通过用户ubuntu连接到它。


我尝试过的:

当我尝试使用psql -d mydb -p 6432 ubuntu(作为用户ubuntu)时,我得到:psql: ERROR: pgbouncer cannot connect to server

同时,pgbouncer.log显示:

01:39:56.428 78472 LOG C-0xfa51e0: mydb/ubuntu@unix(120837):6432 login attempt: db=mydb user=ubuntu tls=no
01:39:56.428 78472 LOG C-0xfa51e0: mydb/ubuntu@unix(120837):6432 closing because: pgbouncer cannot connect to server (age=0)
01:39:56.428 78472 WARNING C-0xfa51e0: mydb/ubuntu@unix(120837):6432 Pooler Error: pgbouncer cannot connect to server
01:40:11.428 78472 LOG S-0xfa0530: mydb/ubuntu@11.65.119.381:5432 closing because: connect failed (age=15)

请注意,psql -d mydb -p 5432 ubuntu 成功登录了 mydb(无需密码)。这里是否是密码导致的问题?
接下来,如果我使用用户 ubuntu 执行 pgbouncer -d pgbouncer.ini,我会收到一个 permission denied 错误。
2017-10-15 23:34:14.325 17606 FATAL Cannot open logfile: '/var/log/postgresql/pgbouncer.log': Permission denied

pgbouncer.log中没有生成相应的日志行。文件perms设置如下:

ubuntu@ip-xxx-xx-xx-xx:/var/log/postgresql$ ls -lh
total 59M
-rw-r--r-- 1 postgres postgres 1.8M Oct 15 23:35 pgbouncer.log
-rw-r----- 1 postgres adm       57M Oct 15 23:07 postgresql-9.6-main.log

我已经配置的内容:

仅供参考,这是我在Django应用程序的settings.py文件中的配置:

DATABASES = {
        'default': {
                'ENGINE': 'django.db.backends.postgresql_psycopg2',
                'NAME': 'mydb', 
                'USER': 'ubuntu',
                'PASSWORD': DB_PASSWORD,
                'HOST': '/var/run/postgresql',                 
                #'PORT': '6432',
        }

如果我取消注释'PORT': '6432',它仍然无法工作。
Pgbouncer的pgbouncer.ini包含以下内容:
[databases]
mydb= host=11.65.119.381 port=5432 user=ubuntu dbname=mydb

logfile = /var/log/postgresql/pgbouncer.log
pidfile = /var/run/postgresql/pgbouncer.pid

; ip address or * which means all ip-s
listen_addr = *
listen_port = 6432

; unix socket is also used for -R.
; On debian it should be /var/run/postgresql
;unix_socket_mode = 0777
;unix_socket_group =
unix_socket_dir = /var/run/postgresql

auth_type = trust
auth_file = /etc/pgbouncer/userlist.txt
admin_users = myuser, postgres, root
stats_users = myuser, postgres, root

auth_type 设置为 any 也无效。


/etc/pgbouncer/userlist.txt 包含:

"ubuntu" "md565j6e98u1z098oiuyt7543poi4561yh3"

我通过 SELECT usename, passwd FROM pg_shadow WHERE usename='ubuntu'; 获得了密码字符串。请注意,这与 Django 的 settings.py 中引用的 DB_PASSWORD 不同(我也在 userlist.txt 中尝试过但未成功)。


pg_hba.conf 包含:

local   all             postgres                                peer

# "local" is for Unix domain socket connections only
local   all             all                                     trust
# IPv4 local connections:
host    all             all             127.0.0.1/32            trust
# IPv6 local connections:
host    all             all             ::1/128                 md5

postgresql.conf 包含:

listen_addresses = '*'
port = 5432 
unix_socket_directories = '/var/run/postgresql'
#unix_socket_group = ''                 # (change requires restart)
#unix_socket_permissions = 0777         # begin with 0 to use octal notation

文件权限:

/var/run/postgresql/ 包含:

total 8.0K
drwxr-s--- 2 postgres postgres 120 Oct 16 00:06 9.6-main.pg_stat_tmp
-rw-r--r-- 1 postgres postgres   6 Oct 15 13:23 9.6-main.pid
-rw-r--r-- 1 postgres postgres   6 Oct 15 23:23 pgbouncer.pid

已经打开了 log_connections。由于这是一个繁忙的服务器,所以它立即开始出现溢出情况,显示如下信息:2017-10-18 06:55:28.130 UTC [75440] [unknown]@[unknown] LOG: connection received: host=[local] 2017-10-18 06:55:28.130 UTC [75440] ubuntu@mydb LOG: connection authorized: user=ubuntu database=mydb。接下来我尝试使用 psql -d mydb -p 6432 ubuntu 命令,但在 PostgreSQL 日志中没有任何新的内容,完全重复了相同的字符串。而在终端上,我收到了错误提示 psql: ERROR: pgbouncer cannot connect to server - Hassan Baig
这意味着 pgbouncer 没有连接到 PostgreSQL 服务器,因此其配置可能存在问题。 - Laurenz Albe
@LaurenzAlbe: 理论上说,这可能是一个端口/防火墙问题吗? - Hassan Baig
是的。不幸的是,我对防火墙或pgBouncer并不了解很多。您可以使用strace命令跟踪pgBouncer进程,以查看它尝试连接到哪里。 - Laurenz Albe
@laurenzalbe:哎呀,strace 不是一个直观的阅读工具。但是这是个好建议——我删除了我在问题中包含的冗长的 pgbouncer.log 错误,并添加了 strace 输出。 - Hassan Baig
显示剩余3条评论
1个回答

1
如果您已经成功地通过Unix套接字连接到Postgres,您可以告诉pgbouncer做同样的事情,方法是将主机指定为您的套接字文件所在的目录(如果您自己编译,则通常为/tmp),但各个发行版会将其放置在不同的位置。因此,请尝试在您的pgbouncer.ini中添加类似以下内容的配置:
[databases]
mydb= host=/tmp dbname=mydb

你可能不需要在使用默认端口号且pgbouncer以用户ubuntu身份运行时设置用户名,因此不需要显式设置它。
在Postgres中执行:
show unix_socket_directories;

查看您实际的套接字目录位置。


在我的情况下,pgbouncer.pid9.6-main.pid 都位于 /var/run/postgresql 目录下(此外,show unix_socket_directories 也指向这里)。因此,在我的情况下,您建议我应该在 pgbouncer.ini 中设置 host=/var/run/postgresql,然后通过 sudo service pgbouncer reload 重新加载 pgbouncer 吗? - Hassan Baig
是的。只要服务配置为使用与您的psql测试相同的用户,那么您应该没问题。而且您可能需要重新启动,而不仅仅是重新加载。 - Johann Oskarsson
很好。这个更改使我能够通过 psql -d mddb -p 6432 ubuntu 登录。Pgbouncer仍然没有开始运行。你能否快速查看我在问题中发布的Django配置 - 特别是我已经注释的端口?我需要取消注释才能继续吗?我在生产环境中,所以在执行此操作之前要特别小心。 - Hassan Baig
你所注释的端口是pgbouncer监听连接的端口号(文件名),它监听在它创建的Unix Socket上。你可以使用 ls -a /var/run/postgresql 命令查看这些文件。如果没有该文件,它将尝试连接到Postgres服务器本身。话虽如此,我不知道如何配置Django——只要正确地将参数发送给psychopg2即可。 - Johann Oskarsson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接