首页
产品
CLup:PostgreSQL高可用集群平台CData高性能数据库云一体机CBackup数据库备份恢复云平台CPDA高性能双子星数据库机
解决方案
数据库专业技术服务全栈式PostgreSQL解决方案Oracle分布式存储化数据库云
文章
客户及伙伴
中启开源
关于我们
公司简介 联系我们
中启开源

当网络临时性中断一会后然后又恢复或中间出现丢包等临时性故障,一般要求应用程序能自动恢复。同样应用程序连接数据库,当应用与数据库之间的网络出现故障后,也需要应用能自动从这个临时性故障中恢复。

在最早的TCP设计中,当没有数据包时,它本身并没有心跳。也就是说当应用向数据库发送一个请求后,数据库一直没有返回结果时,应用程序是不知道是因为网络出现问题导致数据库返回的结果丢失了,还是数据库服务器还一直在执行SQL。虽然后面的TCP协议增加了keepalive的心跳包,但多数操作系统的心跳包的间隔时间要么很长,要不默认没有设置。如Linux下的keepalive的设置是2小时,这对于多数应用都是太长了。所以应用程序通常使用超时的机制来解决这个问题。也就是设置socket的超时时间,即socketTimeout。

在JDBC中,设置超时时间,通常可以在连接数据库中的URL中以参数的形式设置,如在PostgreSQL中:

  1. jdbc:postgresql://127.0.0.1:5432/osdba?socketTimeout=180

在MySQL中:

  1. jdbc:MySQL://127.0.0.1:3306/osdba?socketTimeout=180000

需要注意的是,在PostgreSQL中socketTimeout的单位为秒,而MySQL中的单位为毫秒。

在JDBC中,Statement.setQueryTimeout()来设置查询的超时时间,不同的数据库的JDBC,这个超时时间实现的原理是不一样的。MySQL中,是启动一个timer任务,到了超时时间,查询还没有返回,则直接调用MySQL的kill指令把session终止掉。在PostgreSQL中,到了超时时间,向服务器发送取消执行的命令,所以在PostgreSQL中超时后得到的错误是“ERROR: canceling statement due to user request”。

需要注意的是:

即使设置了查询超时,当网络出错时,查询也可能会出现hang,这必须通过设置socketTimeout来解决

实际对于PostgreSQL来说,可以直接在服务端端参数设置查询的超时时间:

  1. SET statement_timeout=3000;

PostgreSQL JDBC的连接的超时参数为loginTimeout,单位为秒:

  1. jdbc:postgresql://127.0.0.1/osdba?loginTimeout=10

MySQL JDBC的连接的超时参数为connectTimeout,单位为毫秒:

  1. jdbc:MySQL://127.0.0.1:3306/osdba?connectTimeout=10000

MySQL数据库服务端的一些超时的参数说明:

在PostgreSQL中没有类似MySQL中的“wait_timeout”参数,但可以自己写一个crontab任务查询pg_stat_activity表,发现一个Idle的连接超过一定的时间后,kill掉。

PostreSQL的锁超时参数:

MySQL中的锁超时参数: