本期问答如下:
- 同步模式节点名称包含特殊字符如何设置
- pg_restore如何自定义恢复多个表对象
- 如何正确获取客户端主机名
- PostgreSQL是否支持数据动态脱敏
Q1. 同步模式因节点名称包含特殊字符未生效。
问题描述
搭建主从流复制时,节点名称有特殊字符“-”减号,主从节点对应的synchronous_standby_names和primary_conninfo即便使用双引号配置,同步模式也未生效?
问题解答
经过多次测试,节点名称如果有特殊字符,需要注意如下两点:
- 主库synchronous_standby_names里需要加一层双引号
- 备库application_name不需要加双引号
示例:
主库:synchronous_standby_names='"node-a"'
备库:primary_conninfo = 'host= port= user= application_name=node-a'
正常同步状态如下:

Q2. pg_restore备份恢复多个表对象是否可以使用多组-n与-t进行组合。
问题描述
使用pg_dump时可以使用多组-n与-t导出多个表对象,当然-n是可选的,可以直接在-t里面指定schema。
例如下面导出test1模式下所有以test开头的表以及test2模式下所有以test开头的表。
$ pg_dump -t test1.test* -t test2.test* -Fc -f tmp.dmp
但使用pg_restore进行恢复时如果指定恢复多个对象呢?
问题解答
使用pg_restore恢复需要使用-n与-t拆分指定schema和table精准恢复单个表对象,示例如下:
$ pg_restore -n test1 -t test2 tmp.dmp -v -c
否则只使用-t则会把多个schema下的表都恢复。
$ pg_restore -d test -t test1 tmp.dmp -v -c
pg_restore: connecting to database for restore
pg_restore: dropping TABLE test1
pg_restore: dropping TABLE test1
pg_restore: creating TABLE "test1.test1"
pg_restore: creating TABLE "test2.test1"
pg_restore: processing data for table "test1.test1"
pg_restore: processing data for table "test2.test1"
但恢复多个对象,不能使用多组-n与-t,此时可以使用备份清单进行对象重排。
$ pg_restore -l tmp.dmp > manifest.ini
然后我们可以参考格式进行删减调整,例如我们只想恢复test1模式下的test2表,以及test2模式下的test1表,对应关注下面两条恢复结构和和两条恢复数据的条目,生成新的清单列表my_manifest.ini。
GREP="TABLE test1 test2 | TABLE test2 test1 | TABLE DATA test1 test2 | TABLE DATA test2 test1"
$ pg_restore -l tmp.dmp | grep -E "$GREP" > my_manifest.ini
最后根据生成的清单my_manifest.ini进行恢复:
$ pg_restore -L my_manifest.ini -d test tmp.dmp -v -c
pg_restore: connecting to database for restore
pg_restore: dropping TABLE test1
pg_restore: dropping TABLE test2
pg_restore: creating TABLE "test1.test2"
pg_restore: creating TABLE "test2.test1"
pg_restore: processing data for table "test1.test2"
pg_restore: processing data for table "test2.test1"
Q3. SQL查询是否可以获取客户端连接的主机名。
问题描述
通过活动会话视图pg_stat_activity可以查看客户端连接信息,client_addr可以获取客户端IP地址,client_hostname可以获取客户端主机名,但client_hostname查询的值为什么空呢?
问题解答
pg_stat_activity视图能够显示client_hostname值需要满足如下两个条件
- 服务端数据库参数log_hostname设置为on
- 服务端操作系统hosts文件添加客户端IP的配置
示例如下:
1.服务端数据库确保log_hostname为on
postgres=# show log_hostname ;
log_hostname
--------------
on
(1 row)
2.数据库服务端/etc/hosts添加客户端主机名映射
192.168.20.200 www.miduo.andy
3.客户端测试
客户端使用psql测试
$ psql -h 192.168.20.100 -U postgres
postgres=# select client_addr,client_hostname from pg_stat_activity
where pid=pg_backend_pid() ;
client_addr | client_hostname
----------------+-----------------
192.168.20.200 | www.miduo.andy
(1 row)
客户端使用jdbc测试也类似
$ java -jar TestClientHostname.jar
application name:myJavaConnApp
client hostname:www.miduo.andy
client addr:192.168.20.200
client port:36850
注意该功能需要开启log_hostname参数来解析主机名,对性能有一定损耗,默认是关闭状态,并不推荐使用。
如果只是为了识别客户端,客户端可以设置客户端参数application name,比如jdbc驱动预设该值为PostgreSQL JDBC Driver,当我们部署客户端程序时可以修改设置为主机名。
connection.setClientInfo("ApplicationName", "www.miduo.andy");
Q4. PostgreSQL是否支持数据动态脱敏
Anonymizer插件支持使用security labels进行脱敏规则声明,它提供了8种脱敏策略,可以对不同的列使用不同的策略,同时支持静态脱敏、动态脱敏及抽样脱敏。详细介绍可以参考这篇文章:PostgreSQL数据脱敏插件介绍




