今天 BBS 有朋友问到这么一个问题:假如在客户端执行某一查询语句需要 20 秒时间,而在执行过程中由于某种原因客户端掉线了,此时查询语句在数据库服务端是被终止还是继续运行?
带着这个问题,先做个简单的测试,看看结果如何?
客户端异常掉线测试
测试严格按以下步骤进行:
1.1 会话11
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18[pg93@redhatB ~]$ psql francs francs
psql (9.3beta1)
Type "help" for help.
francs=> begin;
BEGIN
francs=> select pg_backend_pid();
pg_backend_pid
----------------
30079
(1 row)
francs=> timing
Timing is on.
francs=> select pg_sleep(120);
...
备注:这里还在执行过程中。
1.2 另开一窗口查看会话1 状态1
2
3 [pg93@redhatB ~]$ ps -ef | grep 30079
pg93 30079 2504 0 11:47 ? 00:00:00 postgres: francs francs [local] SELECT
pg93 30104 29293 0 11:48 pts/1 00:00:00 grep 30079
1.3 中断会话1
这里模拟客户端异常,直接右键将会话1 的 SecureCrt 客户端关闭。
1.4 继续查看会话1 状态1
2
3 [pg93@redhatB ~]$ ps -ef | grep 30079
pg93 30079 2504 0 11:47 ? 00:00:00 postgres: francs francs [local] SELECT
pg93 30104 29293 0 11:48 pts/1 00:00:00 grep 30079
备注:说明客户端会话被关闭后,查询 SQL 依然在数据库服务器上执行,而没被中断。
总结
- 以上测试的结果是:客户端中断后,语句依然在数据库端执行,有兴趣的朋友可以模拟更多的场景。
- 当语句在客户端发送到数据库后,数据库忙着跑语句,而不会检查客户端的状态,因此客户端掉了,
语句依然能执行,在程序中需要加入连接异常时的处理代码。 - 当维护人员通过客户端 (psql, pgAdmin3) 时发出大的统计查询时,如果会话异常中断,此时最好
联系 DBA ,查下会话是否还在跑,大的统计 SQL 可能要跑好几小时,会严重影响数据库性能。