实验步骤:
一.安装
1.下载pgbouncer的安装包
http://pgfoundry.org/frs/?group_id=1000258&release_id=1952,本次下载的安装包是pgbouncer-1.5.2.tar.gz
2.下载libevent包
http://monkey.org/~provos/libevent/,见pgbouncer源码包中的Readme
这玩意也是个好东西,在很多地方用到
3.安装libevent
$ cd libevent-2.0.19-stable
$ ./configure --prefix=/opt/pgbouncer/libevent
$ make
$ make install
加载libevent动态库
cd /etc/ld.so.conf.d/
vim libevent2.0.21.conf
/usr/local/libevent/lib
ldconfig
4.安装pgbouncer
$ cd pgbouncer-1.5.2
$ ./configure --prefix=/opt/pgbouncer/pgbouncer --with-libevent=/opt/pgbouncer/libevent/
$ make
$ make install
配置运行环境变量
vim ~/.bash_profile
PATH=/opt/pgbouncer/pgbouncer/bin:$PATH
export PATH
执行生效
source ~/.bash_profile
查看pgbouncer是否安装成功,可以通过查看config.log中最后的返回值exit来确认,0是成功1是失败.
二.配置
1.配置pgbouncer的cfg文件
[highgo@sourcedb config]$ pwd
/opt/pgbouncer/pgbouncer/config ----可以手动创建此目录和文件
$ more pgbouncer.ini ----修改该文件内容后,需要重启pgbouncer后才生效 ----重启pgbouncer命令(pgbouncer -R -d pgbouncer.ini)
[databases]
aaa = host=127.0.0.1 port=5866 dbname=highgo user=highgo password=highgo123
[pgbouncer]
listen_port = 1999
listen_addr = 127.0.0.1
auth_type = md5
auth_file = /opt/pgbouncer/pgbouncer/users.txt
logfile = /opt/pgbouncer/pgbouncer/pgbouncer.log
pidfile = /opt/pgbouncer/pgbouncer/pgbouncer.pid
admin_users = highgo
pool_mode = Transaction
2.配置用户密码文件users.txt
[highgo@sourcedb pgbouncer]$ pwd
/opt/pgbouncer/pgbouncer
$ cat users.txt
"highgo" "highgo123"
三.启动
1.启动命令
[postgres9.6@localhost config]$ pgbouncer -d pgbouncer.ini
2012-08-21 00:29:55.573 4247 LOG File descriptor limit: 1024 (H:1024), max_client_conn: 100, max fds possible: 130
2.查看日志
$ tail -f /opt/pgbouncer/pgbouncer/pgbouncer.log
[highgo@sourcedb pgbouncer]$ psql -h 127.0.0.1 -p 5866 -U highgo highgo
Password for user highgo:
psql (3.1.4)
Type "help" for help.
highgo=#
[highgo@sourcedb config]$ psql -h 127.0.0.1 -p 1999 -d aaa -U highgo
Password for user highgo:
psql (3.1.4)
Type "help" for help.
aaa=# select current_database();
current_database
------------------
highgo
(1 row)
aaa=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
--------------+--------------+----------+------------+------------+-------------------
benchmarksql | benchmarksql | UTF8 | zh_CN.utf8 | zh_CN.utf8 |
highgo | highgo | UTF8 | zh_CN.utf8 | zh_CN.utf8 |
template0 | highgo | UTF8 | zh_CN.utf8 | zh_CN.utf8 | =c/highgo +
| | | | | highgo=CTc/highgo
template1 | highgo | UTF8 | zh_CN.utf8 | zh_CN.utf8 | =c/highgo +
| | | | | highgo=CTc/highgo
(4 rows)
aaa=#
aaa=# \q
[highgo@sourcedb config]$ psql -h 127.0.0.1 -p 1999 -U highgo -d pgbouncer
Password for user highgo:
psql (3.1.4, server 1.5.4/bouncer)
Type "help" for help.
pgbouncer=# \l
ERROR: invalid command 'SELECT d.datname as "Name",
pg_catalog.pg_get_userbyid(d.datdba) as "Owner",
pg_catalog.pg_encoding_to_char(d.encoding) as "Encoding",
pg_catalog.array_to_string(d.datacl, '\n') AS "Access privileges"
FROM pg_catalog.pg_database d
ORDER BY 1;', use SHOW HELP;
pgbouncer=# show config
pgbouncer-# ;
key | value | changeable
---------------------------+----------------------------------------+------------
job_name | pgbouncer | no
conffile | pgbouncer.ini | yes
logfile | /opt/pgbouncer/pgbouncer/pgbouncer.log | yes
pidfile | /opt/pgbouncer/pgbouncer/pgbouncer.pid | no
listen_addr | * | no
listen_port | 1999 | no
listen_backlog | 128 | no
unix_socket_dir | /tmp | no
unix_socket_mode | 511 | no
unix_socket_group | | no
auth_type | md5 | yes
auth_file | /opt/pgbouncer/pgbouncer/users.txt | yes
pool_mode | transaction | yes
max_client_conn | 100 | yes
default_pool_size | 20 | yes
min_pool_size | 0 | yes
reserve_pool_size | 0 | yes
reserve_pool_timeout | 5 | yes
******************************************************************************************
连接pgbouncer数据库时提示不允许连接:
[postgres9.6@sourcedb config]$ psql -h 127.0.0.1 -p 6432 -U postgres9.6 pgbouncer
psql: ERROR: not allowed
[postgres9.6@sourcedb config]$ psql -h 127.0.0.1 -p 6432 -U test pgbouncer
psql: ERROR: not allowed
需要修改admin_users如下:
[postgres9.6@sourcedb config]$ pwd
/hgdata/pgbouncer-1.5.4/config
[postgres9.6@sourcedb config]$ cat pgbouncer.ini |grep admin_users
;admin_users = user2, someadmin, otheradmin
admin_users=postgres9.6
[postgres9.6@sourcedb config]$ psql -h 127.0.0.1 -p 6432 -U postgres9.6 pgbouncer
Password for user postgres9.6:
Null display is "NULL".
psql:/home/postgres9.6/.psqlrc:2: NOTICE: SET ignored
Pager is always used.
Timing is on.
psql (9.6.1, server 1.5.4/bouncer)
Type "help" for help.
postgres9.6@127.0.0.1:6432 pgbouncer# \q
[postgres9.6@sourcedb config]$ psql -h 127.0.0.1 -p 6432 -U test pgbouncer
psql: ERROR: not allowed
**********************************************************************************************
在连接池端看连接数:(transaction是基于事务模式的 )
pgbouncer=# show clients;
type | user | database | state | addr | port | local_addr | local_port | connect_time | request_time | ptr | link
------+--------+-----------+--------+-----------+-------+------------+------------+---------------------+---------------------+-----------+------
C | highgo | aaa | active | 127.0.0.1 | 23590 | 127.0.0.1 | 1999 | 2017-07-19 09:34:34 | 2017-07-19 09:34:34 | 0x1d71528 |
C | highgo | aaa | active | 127.0.0.1 | 23591 | 127.0.0.1 | 1999 | 2017-07-19 09:34:36 | 2017-07-19 09:34:36 | 0x1d71690 |
C | highgo | aaa | active | 127.0.0.1 | 23592 | 127.0.0.1 | 1999 | 2017-07-19 09:34:36 | 2017-07-19 09:34:36 | 0x1d717f8 |
C | highgo | aaa | active | 127.0.0.1 | 23593 | 127.0.0.1 | 1999 | 2017-07-19 09:34:37 | 2017-07-19 09:34:37 | 0x1d71960 |
C | highgo | aaa | active | 127.0.0.1 | 23594 | 127.0.0.1 | 1999 | 2017-07-19 09:34:38 | 2017-07-19 09:34:38 | 0x1d71ac8 |
C | highgo | aaa | active | 127.0.0.1 | 23595 | 127.0.0.1 | 1999 | 2017-07-19 09:34:39 | 2017-07-19 09:34:39 | 0x1d71c30 |
C | highgo | pgbouncer | active | 127.0.0.1 | 23599 | 127.0.0.1 | 1999 | 2017-07-19 09:34:55 | 2017-07-19 09:34:59 | 0x1d713c0 |
(7 rows)
pgbouncer=# show fds;
fd | task | user | database | addr | port | cancel | link | client_encoding | std_strings | datestyle | timezone
----+--------+--------+----------+-----------+-------+----------------------+------+-----------------+-------------+-----------+----------
9 | pooler | | | 127.0.0.1 | 1999 | 0 | 0 | | | |
10 | pooler | | | unix | 1999 | 0 | 0 | | | |
14 | client | highgo | aaa | 127.0.0.1 | 23590 | 9334293529859771476 | 0 | UTF8 | on | ISO, YMD | PRC
15 | client | highgo | aaa | 127.0.0.1 | 23591 | 13214640478787632242 | 0 | UTF8 | on | ISO, YMD | PRC
16 | client | highgo | aaa | 127.0.0.1 | 23592 | 12262729768783333509 | 0 | UTF8 | on | ISO, YMD | PRC
17 | client | highgo | aaa | 127.0.0.1 | 23593 | 16056577313122752872 | 0 | UTF8 | on | ISO, YMD | PRC
18 | client | highgo | aaa | 127.0.0.1 | 23594 | 10476624138286828314 | 0 | UTF8 | on | ISO, YMD | PRC
19 | client | highgo | aaa | 127.0.0.1 | 23595 | 8296638690593801308 | 0 | UTF8 | on | ISO, YMD | PRC
13 | server | highgo | aaa | 127.0.0.1 | 5866 | 46253389067440 | 0 | UTF8 | on | ISO, YMD | PRC
(9 rows)
在DB端查询:
aaa=# select count(*) from pg_stat_activity ;
count
-------
2
(1 row)
每产生或退出一个连接,后台日志都记录如下:
[highgo@sourcedb pgbouncer]$ tail -f pgbouncer.log
2017-07-19 10:22:39.051 10767 LOG C-0x1d71d98: aaa/highgo@127.0.0.1:23602 login attempt: db=aaa user=highgo
2017-07-19 10:22:39.051 10767 LOG C-0x1d71d98: aaa/highgo@127.0.0.1:23602 closing because: client unexpected eof (age=0)
2017-07-19 10:22:41.271 10767 LOG C-0x1d71d98: aaa/highgo@127.0.0.1:23603 login attempt: db=aaa user=highgo
2017-07-19 10:22:48.461 10767 LOG C-0x1d71d98: aaa/highgo@127.0.0.1:23603 closing because: client close request (age=7)
pgbouncer=# show help;
NOTICE: Console usage
DETAIL:
SHOW HELP|CONFIG|DATABASES|POOLS|CLIENTS|SERVERS|VERSION
SHOW STATS|FDS|SOCKETS|ACTIVE_SOCKETS|LISTS|MEM
SHOW DNS_HOSTS|DNS_ZONES
SET key = arg
RELOAD
PAUSE [<db>]
RESUME [<db>]
KILL <db>
SUSPEND
SHUTDOWN
SHOW
对于https://my.oschina.net/Kenyon/blog/73935中提到的“2.测试过程中,假如第一次访问被拒绝以后(不是密码不对),后续访问会直接拒绝,此举可以有效降低攻击性的访问。”,在实验中没有发现此问题:
[highgo@sourcedb pgbouncer]$ psql -h 127.0.0.1 -p 1999 -d aaa -U highgo
Password for user highgo:
psql: ERROR: Auth failed
[highgo@sourcedb pgbouncer]$ psql -h 127.0.0.1 -p 1999 -d aaa -U highgo
Password for user highgo:
psql: ERROR: Auth failed
[highgo@sourcedb pgbouncer]$ psql -h 127.0.0.1 -p 1999 -d aaa -U highgo
Password for user highgo:
psql: ERROR: Auth failed
[highgo@sourcedb pgbouncer]$ psql -h 127.0.0.1 -p 1999 -d aaa -U highgo
Password for user highgo:
psql: ERROR: Auth failed
[highgo@sourcedb pgbouncer]$ psql -h 127.0.0.1 -p 1999 -d aaa -U highgo
Password for user highgo:
psql (3.1.4)
Type "help" for help.
aaa=#
******************************************************************************************************
将pool_mode修改为session:(session是默认的模式,每开启一个进程,DB端也会开启一个新的进程 )
pgbouncer=# reload; -->此时需要reload即可生效,无需重启pgbouncer
pgbouncer=# show config;
key | value | changeable
---------------------------+----------------------------------------+------------
job_name | pgbouncer | no
conffile | pgbouncer.ini | yes
logfile | /opt/pgbouncer/pgbouncer/pgbouncer.log | yes
pidfile | /opt/pgbouncer/pgbouncer/pgbouncer.pid | no
listen_addr | * | no
listen_port | 1999 | no
listen_backlog | 128 | no
unix_socket_dir | /tmp | no
unix_socket_mode | 511 | no
unix_socket_group | | no
auth_type | md5 | yes
auth_file | /opt/pgbouncer/pgbouncer/users.txt | yes
pool_mode | session | yes
...
在连接池中查询:
pgbouncer=# show clients;
type | user | database | state | addr | port | local_addr | local_port | connect_time | request_time | ptr | link
------+--------+-----------+--------+-----------+-------+------------+------------+---------------------+---------------------+-----------+------
C | highgo | aaa | active | 127.0.0.1 | 23621 | 127.0.0.1 | 1999 | 2017-07-19 10:42:18 | 2017-07-19 10:42:18 | 0x1d713c0 |
C | highgo | aaa | active | 127.0.0.1 | 23623 | 127.0.0.1 | 1999 | 2017-07-19 10:42:31 | 2017-07-19 10:42:31 | 0x1d71c30 |
C | highgo | aaa | active | 127.0.0.1 | 23625 | 127.0.0.1 | 1999 | 2017-07-19 10:42:44 | 2017-07-19 10:42:44 | 0x1d71ac8 |
C | highgo | aaa | active | 127.0.0.1 | 23627 | 127.0.0.1 | 1999 | 2017-07-19 10:42:52 | 2017-07-19 10:42:52 | 0x1d71960 |
C | highgo | pgbouncer | active | 127.0.0.1 | 23619 | 127.0.0.1 | 1999 | 2017-07-19 10:40:50 | 2017-07-19 10:43:04 | 0x1d71d98 |
(5 rows)
pgbouncer=# show fds;
fd | task | user | database | addr | port | cancel | link | client_encoding | std_strings | datestyle | timezone
----+--------+--------+----------+-----------+-------+----------------------+------+-----------------+-------------+-----------+----------
9 | pooler | | | 127.0.0.1 | 1999 | 0 | 0 | | | |
10 | pooler | | | unix | 1999 | 0 | 0 | | | |
8 | client | highgo | aaa | 127.0.0.1 | 23621 | 9501733392119200235 | 0 | UTF8 | on | ISO, YMD | PRC
14 | client | highgo | aaa | 127.0.0.1 | 23623 | 6441374485719584038 | 0 | UTF8 | on | ISO, YMD | PRC
15 | client | highgo | aaa | 127.0.0.1 | 23625 | 3477675787395047246 | 0 | UTF8 | on | ISO, YMD | PRC
16 | client | highgo | aaa | 127.0.0.1 | 23627 | 16796806409626555809 | 0 | UTF8 | on | ISO, YMD | PRC
(6 rows)
在DB端查询:
aaa=# select count(*) from pg_stat_activity ;
count
-------
5
(1 row)
**************************************************************************************
此时当把pool_mode由session改为transaction,然后reload后,从连接池中查看连接在增加,但从DB端查看连接没有增加也没有减少:
pgbouncer=# show clients;
type | user | database | state | addr | port | local_addr | local_port | connect_time | request_time | ptr | link
------+--------+-----------+--------+-----------+-------+------------+------------+---------------------+---------------------+-----------+------
C | highgo | aaa | active | 127.0.0.1 | 23623 | 127.0.0.1 | 1999 | 2017-07-19 10:42:31 | 2017-07-19 10:50:41 | 0x1d71c30 |
C | highgo | aaa | active | 127.0.0.1 | 23625 | 127.0.0.1 | 1999 | 2017-07-19 10:42:44 | 2017-07-19 10:50:43 | 0x1d71ac8 |
C | highgo | aaa | active | 127.0.0.1 | 23627 | 127.0.0.1 | 1999 | 2017-07-19 10:42:52 | 2017-07-19 10:50:44 | 0x1d71960 |
C | highgo | aaa | active | 127.0.0.1 | 23633 | 127.0.0.1 | 1999 | 2017-07-19 10:47:21 | 2017-07-19 10:50:39 | 0x1d713c0 |
C | highgo | aaa | active | 127.0.0.1 | 23637 | 127.0.0.1 | 1999 | 2017-07-19 10:47:37 | 2017-07-19 10:50:45 | 0x1d717f8 |
C | highgo | aaa | active | 127.0.0.1 | 23642 | 127.0.0.1 | 1999 | 2017-07-19 10:50:58 | 2017-07-19 10:51:18 | 0x1d71690 |
C | highgo | aaa | active | 127.0.0.1 | 23644 | 127.0.0.1 | 1999 | 2017-07-19 10:52:38 | 2017-07-19 10:52:43 | 0x1d71528 |
C | highgo | pgbouncer | active | 127.0.0.1 | 23640 | 127.0.0.1 | 1999 | 2017-07-19 10:50:33 | 2017-07-19 10:52:49 | 0x1d71d98 |
(8 rows)
aaa=# select count(*) from pg_stat_activity ;
count
-------
6 <--此时仍然显示6
(1 row)
此时在DB端 断开部分连接,仅剩余1个连接的情况下:
pgbouncer=# show clients;
type | user | database | state | addr | port | local_addr | local_port | connect_time | request_time | ptr | link
------+--------+-----------+--------+-----------+-------+------------+------------+---------------------+---------------------+-----------+------
C | highgo | aaa | active | 127.0.0.1 | 23644 | 127.0.0.1 | 1999 | 2017-07-19 10:52:38 | 2017-07-19 10:53:46 | 0x1d71528 |
C | highgo | pgbouncer | active | 127.0.0.1 | 23640 | 127.0.0.1 | 1999 | 2017-07-19 10:50:33 | 2017-07-19 10:53:49 | 0x1d71d98 |
(2 rows)
DB端查询还是显示原来的数量:
aaa=# select count(*) from pg_stat_activity ;
count
-------
6 <--此时仍然显示6
(1 row)
此时断开所有连接重连:
pgbouncer=# show clients;
type | user | database | state | addr | port | local_addr | local_port | connect_time | request_time | ptr | link
------+--------+-----------+--------+-----------+-------+------------+------------+---------------------+---------------------+-----------+------
C | highgo | pgbouncer | active | 127.0.0.1 | 23640 | 127.0.0.1 | 1999 | 2017-07-19 10:50:33 | 2017-07-19 10:54:38 | 0x1d71d98 |
(1 row)
pgbouncer=# show clients;
type | user | database | state | addr | port | local_addr | local_port | connect_time | request_time | ptr | link
------+--------+-----------+--------+-----------+-------+------------+------------+---------------------+---------------------+-----------+------
C | highgo | aaa | active | 127.0.0.1 | 23646 | 127.0.0.1 | 1999 | 2017-07-19 10:54:44 | 2017-07-19 10:54:44 | 0x1d71528 |
C | highgo | aaa | active | 127.0.0.1 | 23648 | 127.0.0.1 | 1999 | 2017-07-19 10:54:50 | 2017-07-19 10:54:50 | 0x1d71690 |
C | highgo | aaa | active | 127.0.0.1 | 23650 | 127.0.0.1 | 1999 | 2017-07-19 10:54:54 | 2017-07-19 10:54:54 | 0x1d717f8 |
C | highgo | aaa | active | 127.0.0.1 | 23652 | 127.0.0.1 | 1999 | 2017-07-19 10:54:58 | 2017-07-19 10:54:58 | 0x1d71960 |
C | highgo | aaa | active | 127.0.0.1 | 23654 | 127.0.0.1 | 1999 | 2017-07-19 10:55:02 | 2017-07-19 10:55:02 | 0x1d71ac8 |
C | highgo | aaa | active | 127.0.0.1 | 23658 | 127.0.0.1 | 1999 | 2017-07-19 10:55:09 | 2017-07-19 10:55:09 | 0x1d71c30 |
C | highgo | aaa | active | 127.0.0.1 | 23660 | 127.0.0.1 | 1999 | 2017-07-19 10:55:14 | 2017-07-19 10:55:14 | 0x1d713c0 |
C | highgo | pgbouncer | active | 127.0.0.1 | 23640 | 127.0.0.1 | 1999 | 2017-07-19 10:50:33 | 2017-07-19 10:55:18 | 0x1d71d98 |
(8 rows)
在DB端查询显示:
aaa=# select count(*) from pg_stat_activity ;
count
-------
6 <--此时仍然显示6
(1 row)
断开连接的pgbouncer=# \q后,效果如上。
****************************************************************************************************************
重启pgbouncer:
[highgo@sourcedb config]$ pgbouncer -R -d pgbouncer.ini
2017-07-19 11:00:04.784 12101 LOG File descriptor limit: 1024 (H:4096), max_client_conn: 100, max fds possible: 130
2017-07-19 11:00:04.787 12101 LOG takeover_init: launching connection
2017-07-19 11:00:04.787 12101 LOG S-0x1b2ba10: pgbouncer/pgbouncer@unix:1999 new connection to server
2017-07-19 11:00:04.788 12101 LOG S-0x1b2ba10: pgbouncer/pgbouncer@unix:1999 Login OK, sending SUSPEND
2017-07-19 11:00:04.800 12101 LOG SUSPEND finished, sending SHOW FDS
2017-07-19 11:00:04.800 12101 LOG got pooler socket: 127.0.0.1@1999
2017-07-19 11:00:04.800 12101 LOG got pooler socket: unix@1999
2017-07-19 11:00:04.800 12101 LOG SHOW FDS finished
2017-07-19 11:00:04.800 12101 LOG disko over, going background
[highgo@sourcedb config]$
[highgo@sourcedb config]$ psql -h 127.0.0.1 -p 1999 -U highgo -d pgbouncer
Password for user highgo:
psql (3.1.4, server 1.5.4/bouncer)
Type "help" for help.
pgbouncer=# show clients;
type | user | database | state | addr | port | local_addr | local_port | connect_time | request_time | ptr | link
------+--------+-----------+--------+-----------+-------+------------+------------+---------------------+---------------------+-----------+------
C | highgo | aaa | active | 127.0.0.1 | 23688 | 127.0.0.1 | 1999 | 2017-07-19 11:00:21 | 2017-07-19 11:00:49 | 0x1b49528 |
C | highgo | aaa | active | 127.0.0.1 | 23691 | 127.0.0.1 | 1999 | 2017-07-19 11:00:21 | 2017-07-19 11:01:13 | 0x1b497f8 |
C | highgo | aaa | active | 127.0.0.1 | 23690 | 127.0.0.1 | 1999 | 2017-07-19 11:00:21 | 2017-07-19 11:01:11 | 0x1b49690 |
C | highgo | aaa | active | 127.0.0.1 | 23692 | 127.0.0.1 | 1999 | 2017-07-19 11:00:21 | 2017-07-19 11:01:15 | 0x1b49960 |
C | highgo | aaa | active | 127.0.0.1 | 23693 | 127.0.0.1 | 1999 | 2017-07-19 11:00:21 | 2017-07-19 11:01:16 | 0x1b49ac8 |
C | highgo | aaa | active | 127.0.0.1 | 23695 | 127.0.0.1 | 1999 | 2017-07-19 11:00:32 | 2017-07-19 11:01:18 | 0x1b49c30 |
C | highgo | aaa | active | 127.0.0.1 | 23697 | 127.0.0.1 | 1999 | 2017-07-19 11:00:55 | 2017-07-19 11:01:00 | 0x1b49d98 |
C | highgo | pgbouncer | active | 127.0.0.1 | 23687 | 127.0.0.1 | 1999 | 2017-07-19 11:00:21 | 2017-07-19 11:02:17 | 0x1b493c0 |
(8 rows)
pgbouncer=#
DB端查询:
aaa=# select count(*) from pg_stat_activity ;
count
-------
1 <--此时显示的值正常
(1 row)
一.安装
1.下载pgbouncer的安装包
http://pgfoundry.org/frs/?group_id=1000258&release_id=1952,本次下载的安装包是pgbouncer-1.5.2.tar.gz
2.下载libevent包
http://monkey.org/~provos/libevent/,见pgbouncer源码包中的Readme
这玩意也是个好东西,在很多地方用到
3.安装libevent
$ cd libevent-2.0.19-stable
$ ./configure --prefix=/opt/pgbouncer/libevent
$ make
$ make install
加载libevent动态库
cd /etc/ld.so.conf.d/
vim libevent2.0.21.conf
/usr/local/libevent/lib
ldconfig
4.安装pgbouncer
$ cd pgbouncer-1.5.2
$ ./configure --prefix=/opt/pgbouncer/pgbouncer --with-libevent=/opt/pgbouncer/libevent/
$ make
$ make install
配置运行环境变量
vim ~/.bash_profile
PATH=/opt/pgbouncer/pgbouncer/bin:$PATH
export PATH
执行生效
source ~/.bash_profile
查看pgbouncer是否安装成功,可以通过查看config.log中最后的返回值exit来确认,0是成功1是失败.
二.配置
1.配置pgbouncer的cfg文件
[highgo@sourcedb config]$ pwd
/opt/pgbouncer/pgbouncer/config ----可以手动创建此目录和文件
$ more pgbouncer.ini ----修改该文件内容后,需要重启pgbouncer后才生效 ----重启pgbouncer命令(pgbouncer -R -d pgbouncer.ini)
[databases]
aaa = host=127.0.0.1 port=5866 dbname=highgo user=highgo password=highgo123
[pgbouncer]
listen_port = 1999
listen_addr = 127.0.0.1
auth_type = md5
auth_file = /opt/pgbouncer/pgbouncer/users.txt
logfile = /opt/pgbouncer/pgbouncer/pgbouncer.log
pidfile = /opt/pgbouncer/pgbouncer/pgbouncer.pid
admin_users = highgo
pool_mode = Transaction
2.配置用户密码文件users.txt
[highgo@sourcedb pgbouncer]$ pwd
/opt/pgbouncer/pgbouncer
$ cat users.txt
"highgo" "highgo123"
三.启动
1.启动命令
[postgres9.6@localhost config]$ pgbouncer -d pgbouncer.ini
2012-08-21 00:29:55.573 4247 LOG File descriptor limit: 1024 (H:1024), max_client_conn: 100, max fds possible: 130
2.查看日志
$ tail -f /opt/pgbouncer/pgbouncer/pgbouncer.log
[highgo@sourcedb pgbouncer]$ psql -h 127.0.0.1 -p 5866 -U highgo highgo
Password for user highgo:
psql (3.1.4)
Type "help" for help.
highgo=#
[highgo@sourcedb config]$ psql -h 127.0.0.1 -p 1999 -d aaa -U highgo
Password for user highgo:
psql (3.1.4)
Type "help" for help.
aaa=# select current_database();
current_database
------------------
highgo
(1 row)
aaa=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
--------------+--------------+----------+------------+------------+-------------------
benchmarksql | benchmarksql | UTF8 | zh_CN.utf8 | zh_CN.utf8 |
highgo | highgo | UTF8 | zh_CN.utf8 | zh_CN.utf8 |
template0 | highgo | UTF8 | zh_CN.utf8 | zh_CN.utf8 | =c/highgo +
| | | | | highgo=CTc/highgo
template1 | highgo | UTF8 | zh_CN.utf8 | zh_CN.utf8 | =c/highgo +
| | | | | highgo=CTc/highgo
(4 rows)
aaa=#
aaa=# \q
[highgo@sourcedb config]$ psql -h 127.0.0.1 -p 1999 -U highgo -d pgbouncer
Password for user highgo:
psql (3.1.4, server 1.5.4/bouncer)
Type "help" for help.
pgbouncer=# \l
ERROR: invalid command 'SELECT d.datname as "Name",
pg_catalog.pg_get_userbyid(d.datdba) as "Owner",
pg_catalog.pg_encoding_to_char(d.encoding) as "Encoding",
pg_catalog.array_to_string(d.datacl, '\n') AS "Access privileges"
FROM pg_catalog.pg_database d
ORDER BY 1;', use SHOW HELP;
pgbouncer=# show config
pgbouncer-# ;
key | value | changeable
---------------------------+----------------------------------------+------------
job_name | pgbouncer | no
conffile | pgbouncer.ini | yes
logfile | /opt/pgbouncer/pgbouncer/pgbouncer.log | yes
pidfile | /opt/pgbouncer/pgbouncer/pgbouncer.pid | no
listen_addr | * | no
listen_port | 1999 | no
listen_backlog | 128 | no
unix_socket_dir | /tmp | no
unix_socket_mode | 511 | no
unix_socket_group | | no
auth_type | md5 | yes
auth_file | /opt/pgbouncer/pgbouncer/users.txt | yes
pool_mode | transaction | yes
max_client_conn | 100 | yes
default_pool_size | 20 | yes
min_pool_size | 0 | yes
reserve_pool_size | 0 | yes
reserve_pool_timeout | 5 | yes
******************************************************************************************
连接pgbouncer数据库时提示不允许连接:
[postgres9.6@sourcedb config]$ psql -h 127.0.0.1 -p 6432 -U postgres9.6 pgbouncer
psql: ERROR: not allowed
[postgres9.6@sourcedb config]$ psql -h 127.0.0.1 -p 6432 -U test pgbouncer
psql: ERROR: not allowed
需要修改admin_users如下:
[postgres9.6@sourcedb config]$ pwd
/hgdata/pgbouncer-1.5.4/config
[postgres9.6@sourcedb config]$ cat pgbouncer.ini |grep admin_users
;admin_users = user2, someadmin, otheradmin
admin_users=postgres9.6
[postgres9.6@sourcedb config]$ psql -h 127.0.0.1 -p 6432 -U postgres9.6 pgbouncer
Password for user postgres9.6:
Null display is "NULL".
psql:/home/postgres9.6/.psqlrc:2: NOTICE: SET ignored
Pager is always used.
Timing is on.
psql (9.6.1, server 1.5.4/bouncer)
Type "help" for help.
postgres9.6@127.0.0.1:6432 pgbouncer# \q
[postgres9.6@sourcedb config]$ psql -h 127.0.0.1 -p 6432 -U test pgbouncer
psql: ERROR: not allowed
**********************************************************************************************
在连接池端看连接数:(transaction是基于事务模式的 )
pgbouncer=# show clients;
type | user | database | state | addr | port | local_addr | local_port | connect_time | request_time | ptr | link
------+--------+-----------+--------+-----------+-------+------------+------------+---------------------+---------------------+-----------+------
C | highgo | aaa | active | 127.0.0.1 | 23590 | 127.0.0.1 | 1999 | 2017-07-19 09:34:34 | 2017-07-19 09:34:34 | 0x1d71528 |
C | highgo | aaa | active | 127.0.0.1 | 23591 | 127.0.0.1 | 1999 | 2017-07-19 09:34:36 | 2017-07-19 09:34:36 | 0x1d71690 |
C | highgo | aaa | active | 127.0.0.1 | 23592 | 127.0.0.1 | 1999 | 2017-07-19 09:34:36 | 2017-07-19 09:34:36 | 0x1d717f8 |
C | highgo | aaa | active | 127.0.0.1 | 23593 | 127.0.0.1 | 1999 | 2017-07-19 09:34:37 | 2017-07-19 09:34:37 | 0x1d71960 |
C | highgo | aaa | active | 127.0.0.1 | 23594 | 127.0.0.1 | 1999 | 2017-07-19 09:34:38 | 2017-07-19 09:34:38 | 0x1d71ac8 |
C | highgo | aaa | active | 127.0.0.1 | 23595 | 127.0.0.1 | 1999 | 2017-07-19 09:34:39 | 2017-07-19 09:34:39 | 0x1d71c30 |
C | highgo | pgbouncer | active | 127.0.0.1 | 23599 | 127.0.0.1 | 1999 | 2017-07-19 09:34:55 | 2017-07-19 09:34:59 | 0x1d713c0 |
(7 rows)
pgbouncer=# show fds;
fd | task | user | database | addr | port | cancel | link | client_encoding | std_strings | datestyle | timezone
----+--------+--------+----------+-----------+-------+----------------------+------+-----------------+-------------+-----------+----------
9 | pooler | | | 127.0.0.1 | 1999 | 0 | 0 | | | |
10 | pooler | | | unix | 1999 | 0 | 0 | | | |
14 | client | highgo | aaa | 127.0.0.1 | 23590 | 9334293529859771476 | 0 | UTF8 | on | ISO, YMD | PRC
15 | client | highgo | aaa | 127.0.0.1 | 23591 | 13214640478787632242 | 0 | UTF8 | on | ISO, YMD | PRC
16 | client | highgo | aaa | 127.0.0.1 | 23592 | 12262729768783333509 | 0 | UTF8 | on | ISO, YMD | PRC
17 | client | highgo | aaa | 127.0.0.1 | 23593 | 16056577313122752872 | 0 | UTF8 | on | ISO, YMD | PRC
18 | client | highgo | aaa | 127.0.0.1 | 23594 | 10476624138286828314 | 0 | UTF8 | on | ISO, YMD | PRC
19 | client | highgo | aaa | 127.0.0.1 | 23595 | 8296638690593801308 | 0 | UTF8 | on | ISO, YMD | PRC
13 | server | highgo | aaa | 127.0.0.1 | 5866 | 46253389067440 | 0 | UTF8 | on | ISO, YMD | PRC
(9 rows)
在DB端查询:
aaa=# select count(*) from pg_stat_activity ;
count
-------
2
(1 row)
每产生或退出一个连接,后台日志都记录如下:
[highgo@sourcedb pgbouncer]$ tail -f pgbouncer.log
2017-07-19 10:22:39.051 10767 LOG C-0x1d71d98: aaa/highgo@127.0.0.1:23602 login attempt: db=aaa user=highgo
2017-07-19 10:22:39.051 10767 LOG C-0x1d71d98: aaa/highgo@127.0.0.1:23602 closing because: client unexpected eof (age=0)
2017-07-19 10:22:41.271 10767 LOG C-0x1d71d98: aaa/highgo@127.0.0.1:23603 login attempt: db=aaa user=highgo
2017-07-19 10:22:48.461 10767 LOG C-0x1d71d98: aaa/highgo@127.0.0.1:23603 closing because: client close request (age=7)
pgbouncer=# show help;
NOTICE: Console usage
DETAIL:
SHOW HELP|CONFIG|DATABASES|POOLS|CLIENTS|SERVERS|VERSION
SHOW STATS|FDS|SOCKETS|ACTIVE_SOCKETS|LISTS|MEM
SHOW DNS_HOSTS|DNS_ZONES
SET key = arg
RELOAD
PAUSE [<db>]
RESUME [<db>]
KILL <db>
SUSPEND
SHUTDOWN
SHOW
对于https://my.oschina.net/Kenyon/blog/73935中提到的“2.测试过程中,假如第一次访问被拒绝以后(不是密码不对),后续访问会直接拒绝,此举可以有效降低攻击性的访问。”,在实验中没有发现此问题:
[highgo@sourcedb pgbouncer]$ psql -h 127.0.0.1 -p 1999 -d aaa -U highgo
Password for user highgo:
psql: ERROR: Auth failed
[highgo@sourcedb pgbouncer]$ psql -h 127.0.0.1 -p 1999 -d aaa -U highgo
Password for user highgo:
psql: ERROR: Auth failed
[highgo@sourcedb pgbouncer]$ psql -h 127.0.0.1 -p 1999 -d aaa -U highgo
Password for user highgo:
psql: ERROR: Auth failed
[highgo@sourcedb pgbouncer]$ psql -h 127.0.0.1 -p 1999 -d aaa -U highgo
Password for user highgo:
psql: ERROR: Auth failed
[highgo@sourcedb pgbouncer]$ psql -h 127.0.0.1 -p 1999 -d aaa -U highgo
Password for user highgo:
psql (3.1.4)
Type "help" for help.
aaa=#
******************************************************************************************************
将pool_mode修改为session:(session是默认的模式,每开启一个进程,DB端也会开启一个新的进程 )
pgbouncer=# reload; -->此时需要reload即可生效,无需重启pgbouncer
pgbouncer=# show config;
key | value | changeable
---------------------------+----------------------------------------+------------
job_name | pgbouncer | no
conffile | pgbouncer.ini | yes
logfile | /opt/pgbouncer/pgbouncer/pgbouncer.log | yes
pidfile | /opt/pgbouncer/pgbouncer/pgbouncer.pid | no
listen_addr | * | no
listen_port | 1999 | no
listen_backlog | 128 | no
unix_socket_dir | /tmp | no
unix_socket_mode | 511 | no
unix_socket_group | | no
auth_type | md5 | yes
auth_file | /opt/pgbouncer/pgbouncer/users.txt | yes
pool_mode | session | yes
...
在连接池中查询:
pgbouncer=# show clients;
type | user | database | state | addr | port | local_addr | local_port | connect_time | request_time | ptr | link
------+--------+-----------+--------+-----------+-------+------------+------------+---------------------+---------------------+-----------+------
C | highgo | aaa | active | 127.0.0.1 | 23621 | 127.0.0.1 | 1999 | 2017-07-19 10:42:18 | 2017-07-19 10:42:18 | 0x1d713c0 |
C | highgo | aaa | active | 127.0.0.1 | 23623 | 127.0.0.1 | 1999 | 2017-07-19 10:42:31 | 2017-07-19 10:42:31 | 0x1d71c30 |
C | highgo | aaa | active | 127.0.0.1 | 23625 | 127.0.0.1 | 1999 | 2017-07-19 10:42:44 | 2017-07-19 10:42:44 | 0x1d71ac8 |
C | highgo | aaa | active | 127.0.0.1 | 23627 | 127.0.0.1 | 1999 | 2017-07-19 10:42:52 | 2017-07-19 10:42:52 | 0x1d71960 |
C | highgo | pgbouncer | active | 127.0.0.1 | 23619 | 127.0.0.1 | 1999 | 2017-07-19 10:40:50 | 2017-07-19 10:43:04 | 0x1d71d98 |
(5 rows)
pgbouncer=# show fds;
fd | task | user | database | addr | port | cancel | link | client_encoding | std_strings | datestyle | timezone
----+--------+--------+----------+-----------+-------+----------------------+------+-----------------+-------------+-----------+----------
9 | pooler | | | 127.0.0.1 | 1999 | 0 | 0 | | | |
10 | pooler | | | unix | 1999 | 0 | 0 | | | |
8 | client | highgo | aaa | 127.0.0.1 | 23621 | 9501733392119200235 | 0 | UTF8 | on | ISO, YMD | PRC
14 | client | highgo | aaa | 127.0.0.1 | 23623 | 6441374485719584038 | 0 | UTF8 | on | ISO, YMD | PRC
15 | client | highgo | aaa | 127.0.0.1 | 23625 | 3477675787395047246 | 0 | UTF8 | on | ISO, YMD | PRC
16 | client | highgo | aaa | 127.0.0.1 | 23627 | 16796806409626555809 | 0 | UTF8 | on | ISO, YMD | PRC
(6 rows)
在DB端查询:
aaa=# select count(*) from pg_stat_activity ;
count
-------
5
(1 row)
**************************************************************************************
此时当把pool_mode由session改为transaction,然后reload后,从连接池中查看连接在增加,但从DB端查看连接没有增加也没有减少:
pgbouncer=# show clients;
type | user | database | state | addr | port | local_addr | local_port | connect_time | request_time | ptr | link
------+--------+-----------+--------+-----------+-------+------------+------------+---------------------+---------------------+-----------+------
C | highgo | aaa | active | 127.0.0.1 | 23623 | 127.0.0.1 | 1999 | 2017-07-19 10:42:31 | 2017-07-19 10:50:41 | 0x1d71c30 |
C | highgo | aaa | active | 127.0.0.1 | 23625 | 127.0.0.1 | 1999 | 2017-07-19 10:42:44 | 2017-07-19 10:50:43 | 0x1d71ac8 |
C | highgo | aaa | active | 127.0.0.1 | 23627 | 127.0.0.1 | 1999 | 2017-07-19 10:42:52 | 2017-07-19 10:50:44 | 0x1d71960 |
C | highgo | aaa | active | 127.0.0.1 | 23633 | 127.0.0.1 | 1999 | 2017-07-19 10:47:21 | 2017-07-19 10:50:39 | 0x1d713c0 |
C | highgo | aaa | active | 127.0.0.1 | 23637 | 127.0.0.1 | 1999 | 2017-07-19 10:47:37 | 2017-07-19 10:50:45 | 0x1d717f8 |
C | highgo | aaa | active | 127.0.0.1 | 23642 | 127.0.0.1 | 1999 | 2017-07-19 10:50:58 | 2017-07-19 10:51:18 | 0x1d71690 |
C | highgo | aaa | active | 127.0.0.1 | 23644 | 127.0.0.1 | 1999 | 2017-07-19 10:52:38 | 2017-07-19 10:52:43 | 0x1d71528 |
C | highgo | pgbouncer | active | 127.0.0.1 | 23640 | 127.0.0.1 | 1999 | 2017-07-19 10:50:33 | 2017-07-19 10:52:49 | 0x1d71d98 |
(8 rows)
aaa=# select count(*) from pg_stat_activity ;
count
-------
6 <--此时仍然显示6
(1 row)
此时在DB端 断开部分连接,仅剩余1个连接的情况下:
pgbouncer=# show clients;
type | user | database | state | addr | port | local_addr | local_port | connect_time | request_time | ptr | link
------+--------+-----------+--------+-----------+-------+------------+------------+---------------------+---------------------+-----------+------
C | highgo | aaa | active | 127.0.0.1 | 23644 | 127.0.0.1 | 1999 | 2017-07-19 10:52:38 | 2017-07-19 10:53:46 | 0x1d71528 |
C | highgo | pgbouncer | active | 127.0.0.1 | 23640 | 127.0.0.1 | 1999 | 2017-07-19 10:50:33 | 2017-07-19 10:53:49 | 0x1d71d98 |
(2 rows)
DB端查询还是显示原来的数量:
aaa=# select count(*) from pg_stat_activity ;
count
-------
6 <--此时仍然显示6
(1 row)
此时断开所有连接重连:
pgbouncer=# show clients;
type | user | database | state | addr | port | local_addr | local_port | connect_time | request_time | ptr | link
------+--------+-----------+--------+-----------+-------+------------+------------+---------------------+---------------------+-----------+------
C | highgo | pgbouncer | active | 127.0.0.1 | 23640 | 127.0.0.1 | 1999 | 2017-07-19 10:50:33 | 2017-07-19 10:54:38 | 0x1d71d98 |
(1 row)
pgbouncer=# show clients;
type | user | database | state | addr | port | local_addr | local_port | connect_time | request_time | ptr | link
------+--------+-----------+--------+-----------+-------+------------+------------+---------------------+---------------------+-----------+------
C | highgo | aaa | active | 127.0.0.1 | 23646 | 127.0.0.1 | 1999 | 2017-07-19 10:54:44 | 2017-07-19 10:54:44 | 0x1d71528 |
C | highgo | aaa | active | 127.0.0.1 | 23648 | 127.0.0.1 | 1999 | 2017-07-19 10:54:50 | 2017-07-19 10:54:50 | 0x1d71690 |
C | highgo | aaa | active | 127.0.0.1 | 23650 | 127.0.0.1 | 1999 | 2017-07-19 10:54:54 | 2017-07-19 10:54:54 | 0x1d717f8 |
C | highgo | aaa | active | 127.0.0.1 | 23652 | 127.0.0.1 | 1999 | 2017-07-19 10:54:58 | 2017-07-19 10:54:58 | 0x1d71960 |
C | highgo | aaa | active | 127.0.0.1 | 23654 | 127.0.0.1 | 1999 | 2017-07-19 10:55:02 | 2017-07-19 10:55:02 | 0x1d71ac8 |
C | highgo | aaa | active | 127.0.0.1 | 23658 | 127.0.0.1 | 1999 | 2017-07-19 10:55:09 | 2017-07-19 10:55:09 | 0x1d71c30 |
C | highgo | aaa | active | 127.0.0.1 | 23660 | 127.0.0.1 | 1999 | 2017-07-19 10:55:14 | 2017-07-19 10:55:14 | 0x1d713c0 |
C | highgo | pgbouncer | active | 127.0.0.1 | 23640 | 127.0.0.1 | 1999 | 2017-07-19 10:50:33 | 2017-07-19 10:55:18 | 0x1d71d98 |
(8 rows)
在DB端查询显示:
aaa=# select count(*) from pg_stat_activity ;
count
-------
6 <--此时仍然显示6
(1 row)
断开连接的pgbouncer=# \q后,效果如上。
****************************************************************************************************************
重启pgbouncer:
[highgo@sourcedb config]$ pgbouncer -R -d pgbouncer.ini
2017-07-19 11:00:04.784 12101 LOG File descriptor limit: 1024 (H:4096), max_client_conn: 100, max fds possible: 130
2017-07-19 11:00:04.787 12101 LOG takeover_init: launching connection
2017-07-19 11:00:04.787 12101 LOG S-0x1b2ba10: pgbouncer/pgbouncer@unix:1999 new connection to server
2017-07-19 11:00:04.788 12101 LOG S-0x1b2ba10: pgbouncer/pgbouncer@unix:1999 Login OK, sending SUSPEND
2017-07-19 11:00:04.800 12101 LOG SUSPEND finished, sending SHOW FDS
2017-07-19 11:00:04.800 12101 LOG got pooler socket: 127.0.0.1@1999
2017-07-19 11:00:04.800 12101 LOG got pooler socket: unix@1999
2017-07-19 11:00:04.800 12101 LOG SHOW FDS finished
2017-07-19 11:00:04.800 12101 LOG disko over, going background
[highgo@sourcedb config]$
[highgo@sourcedb config]$ psql -h 127.0.0.1 -p 1999 -U highgo -d pgbouncer
Password for user highgo:
psql (3.1.4, server 1.5.4/bouncer)
Type "help" for help.
pgbouncer=# show clients;
type | user | database | state | addr | port | local_addr | local_port | connect_time | request_time | ptr | link
------+--------+-----------+--------+-----------+-------+------------+------------+---------------------+---------------------+-----------+------
C | highgo | aaa | active | 127.0.0.1 | 23688 | 127.0.0.1 | 1999 | 2017-07-19 11:00:21 | 2017-07-19 11:00:49 | 0x1b49528 |
C | highgo | aaa | active | 127.0.0.1 | 23691 | 127.0.0.1 | 1999 | 2017-07-19 11:00:21 | 2017-07-19 11:01:13 | 0x1b497f8 |
C | highgo | aaa | active | 127.0.0.1 | 23690 | 127.0.0.1 | 1999 | 2017-07-19 11:00:21 | 2017-07-19 11:01:11 | 0x1b49690 |
C | highgo | aaa | active | 127.0.0.1 | 23692 | 127.0.0.1 | 1999 | 2017-07-19 11:00:21 | 2017-07-19 11:01:15 | 0x1b49960 |
C | highgo | aaa | active | 127.0.0.1 | 23693 | 127.0.0.1 | 1999 | 2017-07-19 11:00:21 | 2017-07-19 11:01:16 | 0x1b49ac8 |
C | highgo | aaa | active | 127.0.0.1 | 23695 | 127.0.0.1 | 1999 | 2017-07-19 11:00:32 | 2017-07-19 11:01:18 | 0x1b49c30 |
C | highgo | aaa | active | 127.0.0.1 | 23697 | 127.0.0.1 | 1999 | 2017-07-19 11:00:55 | 2017-07-19 11:01:00 | 0x1b49d98 |
C | highgo | pgbouncer | active | 127.0.0.1 | 23687 | 127.0.0.1 | 1999 | 2017-07-19 11:00:21 | 2017-07-19 11:02:17 | 0x1b493c0 |
(8 rows)
pgbouncer=#
DB端查询:
aaa=# select count(*) from pg_stat_activity ;
count
-------
1 <--此时显示的值正常
(1 row)