我们知道达梦的disql工具是具有自动重连的功能的,它的目的就是为了防止因网络层面的波动造成会话断开,只要客户端disql的进程还在,可以在网络恢复正常后自动跟数据库服务端创建新连接,并且disql的自动重连功能默认就是打开的,这个autoreconn功能只针对当前disql会话生效。
首先来看“它的功劳”:
当disql自动重连功能关闭时,即在test.sql脚本之前增加set autoreconn off;即可
当disql自动重连功能打开时,我们在执行第一个语句块的过程中重启客户端与数据库服务端的网卡,从而模拟网络中断,我们发现在网络恢复后,脚本中第二个语句块也顺利执行成功了,无需人工干预。所以在sql脚本中执行的操作很多的情况下,如果发生网络波动造成连接断开,这个自动重连功能可以很方便的将后续操作执行完成。
但是,凡事都有两面性,在某种场景下这样可能就不是特别好了,我们再来看看它的“过”:
现有场景如下,使用disql没半小时执行如下脚本,伪代码如下:
delete from xxx where ...; --语句1
insert into xxx values(xxx,xxx...); --语句2
...
insert into xxx values(xxx,xxx...);
update xxx set xxx=xxx,xxx=xxx... where xxx=xxx; --语句3
假如第一条delete和update因为某种原因性能变得极其低下,需要非常长时间去执行,而中间的insert有上千条,并且客户端的应用以每半小时的频率调用disql执行此脚本。现场经过一段时间运行后,发现数据库中有80多个delete操作正在执行,并且都是相同的语句1正在执行,当我们发现此脚本执行的sql语句存在很大性能问题时,肯定是需要对语句1和语句3进行优化,从而提升提性能,那优化之前肯定需要将这80个会话先杀掉。
与现场业务负责人沟通后,进行了“一顿操作梦如虎”,但是每当将这80个连接杀掉后重新查看活动会话时,发现这80个会话又“回来了”,之所以说又回来了是因为这80个会话的create_time是当前时间,并且sess_id都是全新的(不在之前记录的sess_id列表中),说明是杀掉瞬间几乎再次同时创建执行的,这种情况下无论你杀多少次会话都会像“打地鼠”一样蹦出来。
这里有一点需要注意:
如果是通过 sp_close_session()系统过程来杀掉会话,自动重连的连接sess_id是一个完全不同的会话id,如果是网络波动造成的会话中断,disql自动重连上来的连接sess_id还是之前的会话id。
这个问题说到这里大家应该就知道怎么回事了,因为disql自动重连的问题,每当杀掉这些会话,客户端的disql就会立刻尝试重连,并且会从脚本中上一次正在执行的语句位置重新开始往下执行。分析到这里,我们就知道应该怎么处理了:
1.先关闭cront定时任务调用disql脚本
2.杀掉当前正在执行的sh脚本进程;
3.杀掉当前正在执行的disql进程,这时候正在执行的相关活动会话应该就消失了,无需手动杀会话了,这一步也是最关键的一步操作;
4.在每个.sql文件开头增加如下设置关闭disql自动重连
set autoreconn off;
5.优化.sql文件中sql执行效率,重新启用disql定时调用任务;
从上述分析中,其实可以看出disql自动重连功能在某些方面的确很方便,但是在某些场景下又会给运维工作带来一下“麻烦”,我们需要根据实际情况来看是否需要开启disql的自动重连功能,让它更好的服务于我们的业务功能。
文章
阅读量
获赞