常见问题处理
连接性能问题
- 开启了log_hostname,但是配置了错误的DNS导致的连接性能问题。
在连接上数据库,通过“show log_hostname”语句,检查数据库中是否开启了log_hostname参数。
如果开启了相关参数,那么数据库内核会通过DNS反查客户端所在机器的主机名。这时如果数据库CN所在的主机配置了不正确的/不可达的DNS服务器,那么会导致数据库建立连接过程较慢。
- 数据库内核执行初始化语句较慢导致的性能问题。
此种情况定位较难,可以尝试使用Linux的跟踪命令:strace。
strace gsql -U MyUserName -d postgres -h 127.0.0.1 -p 23508 -r -c '\q' Password for MyUserName:
此时便会在屏幕上打印出数据库的连接过程。比如较长时间停留在下面的操作上:
sendto(3, "Q\0\0\0\25SELECT VERSION()\0", 22, MSG_NOSIGNAL, NULL, 0) = 22 poll([{fd=3, events=POLLIN|POLLERR}], 1, -1) = 1 ([{fd=3, revents=POLLIN}])
此时便可以确定是数据库执行"SELECT VERSION()"语句较慢。
在连接上数据库后,便可以通过执行“explain performance select version()”语句来确定初始化语句执行较慢的原因。
另外还有一种场景不太常见:由于数据库CN所在机器的磁盘满或故障,此时所查询等受影响,无法进行用户认证,导致连接过程挂起,表现为假死。解决此问题联系客服人员清理数据库CN的数据盘空间便可。
- TCP连接创建较慢问题。
此问题可以参考上面的初始化语句较慢排查的做法,通过strace跟踪,如果长时间停留在:
connect(3, {sa_family=AF_FILE, path="/home/test/tmp/gaussdb_llt1/.s.PGSQL.61052"}, 110) = 0
或者
connect(3, {sa_family=AF_INET, sin_port=htons(61052), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
那么说明客户端与数据库端建立物理连接过慢,此时应当检查网络是否存在不稳定、网络吞吐量太大的问题。
创建连接故障
- gsql: could not connect to server: No route to host
- gsql: FATAL: Invalid username/password,login denied.
- The "libpq.so" loaded mismatch the version of gsql, please check it.
此问题是由于环境中使用的libpq.so的版本与gsql的版本不匹配导致的,请通过“ldd gsql”命令确认当前加载的libpq.so的版本,并通过修改LD_LIBRARY_PATH环境变量来加载正确的libpq.so。
请参照下面示例,修改LD_LIBRARY_PATH环境变量。其中${path_to_correct_libpq_dir}表示实际环境中正确libpq.so所在目录
export LD_LIBRARY_PATH=${path_to_correct_libpq_dir}:$LD_LIBRARY_PATH
- gsql: symbol lookup error: xxx/gsql: undefined symbol: libpqVersionString
此问题是由于环境中使用的libpq.so的版本与gsql的版本不匹配导致的(也有可能是环境中存在PostgreSQL的libpq.so),请通过“ldd gsql”命令确认当前加载的libpq.so的版本,并通过修改LD_LIBRARY_PATH环境变量来加载正确的libpq.so。
- gsql: connect to server failed: Connection timed out
Is the server running on host "xx.xxx.xxx.xxx" and accepting TCP/IP connections on port xxxx?
此问题是由于网络连接故障造成。请检查客户端与数据库服务器间的网络连接。如果发现从客户端无法PING到数据库服务器端,则说明网络连接出现故障。请联系网络管理人员排查解决。
ping -c 4 10.10.10.1 PING 10.10.10.1 (10.10.10.1) 56(84) bytes of data. From 10.10.10.1: icmp_seq=2 Destination Host Unreachable From 10.10.10.1 icmp_seq=2 Destination Host Unreachable From 10.10.10.1 icmp_seq=3 Destination Host Unreachable From 10.10.10.1 icmp_seq=4 Destination Host Unreachable --- 10.10.10.1 ping statistics --- 4 packets transmitted, 0 received, +4 errors, 100% packet loss, time 2999ms
- gsql: FATAL: permission denied for database "postgres"
DETAIL: User does not have CONNECT privilege.
此问题是由于用户不具备访问该数据库的权限,可以使用如下方法解决。
- 使用管理员用户连接数据库。
- 赋予该用户访问数据库的权限。
- gsql: FATAL: sorry, too many clients already,active/non-active: 197/3.
此问题是由于系统连接数量超过了最大连接数量。请联系数据库DBA进行会话连接数管理,释放无用会话。
关于查看用户会话连接数的方法如表1。
会话状态可以在视图PG_STAT_ACTIVITY中查看。无用会话可以使用函数pg_terminate_backend进行释放。
select datid,pid,state from pg_stat_activity;
datid | pid | state -------+-----------------+-------- 13205 | 139834762094352 | active 13205 | 139834759993104 | idle (2 rows)
其中pid的值即为该会话的线程ID。根据线程ID结束会话。
SELECT PG_TERMINATE_BACKEND(139834759993104);
显示类似如下信息,表示结束会话成功。
PG_TERMINATE_BACKEND ---------------------- t (1 row)
表1 查看会话连接数 描述
命令
查看指定用户的会话连接数上限。
执行如下命令查看连接到指定用户USER1的会话连接数上限。其中-1表示没有对用户user1设置连接数的限制。
SELECT ROLNAME,ROLCONNLIMIT FROM PG_ROLES WHERE ROLNAME='user1'; rolname | rolconnlimit ---------+-------------- user1 | -1 (1 row)
查看指定用户已使用的会话连接数。
执行如下命令查看指定用户USER1已使用的会话连接数。其中,1表示USER1已使用的会话连接数。
SELECT COUNT(*) FROM dv_sessions WHERE USERNAME='user1'; count ------- 1 (1 row)
查看指定数据库的会话连接数上限。
执行如下命令查看连接到指定数据库postgres的会话连接数上限。其中-1表示没有对数据库postgres设置连接数的限制。
SELECT DATNAME,DATCONNLIMIT FROM PG_DATABASE WHERE DATNAME='postgres'; datname | datconnlimit ----------+-------------- postgres | -1 (1 row)
查看指定数据库已使用的会话连接数。
执行如下命令查看指定数据库postgres上已使用的会话连接数。其中,1表示数据库postgres上已使用的会话连接数。
SELECT COUNT(*) FROM PG_STAT_ACTIVITY WHERE DATNAME='postgres'; count ------- 1 (1 row)
查看所有用户已使用会话连接数。
执行如下命令查看所有用户已使用的会话连接数。
SELECT COUNT(*) FROM dv_sessions; count ------- 10 (1 row)
- gsql: wait xxx.xxx.xxx.xxx:xxxx timeout expired
gsql在向数据库发起连接的时候,会有5分钟超时机制,如果在这个超时时间内,数据库未能正常的对客户端请求进行校验和身份认证,那么gsql会退出当前会话的连接过程,并报出如上错误。
一般来说,此问题是由于连接时使用的-h参数及-p参数指定的连接主机及端口有误(即错误信息中的xxx部分),导致通信故障;极少数情况是网络故障导致。要排除此问题,请检查数据库的主机名及端口是否正确。
其他故障
- 出现因“总线错误”(Bus error)导致的core dump或异常退出
一般情况下出现此种问题,是进程运行过程中加载的共享动态库(在Linux为.so文件)出现变化;或者进程二进制文件本身出现变化,导致操作系统加载机器的执行码或者加载依赖库的入口发生变化,操作系统出于保护目的将进程杀死,产生core dump文件。
解决此问题,重试便可。同时请尽可能避免在升级等运维操作过程中,在集群内部运行业务程序,避免升级时因替换文件产生此问题。
此故障的core dump文件的可能堆栈是dl_main及其子调用,它是操作系统用来初始化进程做共享动态库加载的。如果进程已经初始化,但是共享动态库还未加载完成,严格意义上来说,进程并未完全启动。