SQL Server报错The datediff function resulted in an overflow

栏目: 数据库 · 发布时间: 5年前

内容简介:经检查,这个报错,调用的是下面的一个监控:这个监控脚本,是用来监控发生在temp上的pagelatch_up的争用。监控脚本中,包含了datediff函数。datediff的返回值如果overflow,将导致上面的报错。我们来看看,datediff这个值溢出的情况。在

zabbix的监控有一个报错:

SQL Server报错The datediff function resulted in an overflow
The datediff function resulted in an overflow. The number of dateparts separating two date/time instances is too large. Try to use datediff with a less precise datepart.

经检查,这个报错,调用的是下面的一个监控:

select count(*) as cnt from sys.sysprocesses 
where  DateDiff(ss,last_batch,getDate())>=10 
and lastwaittype Like 'PAGE%LATCH_%' 
And waitresource Like '2:%'

这个监控脚本,是用来监控发生在temp上的pagelatch_up的争用。监控脚本中,包含了datediff函数。datediff的返回值如果overflow,将导致上面的报错。

我们来看看,datediff这个值溢出的情况。在 官方文档 中,datediff函数定义返回的是int值,int值的取值范围是 (-2,147,483,648 to +2,147,483,647)。所以,第一步的怀疑,是抓取的起始时间和结束时间之差,溢出了。

那么,什么时候会溢出? 如果进程是刚刚发起的,那么之间的差值,应该会很短,不会溢出。那么离目前时间最远的进程,会不会溢出?

在SQL Server中进程分为客户端进程和系统进程,一般情况下,客户端进程都是最近发起的,所以时间差不会溢出。是否是系统进程导致时间差溢出的呢?

因为系统进程不是客户端发起的,所以系统进程的last_batch时间,就是数据库的启动时间,我们检查了一下数据库的启动时间:

SELECT sqlserver_start_time FROM sys.dm_os_sys_info;

发现是2018-04-14 22:02:46.377。这个时间是否有可能导致溢出?

还是根据官方文档:

SQL Server报错The datediff function resulted in an overflow

可以看到,如果是到秒级,即datediff(ss),中间的时间差是可以长达68年19天3小时14分7秒的。而我们的数据库启动时间,远远没有超过68年。

去掉where条件之后,重新运行了几次上述的 SQL 语句,没有发现早于2018-04-14的。

正当束手无策的时候,想起在这个数据库上部署过msawr,会定期snapshot各项性能指标,那么可以从msawr中去找找线索。

SQL Server报错The datediff function resulted in an overflow

确实,我们在msawr中发现了有些进程的last_batch早于数据库启动的时间,这个时间,是1900-01-01 00:00:00.000。

last_batch的含义,在官方文档是这样解释的:

SQL Server报错The datediff function resulted in an overflow

last_batch是个datetime的值,在 官方文档 中说明中,datetime类型默认值是1900:

SQL Server报错The datediff function resulted in an overflow

而last_batch的这个字段,是not null:

SQL Server报错The datediff function resulted in an overflow

也就是说,在为null的情况下,这个datetime类型的值,将有默认值来填充,所以也就出现了1900-01-01 00:00:00.000。

那么sysprocesses的last_batch会出现控制,进而被替代成1900-01-01 00:00:00.000 ?这个在网上找很多文章,都归结到微软的这个文章:”INF: Last Batch Date is Seen as 1900-01-01 00:00:00.000″ at http://support.microsoft.com/?kbid=306625 , 但是点进去你会发现,这个文章已经404找不到了。

幸好,还有另外的一个 文章 启发了我:

SQL Server报错The datediff function resulted in an overflow

它说:

However, it's possible to create a connection to SQL Server without issuing any RPC calls at all. In this case, the value of last_batch will never have been set and master..sysprocesses will display the value as 1900-01-01 00:00:00.000.

也就是说,由非远程调用(RPC,remote procedure call)发起的进程,其last_batch是null值,而null值继而会被1900-01-01 00:00:00.000所替代。

我们进而看lastwaittype:发现其大部分的,是CXPACKET的并发等待。

SQL Server报错The datediff function resulted in an overflow

所以,应该是并发进程,不是有RPC远程调用的,而是直接在本地调用的。在第一次的时候,last_batch没有被更新,只是留有了null值,进而被替换成了1900年。从而导致了我们的溢出报错。

解决方式也很简单。因为1900年的固定的值,加个条件and last_batch<>‘1900-01-01 00:00:00.000’ 就可以了。

select count(*) as cnt from sys.sysprocesses 
where  DateDiff(ss,last_batch,getDate())>=10 
and lastwaittype Like 'PAGE%LATCH_%' 
And waitresource Like '2:%'
and last_batch<>'1900-01-01 00:00:00.000'

以上所述就是小编给大家介绍的《SQL Server报错The datediff function resulted in an overflow》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

精通Nginx

精通Nginx

[瑞士]艾维利 / 陶利军 / 人民邮电出版社 / 2015-2 / 49.00元

Nginx是一个高性能的轻量级Web服务器,本书从配置文件的角度出发,介绍了多种关于 Nginx配置文件的技巧。 本书以模块化风格写成,几乎每一章都是一个独立的模块,读者将能够自由地在各个模块间切换阅读。全书分两部分,第一部分用8章内容介绍了安装Nginx及第三方模块、配置指南、使用mail模块、Nginx作为反向代理、反向代理高级话题、Nginx Http服务器、Nginx的开发以及故障排......一起来看看 《精通Nginx》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

URL 编码/解码
URL 编码/解码

URL 编码/解码

SHA 加密
SHA 加密

SHA 加密工具