« 结束IT168《循序渐进Oracle》技术交流会 | Blog首页 | 《循序渐进Oracle》在当当网上 »
497天是一个轮回-记Linux时钟的回转
作者:eygle | 【转载请注出处】|【云和恩墨 领先的zData数据库一体机 | zCloud PaaS云管平台 | SQM SQL审核平台 | ZDBM 数据库备份一体机】
链接:https://www.eygle.com/archives/2007/09/497_day_linux_limit.html
前几天,同事告诉我一个发现,他说一台数据库的运行时间超过了操作系统的启动时间。链接:https://www.eygle.com/archives/2007/09/497_day_linux_limit.html
从数据库内部可以查询到数据库实例的启动时间:
SQL> COLUMN STARTED_AT format A25
SQL> COLUMN UPTIME format A50
SQL> SELECT TO_CHAR (startup_time, 'DD-MON-YYYY HH24:MI:SS') started_at,
2 TRUNC (SYSDATE - (startup_time))
3 || ' day(s), ' || TRUNC ( 24 * ((SYSDATE - startup_time) -
4 TRUNC (SYSDATE - startup_time)))
5 || ' hour(s), '|| MOD (TRUNC ( 1440 * ( (SYSDATE - startup_time) -
6 TRUNC (SYSDATE - startup_time))),60)
7 || ' minute(s), '|| MOD (TRUNC ( 86400 * ( (SYSDATE - startup_time) -
8 TRUNC (SYSDATE - startup_time))),60)
9 || ' seconds' uptime
10 FROM v$instance;
STARTED_AT UPTIME
------------------------- --------------------------------------------------
05-JUL-2005 10:36:58 803 day(s), 2 hour(s), 27 minute(s), 55 seconds
从这里看数据库实例启动了803天左右,也就是说自2005-07-05开始这个数据库一直在不间断的运行着。
而从操作系统的uptime来看,系统不过启动了306天:
SQL> ! uptime
13:06:21 up 306 days, 19:00, 1 user, load average: 0.00, 0.00, 0.00
同事问我原因,首先我们检查alert文件,发现数据库的确是2005年启动的。
如果日志记录的是没有问题的,我当时猜测是否可能是由于系统时钟的更改,使得uptime的显示出现问题。
但是始终觉得这个解释并不充分,今天再研究一下,发现了问题本质。
和以前研究过的问题完全类似,这是又一次时间溢出的问题,
http://www.eygle.com/archives/2004/11/job_can_not_execute_auto.html
http://www.eygle.com/archives/2006/06/time_stop_again.html
由于某些Linux内核使用32位无符号长整型来计算时间,32位的最大值就是0xffffffff,再加1就将溢出变为0
以下一小段C代码可以解释这种溢出:
[root@jumper root]# cat a.c
int main(void){
unsigned int num = 0xffffffff;
printf("num is %d bits long\n", sizeof(num) * 8);
printf("num = 0x%x\n", num);
printf("num + 1 = 0x%x\n", num + 1);
return 0;
}
[root@jumper root]# gcc -o un a.c
[root@jumper root]# ./un
num is 32 bits long
num = 0xffffffff
num + 1 = 0x0
在我的这个Linux发行版本上,这个时间就此溢出:
SQL> ! uname -a
Linux moto 2.4.21-15.ELsmp #1 SMP Thu Apr 22 00:18:24 EDT 2004 i686 i686 i386 GNU/Linux
SQL> ! cat /etc/redhat-release
Red Hat Enterprise Linux AS release 3 (Taroon Update 2)
我们根据497天再来计算一下:
SQL> select 803 - 306 from dual;当前数据库的显示是正确的,803天减去uptime显示时间,得出的正好是497天。
803-306
----------
497
这才是这次异常的本质所在。
SQL> select * from v$version;
BANNER
----------------------------------------------------------------
Oracle9i Enterprise Edition Release 9.2.0.6.0 - Production
PL/SQL Release 9.2.0.6.0 - Production
CORE 9.2.0.6.0 Production
TNS for Linux: Version 9.2.0.6.0 - Production
NLSRTL Version 9.2.0.6.0 - Production
-The End-
历史上的今天...
>> 2019-09-17文章:
>> 2012-09-17文章:
>> 2010-09-17文章:
>> 2009-09-17文章:
>> 2008-09-17文章:
>> 2006-09-17文章:
By eygle on 2007-09-17 12:59 | Comments (6) | Case | Internal | 1620 |
Eygle研究可真深
是不是忒复杂
这个linux还真稳定。
V$TIMERThis view lists the elapsed time in hundredths of seconds. Time is measured since the beginning of the epoch, which is operating system specific, and wraps around to 0 again whenever the value overflows four bytes (roughly 497 days).
to warehouse:
这个案例和v$timer没关系,v$timer的Bug在9.2.0.4之后就解决了。
这个是Linux的问题,后期的版本也已经修正了这个Bug。
这个linux还真是不错哦`