本文较长,如果要看结果可以直接跳至文章末尾的“实验总结”。
今天这一篇我们来看看在磐维数据库里,应该如何来安全的查杀会话?与PostgreSQL有何不同,有哪些注意事项?
背景知识:
PostgreSQL数据库是多进程架构数据库,启动数据库后除了会生成数据库主进程外,还会生成例如checkpointer、walwriter等数据库必须的子进程。
磐维数据库是单进程多线程架构的数据库,启动数据库后只会生成数据库主进程,其他数据库必须存在的服务均以线程的形式存在。
实验环境:
操作系统:BCLinux7.8
数据库:磐维CMDB数据库1.0环境
磐维数据库服务端(一主两备)IP:
xx.xx.xx.71(主)
xx.xx.xx.72(备)
xx.xx.xx.73(备)
远程客户端IP:
xx.xx.xx.10
PG数据库服务IP:
xx.xx.xx.50
一、准备好实验环境
分别使用本地客户端omm用户(DBA用户)和cmuser用户、远程客户端cmuser2用户连接磐维数据库
本地会话1:
[omm@node1 ~]$ gsql -d postgres -U omm -p17700 -r
gsql ((CMDB(openGauss) 1.0.1 build 58ef6fad) compiled at 2022-09-06 16:04:55 commit 0 last mr )
Non-SSL connection (SSL connection is recommended when requiring high-security)
Type "help" for help.
CMDB=#
本地会话2:
[omm@node1 ~]$ gsql -d postgres -U cmuser -p17700 -r
Password for user cmuser:
gsql ((CMDB(openGauss) 1.0.1 build 58ef6fad) compiled at 2022-09-06 16:04:55 commit 0 last mr )
Non-SSL connection (SSL connection is recommended when requiring high-security)
Type "help" for help.
CMDB=>
远程会话3:
[root@node1 lib]# gsql -d postgres -hxx.xx.xx.71 -U cmuser2 -p17700
Password for user cmuser2:
gsql ((CMDB(openGauss) 1.0.1 build 58ef6fad) compiled at 2022-09-06 16:04:55 commit 0 last mr )
SSL connection (cipher: ECDHE-RSA-AES128-GCM-SHA256, bits: 128)
Type "help" for help.
CMDB=>
查看操作系统进程
[omm@node1 ~]$ ps -ef|grep omm|egrep -v "bash|su|grep"
omm 1585 1 0 09:27 ? 00:00:17 /opt/panweidb/app/bin/om_monitor -L /opt/panweidb/log/omm/cm/om_monitor
omm 1586 1585 3 09:27 ? 00:01:52 /opt/panweidb/app/bin/cm_agent
omm 1599 1 25 09:27 ? 00:12:47 /opt/panweidb/app/bin/cm_server
omm 1608 1 7 09:27 ? 00:03:30 /opt/panweidb/app/bin/gaussdb -D /opt/panweidb/cmdata/data -M pending
omm 1615 1 0 09:27 ? 00:00:01 gaussdb fenced UDF master process
omm 1669 1 0 09:27 ? 00:00:00 ssh-agent -a /home/omm/gaussdb_tmp/gauss_socket_tmp
omm 19086 18851 0 10:14 pts/1 00:00:00 gsql -d postgres -U omm -p17700 -r
omm 19311 18801 0 10:14 pts/2 00:00:00 gsql -d postgres -U cmuser -p17700 -r
omm 20003 5975 0 10:16 pts/0 00:00:00 ps -ef
在PostgreSQL数据库里本地通过psql连接数据库后会在操作系统生成两个进程,一个是psql的客户端进程,显示为psql -U $user -d $dbname -h $ip -p $port;另一个是连接进程,显示为postgres:$user $dbname $ip idle/active。
在磐维数据库的环境里可以看到本地通过gsql连接数据库后在操作系统会生成一个gsql的客户端进程,显示为gsql -d $dbname -U $user -h $ip -p $port,没有为本地会话和远程会话生成对应的连接进程。磐维数据库是单进程多线程结构,数据库连接服务是以线程方式存在的,磐维数据库连接线程可以通过查看主服务进程包含的线程,命令为ps -T -p 主服务进程号。
查看连接线程
[omm@node1 ~]$ ps -T -p 1608
PID SPID TTY TIME CMD
1608 2008 ? 00:00:00 undorecycler
1608 2020 ? 00:00:00 WalSender
1608 23991 ? 00:00:00 worker
1608 24091 ? 00:00:00 worker
1608 24112 ? 00:00:00 worker
每个连接线程对应一个worker,我们可以通过新增一个会话来验证下。
本地会话4:
[omm@node1 ~]$ gsql -d postgres -U cmuser -p17700 -r
Password for user cmuser:
gsql ((CMDB(openGauss) 1.0.1 build 58ef6fad) compiled at 2022-09-06 16:04:55 commit 0 last mr )
Non-SSL connection (SSL connection is recommended when requiring high-security)
Type "help" for help.
CMDB=>
查看新增会话后主进程的线程服务
[omm@node1 ~]$ ps -T -p 1608
PID SPID TTY TIME CMD
1608 2008 ? 00:00:00 undorecycler
1608 2020 ? 00:00:00 WalSender
1608 23991 ? 00:00:00 worker
1608 24091 ? 00:00:00 worker
1608 24112 ? 00:00:00 worker
1608 24929 ? 00:00:00 worker
线程服务中增加了一个worker,因此磐维数据库中的连接服务表现为主进程中的worker线程。
在磐维单进程多线程结构背景下,我们来通过实验展示查杀的效果。
通常杀会话的操作分为数据库内进程查杀和操作系统进程查杀。
二、操作系统线程查杀实验
由于每个连接线程名字都是worker,为了区分不同连接进程对应的worker,经观察,磐维主进程中的worker线程是以连接的前后顺序产生的,查杀实验时要记好连接会话的先后顺序和对应的worker。
1、场景一:kill -9 和kill 查杀连接线程
首先查杀本地客户端cmuser用户的连接线程,
[omm@node1 ~]$ kill -9 24091
[omm@node1 ~]$ ps -T -p 1608
PID SPID TTY TIME CMD
[omm@node1 ~]$ ps -ef|grep omm|egrep -v "bash|su|grep"
omm 1585 1 0 09:27 ? 00:00:23 /opt/panweidb/app/bin/om_monitor -L /opt/panweidb/log/omm/cm/om_monitor
omm 1586 1585 3 09:27 ? 00:02:27 /opt/panweidb/app/bin/cm_agent
omm 1599 1 22 09:27 ? 00:16:35 /opt/panweidb/app/bin/cm_server
omm 1615 1 0 09:27 ? 00:00:01 gaussdb fenced UDF master process
omm 1669 1 0 09:27 ? 00:00:00 ssh-agent -a /home/omm/gaussdb_tmp/gauss_socket_tmp
omm 28790 18851 0 10:39 pts/1 00:00:00 gsql -d postgres -U omm -p17700 -r
omm 28802 18801 0 10:39 pts/2 00:00:00 gsql -d postgres -U cmuser -p17700 -r
omm 29067 1 27 10:40 ? 00:00:01 /opt/panweidb/app/bin/gaussdb -D /opt/panweidb/cmdata/data -M pending
omm 29156 5975 0 10:40 pts/0 00:00:00 ps -ef
实验发现kill -9 杀掉cmuser的连接线程后,会导致主进程服务下的所有线程消失,包括但不限于worker、WalSender等线程,主服务的进程号也被更改,这一点非常严重。
此时cmuser用户连接线程对应的客户端进程内执行sql命令会报错“could not send data to server: Broken pipe”,客户端进程内再次执行sql也会失败,提示“You are currently not connected to a database.”。
此时omm用户连接线程对应的客户端进程内执行sql命令会报错“could not send data to server: Broken pipe”,同时操作系统内会重新出现一个新的连接线程。客户端进程内再次执行sql命令成功。
此时远程会话cmuser2用户线程对应的客户端进程内执行sql命令提示和cmuser一样,再次执行sql提示一样。
本地会话cmuser:
[omm@node1 ~]$ gsql -d postgres -U cmuser -p17700 -r
Password for user cmuser:
gsql ((CMDB(openGauss) 1.0.1 build 58ef6fad) compiled at 2022-09-06 16:04:55 commit 0 last mr )
Non-SSL connection (SSL connection is recommended when requiring high-security)
Type "help" for help.
CMDB=> select user;
could not send data to server: Broken pipe
The connection to the server was lost. Attempting reset: Failed.
!> select user;
You are currently not connected to a database.
!>
本地会话omm用户:
[omm@node1 ~]$ gsql -d postgres -U omm -p17700 -r
gsql ((CMDB(openGauss) 1.0.1 build 58ef6fad) compiled at 2022-09-06 16:04:55 commit 0 last mr )
Non-SSL connection (SSL connection is recommended when requiring high-security)
Type "help" for help.
CMDB=# select user;
could not send data to server: Broken pipe
The connection to the server was lost. Attempting reset: Succeeded.
CMDB=# select user;
current_user
--------------
omm
(1 row)
远程会话cmuser2用户:
[root@node1 lib]# gsql -d postgres -hxx.xx.xx.71 -U cmuser2 -p17700
Password for user cmuser2:
gsql ((CMDB(openGauss) 1.0.1 build 58ef6fad) compiled at 2022-09-06 16:04:55 commit 0 last mr )
SSL connection (cipher: ECDHE-RSA-AES128-GCM-SHA256, bits: 128)
Type "help" for help.
CMDB=> select user;
SSL SYSCALL error: EOF detected, remote datanode (null), error: Success
The connection to the server was lost. Attempting reset: Failed.
!> select user;
You are currently not connected to a database.
!>
[omm@node1 ~]$ ps -T -p 29067
PID SPID TTY TIME CMD
29067 29077 ? 00:00:00 jemalloc_bg_thd
29067 29144 ? 00:00:00 heartbeat
29067 31067 ? 00:00:00 worker
线程服务中仅保留了超级帐号omm的连接线程服务。
实验后在cm_agent日志中(/opt/panweidb/log/omm/cm/cm_agent)发下报错信息:
在kill会话后,报错提示因为管理员命令导致会话断连
2022-12-28 11:49:14.271 tid=1587 ERROR: datanode(0) check set command time out return FAIL! errmsg is FATAL: [FATAL] terminating connection due to administrator command
FATAL: [FATAL] terminating connection due to administrator command
2022-12-28 11:49:14.271 tid=1587 ERROR: DatanodeStatusCheck failed, ret=-1
2022-12-28 11:49:15.280 tid=1587 LOG: process (gaussdb) is not running, path is /opt/panweidb/cmdata/data, haveFound is 0
2022-12-28 11:49:15.281 tid=1587 ERROR: [get_connection: 1296]: fail to read pid file (/opt/panweidb/cmdata/data/postmaster.pid).
2022-12-28 11:49:15.281 tid=1587 ERROR: failed to connect to datanode:/opt/panweidb/cmdata/data
2022-12-28 11:49:15.281 tid=1587 ERROR: DatanodeStatusCheck failed, ret=-1
2022-12-28 11:49:15.287 tid=1587 LOG: process (gaussdb) is not running, path is /opt/panweidb/cmdata/data, haveFound is 0
在kill会话后重新执行sql时,报错信息如下:
2022-12-28 11:49:17.771 tid=1587 ERROR: failed to connect to datanode:/opt/panweidb/cmdata/data
2022-12-28 11:49:17.771 tid=1587 ERROR: connection return errmsg : could not receive data from server, error: Connection reset by peer, remote datanode: (null)
实验继续使用kill -9 查杀omm用户和远程客户端cmuser2用户的连接线程,结果也是一样的,也会导致所有连接线程一起消失,客户端内执行SQL报错。
另外,实验使用kill 查杀会话与kill -9结果相同。
此项实验的结果显示:
1)磐维数据库中客户端的连接服务以线程方式存在,对应的线程名称统一为worker。
2)磐维数据库在操作系统层面杀会话需要先查到主服务进程,然后杀进程下对应的子连接线程。
3)kill -9 和kill 查杀任意用户的连接线程,会导致所有用户连接线程一并被查杀,并且会导致主服务进程重启。
4)客户端进程虽然不会被关联查杀,但是客户端进程内执行sql会报错,然后除超级用户omm的会话可以自动恢复创建连接线程并恢复客户端进程内sql执行,其他用户连接线程全部消失并在客户端再次执行sql时提示“You are currently not connected to a database.”,需要重新连接后才能正常执行sql。
2、场景二:kill -9查杀客户端进程
重新使用本地客户端omm用户和cmuser用户、远程客户端cmuser2连接数据库,重置环境。
[omm@node1 ~]$ ps -ef|grep omm|egrep -v "bash|su|grep"
omm 49010 1 11 11:49 ? 00:02:30 /opt/panweidb/app/bin/gaussdb -D /opt/panweidb/cmdata/data -M pending
omm 57299 46566 0 12:11 pts/4 00:00:00 gsql -d postgres -Uomm -p17700 -r
omm 57326 46608 0 12:11 pts/5 00:00:00 gsql -d postgres -U cmuser -p17700 -r
磐维数据库中客户端是以进程方式存在的,可以直接kill -9 进程号操作。
使用kill -9命令查杀cmuser用户的客户端进程
[omm@node1 ~]$ kill -9 57326
[omm@node1 ~]$ ps -ef|grep omm|egrep -v "bash|su|grep"
omm 49010 1 11 11:49 ? 00:02:38 /opt/panweidb/app/bin/gaussdb -D /opt/panweidb/cmdata/data -M pending
omm 57299 46566 0 12:11 pts/4 00:00:00 gsql -d postgres -Uomm -p17700 -r
[omm@node1 ~]$ ps -T -p 49010
49010 49096 ? 00:00:27 WALreceiver
49010 49097 ? 00:00:00 heartbeat
49010 57300 ? 00:00:00 worker
49010 57390 ? 00:00:00 worker
实验发现kill -9杀掉cmuser的客户端进程后,会导致cmuser的连接线程worker和客户端进程一起消失。其他用户的连接线程和客户端进程不受影响。
此时cmuser客户端会话会直接提示Killed并退出。
[omm@node1 ~]$ gsql -d postgres -U cmuser -p17700 -r
Password for user cmuser:
gsql ((CMDB(openGauss) 1.0.1 build 58ef6fad) compiled at 2022-09-06 16:04:55 commit 0 last mr )
Non-SSL connection (SSL connection is recommended when requiring high-security)
Type "help" for help.
CMDB=> Killed
[omm@node1 ~]$
实验继续使用kill -9命令查杀omm用户的客户端进程,结果也是一样的,会导致omm用户的连接线程和客户端进程一起消失,同时omm用户的客户端会话提示Killed并退出。
实验继续使用kill -9命令查杀远程客户端cmuser2用户的客户端进程,结果一样。
此项实验的结果显示:
1)使用kill -9 命令查杀任意用户的客户端进程,会导致该用户的连接线程和客户端进程一起消失,同时该用户的客户端会话提示Killed并退出。
2)其他用户的连接线程和客户端进程不受影响。
3、场景三:kill 查杀客户端进程
重新使用本地客户端omm用户和cmuser用户、远程客户端cmuser2连接数据库,重置环境
[omm@node1 ~]$ ps -ef|grep omm|egrep -v "bash|su|grep"
omm 58750 1 11 12:15 ? 00:00:51 /opt/panweidb/app/bin/gaussdb -D /opt/panweidb/cmdata/data -M pending
omm 61533 46566 0 12:22 pts/4 00:00:00 gsql -d postgres -Uomm -p17700 -r
omm 61545 46608 0 12:22 pts/5 00:00:00 gsql -d postgres -U cmuser -p17700 -r
使用kill命令查杀cmuser用户的客户端进程
[omm@node1 ~]$ kill 61545
[omm@node1 ~]$ ps -ef|grep omm|egrep -v "bash|su|grep"
omm 58750 1 11 12:15 ? 00:00:54 /opt/panweidb/app/bin/gaussdb -D /opt/panweidb/cmdata/data -M pending
omm 61533 46566 0 12:22 pts/4 00:00:00 gsql -d postgres -Uomm -p17700 -r
omm 61852 48745 0 12:23 pts/0 00:00:00 ps -ef
omm@node1 ~]$ ps -T -p 58750
PID SPID TTY TIME CMD
58750 58831 ? 00:00:09 WALreceiver
58750 61534 ? 00:00:00 worker
58750 61695 ? 00:00:00 worker
实验发现kill命令和kill -9命令效果一样,在杀掉cmuser的客户端进程后,会导致cmuser的连接进程和客户端进程全部消失。其他用户的连接线程和客户端进程不受影响。
但是此时cmuser客户端会话的提示略有不同,会提示Terminated而不是Killed,并退出。
[omm@node1 ~]$ gsql -d postgres -U cmuser -p17700 -r
Password for user cmuser:
gsql ((CMDB(openGauss) 1.0.1 build 58ef6fad) compiled at 2022-09-06 16:04:55 commit 0 last mr )
Non-SSL connection (SSL connection is recommended when requiring high-security)
Type "help" for help.
CMDB=> Terminated
[omm@node1 ~]$
实验继续使用kill命令查杀omm用户的客户端进程,结果也是一样的,会导致omm用户的连接线程和客户端进程一起消失,同时omm用户的客户端会话提示Terminated并退出。
实验继续使用kill命令查杀远程客户端cmuser2用户的客户端进程,结果也是一样的,会导致cmuser2用户的连接线程和客户端进程一起消失,同时cmuser2用户的客户端会话提示Terminated并退出。
[root@node1 bin]# gsql -d postgres -hxx.xx.xx.71 -U cmuser2 -p17700
Password for user cmuser2:
gsql ((CMDB(openGauss) 1.0.1 build 58ef6fad) compiled at 2022-09-06 16:04:55 commit 0 last mr )
SSL connection (cipher: ECDHE-RSA-AES128-GCM-SHA256, bits: 128)
Type "help" for help.
CMDB=> Terminated
此项实验的结果显示:
1)kill命令查杀任意用户的客户端进程,会导致该用户的连接进程和客户端进程一起消失,同时该用户的客户端进程会提示Terminated并退出。
2)其他用户的连接进程和客户端进程不受影响。
三、数据库内进程查杀实验
在数据库内可以使用pg_terminate_backend函数来进行会话查杀
1、场景一:pg_terminate_backend函数查杀用户连接线程
重新使用本地客户端omm用户和cmuser用户、远程客户端cmuser2连接数据库,重置环境,增加一个omm用户会话,用来执行查杀命令。
[omm@node1 ~]$ ps -ef|grep omm|egrep -v "bash|su|grep|check|writer|launcher|stats"
omm 58750 1 11 12:15 ? 00:01:44 /opt/panweidb/app/bin/gaussdb -D /opt/panweidb/cmdata/data -M pending
omm 64292 48745 0 12:30 pts/0 00:00:00 gsql -d postgres -Uomm -p17700 -r
omm 64310 46566 0 12:30 pts/4 00:00:00 gsql -d postgres -Uomm -p17700 -r
omm 64341 46608 0 12:30 pts/5 00:00:00 gsql -d postgres -U cmuser -p17700 -r
[omm@node1 ~]$ ps -T -p 58750
PID SPID TTY TIME CMD
58750 58831 ? 00:00:17 WALreceiver
58750 64293 ? 00:00:00 worker
58750 64311 ? 00:00:00 worker
58750 64357 ? 00:00:00 worker
58750 64389 ? 00:00:00 worker
64292是用来执行查杀命令的客户端进程,64293是用来执行查杀命令的连接线程。我们来执行查杀cmuser用户的连接线程64357
WARNING: PID 64357 is not a gaussdb server thread
pg_terminate_backend
----------------------
f
(1 row)
CMDB=#
[omm@node1 ~]$ ps -T -p 58750
PID SPID TTY TIME CMD
.....
58750 58830 ? 00:00:00 WALrecwriter
58750 58831 ? 00:00:17 WALreceiver
58750 64293 ? 00:00:00 worker
58750 64311 ? 00:00:00 worker
58750 64357 ? 00:00:00 worker
58750 64389 ? 00:00:00 worker
[omm@node1 ~]$ ps -ef|grep omm|egrep -v "bash|su|grep|check|writer|launcher|stats"
omm 58750 1 11 12:15 ? 00:02:09 /opt/panweidb/app/bin/gaussdb -D /opt/panweidb/cmdata/data -M pending
omm 64292 48745 0 12:30 pts/0 00:00:00 gsql -d postgres -Uomm -p17700 -r
omm 64310 46566 0 12:30 pts/4 00:00:00 gsql -d postgres -Uomm -p17700 -r
omm 64341 46608 0 12:30 pts/5 00:00:00 gsql -d postgres -U cmuser -p17700 -r
实验发现pg_terminate_backend函数并不能通过操作系统层面的用户连接线程的线程号来杀掉cmuser的连接线程,客户端也不受影响。这是怎么回事?为什么和PG不一样呢?
在PG中,用户的连接进程号和数据库内pg_stat_activity中查到的pid一致,可以通过操作系统层面查到的连接进程号进行查杀,但在磐维中操作系统层面的连接线程跟数据库中查到的PID不一致,所以上述使用pg_terminate_backend函数杀操作系统层面查询到的连接线程号会失败。
PG环境验证如下:
[postgre@localhost ~]$ psql -d postgres
psql (14.5)
Type "help" for help.
postgres=# select datid,pid,state,query from pg_stat_activity;
datid | pid | state | query
-------+------+--------+-----------------------------------------------------
| 2200 | |
14486 | 4719 | active | select datid,pid,state,query from pg_stat_activity;
| 2196 | |
(6 rows)
[postgre@localhost ~]$ ps -ef|grep postgres|egrep -v "bash|su|grep"
postgre 2193 1 0 18:15 ? 00:00:00 /usr/local/pgsql/bin/postgres -D /opt/database/postgre/data/pgdata
postgre 4718 4671 0 20:44 pts/1 00:00:00 psql -d postgres
postgre 4719 2193 0 20:44 ? 00:00:00 postgres: postgre postgres [local] idle
如上操作,可见在PG中数据库内的PID和操作系统的连接进程的进程号一致,都是4719,因此在PG数据库中可以通过pg_terminate_backend函数查杀操作系统层查到的连接进程号。
继续进行pg_terminate_backend杀会话实验
在执行查杀的会话窗口中,查询pg_stat_activity获取连接会话的PID
CMDB=# select datid,pid,state,query from pg_stat_activity;
datid | pid | state | query
-------+----------------+--------+-----------------------------------------------------
15484 | 47440526968576 | idle | SELECT gs_password_notifytime()
15484 | 47440839640832 | idle | select user;
15484 | 47440799729408 | active | select datid,pid,state,query from pg_stat_activity;
(5 rows)
使用pg_terminate_backend杀会话
CMDB=# select * from pg_terminate_backend(47440526968576);
pg_terminate_backend
----------------------
t
(1 row)
实验发现pg_terminate_backend函数在杀掉cmuser的PID后,会导致cmuser的连接线程消失,但是其他用户不受影响,此时在cmuser的客户端进程内执行sql命令会报错 “terminating connection due to administrator command”。同时操作系统客户端进程仍然存在,但客户端进程内再次执行sql命令会提示“You are currently not connected to a database.”,需要重新连接才能正常执行sql。
[omm@node1 ~]$ gsql -d postgres -U cmuser -p17700 -r
Password for user cmuser:
gsql ((CMDB(openGauss) 1.0.1 build 58ef6fad) compiled at 2022-09-06 16:04:55 commit 0 last mr )
Non-SSL connection (SSL connection is recommended when requiring high-security)
Type "help" for help.
CMDB=> select 1;
FATAL: terminating connection due to administrator command
could not send data to server: Broken pipe
The connection to the server was lost. Attempting reset: Failed.
!> select 1;
You are currently not connected to a database.
!>
postgres=>
[omm@node1 ~]$ ps -ef|grep omm|egrep -v "bash|su|grep|check|writer|launcher|stats"
omm 58750 1 12 12:15 ? 00:04:46 /opt/panweidb/app/bin/gaussdb -D /opt/panweidb/cmdata/data -M pending
omm 64292 48745 0 12:30 pts/0 00:00:00 gsql -d postgres -Uomm -p17700 -r
omm 64310 46566 0 12:30 pts/4 00:00:00 gsql -d postgres -Uomm -p17700 -r
omm 71901 46608 0 12:50 pts/5 00:00:00 gsql -d postgres -U cmuser -p17700 -r
[omm@node1 ~]$ ps -T -p 58750
PID SPID TTY TIME CMD
58750 58750 ? 00:00:00 gaussdb
58750 71789 ? 00:00:00 worker
58750 71845 ? 00:00:00 worker
58750 72055 ? 00:00:00 worker
实验继续使用pg_terminate_backend函数查杀omm用户的会话PID,会导致omm用户的连接线程消失,但是其他用户不受影响。omm用户客户端会话中执行sql会报错“ATAL: terminating connection due to administrator command”。操作系统中的客户端进程仍然存在,客户端再次执行命令成功,与普通帐号再次执行报错不同,omm客户端会话仍然可以正常执行sql。
CMDB=# select user;
FATAL: terminating connection due to administrator command
could not send data to server: Broken pipe
The connection to the server was lost. Attempting reset: Succeeded.
CMDB=# select user;
current_user
--------------
omm
(1 row)
实验继续使用pg_terminate_backend函数查杀远程客户端cmuser2用户的PID,结果和cmuser一样,会导致cmuser2用户的连接线程消失并且再次执行报错,需要重新连接才能正常执行,但是其他用户不受影响。
[root@node1 bin]# gsql -d postgres -hxx.xx.xx.71 -U cmuser2 -p17700
Password for user cmuser2:
gsql ((CMDB(openGauss) 1.0.1 build 58ef6fad) compiled at 2022-09-06 16:04:55 commit 0 last mr )
SSL connection (cipher: ECDHE-RSA-AES128-GCM-SHA256, bits: 128)
Type "help" for help.
CMDB=> select 1;
?column?
----------
1
(1 row)
CMDB=> select 1;
FATAL: terminating connection due to administrator command
SSL connection has been closed unexpectedly, remote datanode (null), error: Success
The connection to the server was lost. Attempting reset: Failed.
!>
此项实验的结果显示:
1)pg_terminate_backend函数可以查杀任意用户的PID,会使该用户本地连接线程消失,其他用户不受影响。
2)客户端进程虽然不会被关联查杀,但是客户端内执行sql会报错,普通帐号再次执行sql会提示断连数据库,超级帐号再次执行sql会恢复正常。
四、实验总结:
知识点:
1)磐维数据库是单进程多线程结构数据库,客户端是单独的进程,客户端对应的连接服务是以线程方式存在,对应的线程名称统一为worker。
2)磐维数据库中kill -9和kill查杀任意用户的连接进程,会导致所有用户的连接线程一并被查杀,并且会导致主服务进程重启。客户端进程虽然不会被关联查杀,但是
客户端进程内执行sql会报错,除超级用户的会话可以自动恢复创建连接线程并恢复客户端中的sql执行,其他用户会话全部消失并在再次执行sql时提示“You are currently not connected to a database.”,需要重新连接后才能正常执行sql。因此,在生产环境中不能直接使用kill或kill -9杀磐维数据库连接会话。
3)磐维数据库中用户连接PID和操作系统层面的连接线程号不一致,不能用过pg_terminate_backend函数杀会话操作系统层面查到的连接线程号。如果使用pg_terminate_backend杀会话,需要先在pg_stat_activity表中查到会话的PID,然后才能使用函数pg_terminate_backend(PID)杀会话。
建议:
通过以上对比试验场景可以看到,对磐维CMDB数据库的会话查杀使用不同的命令还是会有比较大的甚至是非常严重的影响。对于磐维CMDB数据库的会话查杀,建议优先使用pg_terminate_backend函数,如果查杀失败,需要使用更强力的命令时,可以使用kill -9或者kill命令查杀客户端进程。
重要的事情说三遍:
千万不要用kill -9 或者kill 命令查杀任何连接线程!
千万不要用kill -9 或者kill 命令查杀任何连接线程!
千万不要用kill -9 或者kill 命令查杀任何连接线程!