参考文档: PostgreSQL 9 Administration Cookbook (第二版)中文版
-- pg的关闭 (pt_ctl,具体可以查看帮助)
pg_ctl -D datadir -m fast stop
pg_ctl -D datadir stop -m immediate -- 相当O的shutdown abort
-- 重新加载配置文件
pg_ctl -D datadir reload
select pg_reload_conf()
-- 查看修改的部分参数
select name,setting,unit,(source='default') as is_default from pg_settings
where context='sighup'
and (name like '%delay' or name like '%timeout')
and setting != '0';
mydb=# select name,setting,unit,(source='default') as is_default from pg_settings
mydb-# where context='sighup'
mydb-# and (name like '%delay' or name like '%timeout')
mydb-# and setting != '0';
name | setting | unit | is_default
------------------------------+---------+------+------------
authentication_timeout | 60 | s | t
autovacuum_vacuum_cost_delay | 20 | ms | t
bgwriter_delay | 200 | ms | t
checkpoint_timeout | 300 | s | t
max_standby_archive_delay | 30000 | ms | t
max_standby_streaming_delay | 30000 | ms | t
wal_receiver_timeout | 60000 | ms | t
wal_sender_timeout | 60000 | ms | t
wal_writer_delay | 200 | ms | t
(9 rows)
mydb=#
-- 快速重启服务,先做一个checkpoint,将shared_buffer里面的脏数据刷新到数据文件中
psql -c "checkpoint";
pg_ctl -D datadir restart -m fast
-- 阻止新的连接
通过设置连接限制为0来限制指定的数据库的连接数为0 ,-1 解除限制
alter database foo_db connection limit 0;
通过设置连接数限制为0,来限制指定的用户的连接数为0
alter user foo connection limit 0;
或者设置基于主机的认证文件pg_hba.conf
限制用户的连接数为1 ,-1 解除限制
alter role fred connection limit 1;
mydb=# alter database mydb connection limit -1;
ALTER DATABASE
mydb=#
select rolconnlimit from pg_roles where rolname ='xxx'; -- 查看连接限制
select * from pg_stat_activity where usename ='postgres'; -- 查看连接数
-- 断开用户连接 ,使用pg提供的函数pg_terminate_backend()
select pg_terminate_backend(pid) from pg_stat_activity; -- 会断开当前的链接
postgres=# select pg_terminate_backend(pid) from pg_stat_activity;
FATAL: terminating connection due to administrator command
server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.
The connection to the server was lost. Attempting reset: Succeeded.
postgres=#
一个比较好的办法,是通过视图pg_stat_activity 找到pid,然后使用pg_terminate_backend(pid)终结会话
select * from pg_stat_activity -- 找到pid是21044
select pg_terminate_backend(21044); -- 该语句kill掉该会话
postgres=# select now();
now
-------------------------------
2021-01-12 14:29:17.877438+08
(1 row)
postgres=# select now();
FATAL: terminating connection due to administrator command
server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.
The connection to the server was lost. Attempting reset: Succeeded.
postgres=#
-- 或者这样
select count(pg_terminate_backend(pid)) from pg_stat_activity where usename not in
(select usename from pg_user where usesuper);
-- 使用多个模式
可以把一组表划分到他们自己的“命名空间”,也就是PG的模式(schema)。很多情况下,被认为类似目录。
create schema finance;
create schema sales;
mydb=# create table finance.t1(id integer,name varchar(10)); -- 创建一个表,在schema finance下
CREATE TABLE
mydb=#
mydb=# select current_schema; -- 查看当前的schema,是public
current_schema
----------------
public
(1 row)
mydb=#
-- 不写schema,查询不到t1,如果想让用户能够访问某组表,需要修改他的search_path
mydb=# select * from t1;
ERROR: relation "t1" does not exist
LINE 1: select * from t1;
^
mydb=#
mydb=# alter role postgres set search_path='finance';
ALTER ROLE
mydb=# grant all on schema finance to postgres;
GRANT
mydb=# select * from t1;
id | name
----+------
(0 rows)
mydb=#
mydb=# select * from t1;
id | name
----+------
(0 rows)
mydb=# select current_schema;
current_schema
----------------
finance
(1 row)
mydb=# show search_path
mydb-# ;
search_path
-------------
finance
(1 row)
mydb=#
mydb=# set search_path="$user", public;
SET
mydb=# show search_path;
search_path
-----------------
"$user", public
(1 row)
mydb=#
-- 单独给用户分配数据库
create user fred;
create database fred owner = fred ;
这个时候,切换到fred数据库还是可以的,提示使用postgres用户连接到了fred数据库
mydb=# \c fred
You are now connected to database "fred" as user "postgres".
fred=#
收回权限,尝试以postgres来连接数据库.或者,建立一个用户bob,使用bob访问fred数据库,没有权限。只能使用有权限的用户fred连接到数据库。
revoke connect on database fred from public;
grant connect on database fred to fred ;
fred=# revoke connect on database fred from public;
REVOKE
fred=# grant connect on database fred to fred ;
GRANT
fred=#
create user bob ;
alter user bob with password 'oracle';
psql -U bob fred
postgres=# alter user bob with password 'oracle';
ALTER ROLE
-bash-4.2$ psql -d fred -U bob
Password for user bob:
psql.bin: FATAL: permission denied for database "fred"
DETAIL: User does not have CONNECT privilege.
-bash-4.2$
-bash-4.2$ psql -U fred -d fred
Password for user fred:
psql.bin (10.15)
Type "help" for help.
fred=>
-- 配置连接池 pgbouncer
https://www.pgbouncer.org/install.html
http://rpm.pbone.net/info_idpl_68340409_distro_redhatel7_com_pgbouncer-1.9.0-3.rhel7.x86_64.rpm.html
--
-- pgbouncer的安装
yum install pgbouncer-1.9.0-3.rhel7.x86_64.rpm
Installed:
pgbouncer.x86_64 0:1.9.0-3.rhel7
Dependency Installed:
c-ares.x86_64 0:1.10.0-3.el7 postgresql-libs.x86_64 0:9.2.24-1.el7_5 python-psycopg2.x86_64 0:2.5.1-3.el7
Complete!
[root@asm12c tmp]# which pgbouncer
/usr/bin/pgbouncer
[root@asm12c tmp]#
-- 安装后的位置,在/etc/pgbouncer下 ,可以通过 rpm -ql | grep pgbouncer 来查询
[root@asm12c ~]# rpm -ql pgbouncer
/etc/logrotate.d/pgbouncer
/etc/pgbouncer
/etc/pgbouncer/mkauth.py
/etc/pgbouncer/mkauth.pyc
/etc/pgbouncer/mkauth.pyo
/etc/pgbouncer/pgbouncer.ini
/etc/sysconfig/pgbouncer
/run/pgbouncer
/usr/bin/pgbouncer
/usr/lib/systemd/system/pgbouncer.service
/usr/lib/tmpfiles.d/pgbouncer.conf
/usr/share/doc/pgbouncer
/usr/share/doc/pgbouncer/NEWS.rst
/usr/share/doc/pgbouncer/README.rst
/usr/share/doc/pgbouncer/pgbouncer.ini
/usr/share/doc/pgbouncer/userlist.txt
/usr/share/licenses/pgbouncer-1.9.0
/usr/share/licenses/pgbouncer-1.9.0/COPYRIGHT
/usr/share/man/man1/pgbouncer.1.gz
/usr/share/man/man5/pgbouncer.5.gz
[root@asm12c ~]#
-- 编辑pgbouncer.ini文件
[databases]
mydb= host=127.0.0.1 port=5432 user=postgres password=oracle
postgres= host=127.0.0.1 port=5432 user=postgres password=oracle
korean= host=127.0.0.1 port=5432 user=postgres password=oracle
fred= host=127.0.0.1 port=5432 user=fred password=oracle
[pgbouncer]
logfile = /postgres/10/data/log/pgbouncer_log/pgbouncer.log
pidfile = /tmp/pgbouncer.pid
listen_addr = *
listen_port = 6432
auth_type = trust -- 如果是md5,需要通过pg_shadow 查询到用户的md5值,或者使用MD5函数计算出加密后的值
auth_file = /etc/pgbouncer/userlist.txt
admin_users = postgres,fred
pool_mode = session
server_reset_query = DISCARD ALL
ignore_startup_parameters = extra_float_digits
max_client_conn = 1000
default_pool_size = 200
-- 计算MD5值
\o users.txt
\t
SELECT '"'||rolname||'" "'||rolpassword||'"'
FROM pg_authid;
\q
postgres=# \o users.txt
postgres=# \t
Tuples only is on.
postgres=# SELECT '"'||rolname||'" "'||rolpassword||'"'
postgres-# FROM pg_authid;
postgres=# \q
-bash-4.2$ more users.txt
?column? |
---------+-------------------------------------------------
?column? |
---------+-------------------------------------------------
?column? |
---------+-------------------------------------------------
?column? |
---------+-------------------------------------------------
?column? |
---------+-------------------------------------------------
?column? | "postgres" "md57e1a83ffb47df2396c5eafd05bac4ade"
---------+-------------------------------------------------
?column? | "bob" "md535bb865af345b47dcbebab163fe54390"
---------+-------------------------------------------------
?column? | "fred" "md569361356a5bde6d88405a0f45d28bb30"
-bash-4.2$
-- 编辑userlist.txt, 因为上面认证使用的是trust,所以文件中写明文密码了。(生产不建议)
[root@asm12c ~]# more /etc/pgbouncer/userlist.txt
"postgres" "oracle"
"fred" "oracle"
[root@asm12c ~]#
-- 启动pgbouncer
su - postgres
pgbouncer -d /etc/pgbouncer/pgbouncer.ini
[root@asm12c ~]# netstat -anlpt | grep 6432
tcp 0 0 0.0.0.0:6432 0.0.0.0:* LISTEN 12514/pgbouncer
tcp 0 0 127.0.0.1:9637 127.0.0.1:6432 ESTABLISHED 12759/psql.bin
tcp 0 0 127.0.0.1:6432 127.0.0.1:9637 ESTABLISHED 12514/pgbouncer
tcp6 0 0 :::6432 :::* LISTEN 12514/pgbouncer
[root@asm12c ~]#
-- 登录到pgbouncer
psql -Upostgres -dpgbouncer -p6432 -h127.0.0.1
pgbouncer=# \x
Expanded display is on.
pgbouncer=# show clients;
-[ RECORD 1 ]+--------------------
type | C
user | postgres
database | pgbouncer
state | active
addr | 127.0.0.1
port | 9637
local_addr | 127.0.0.1
local_port | 6432
connect_time | 2021-01-13 15:32:45
request_time | 2021-01-13 15:48:53
wait | 964
wait_us | 397897
close_needed | 0
ptr | 0x18d7730
link |
remote_pid | 0
tls |
pgbouncer=#
-- 查看连接池
pgbouncer=# show pools;
database | user | cl_active | cl_waiting | sv_active | sv_idle | sv_used | sv_tested | sv_login | maxwait | maxwait_us | pool_mode
-----------+-----------+-----------+------------+-----------+---------+---------+-----------+----------+---------+------------+-----------
korean | postgres | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | session
mydb | postgres | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | session
pgbouncer | pgbouncer | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | statement
postgres | postgres | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | session
(4 rows)
pgbouncer=#
-- 列出数据库,报错,难道pgbouncer版本和postgres版本不兼容?
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=#
-- 重新加载pgbouncer的配置信息
pgbouncer=# reload
pgbouncer-# ;
RELOAD
pgbouncer=#
-- 重启pgbouncer
su - postgres
pgbouncer -R /etc/pgbouncer/pgbouncer.ini
-- 关闭pgbouncer
cat /tmp/pgbouncer.pid | xargs kill -9 -- 这个是网上看到的
psql -p 6432 pgbouncer -c "SHUTDOWN"
-- 查看帮助
pgbouncer=# show help;
NOTICE: Console usage
DETAIL:
SHOW HELP|CONFIG|DATABASES|POOLS|CLIENTS|SERVERS|VERSION
SHOW FDS|SOCKETS|ACTIVE_SOCKETS|LISTS|MEM
SHOW DNS_HOSTS|DNS_ZONES
SHOW STATS|STATS_TOTALS|STATS_AVERAGES
SET key = arg
RELOAD
PAUSE [<db>]
RESUME [<db>]
DISABLE <db>
ENABLE <db>
RECONNECT [<db>]
KILL <db>
SUSPEND
SHUTDOWN
SHOW
pgbouncer=#
-- pgadmin的连接,可以连接。
END