记录一次奇怪的sysdate时间错误问题

最近总是遇到奇葩的问题...

客户的生产环境为一套两节点RAC,数据库版本为11.2.0.4,运行在centos6.9虚拟机中,现在发现下面客户端连接到数据库的时候,当会话连接在节点1上的时候,查询的sysdate时间不对,比正常时间晚了13个小时,而当会话连接到节点2的时候,时间是正常的.

对于此问题,第一反应就是两个系统的时区不对.连接到节点上,分别执行date命令查看,发现时区都是对的,都是CST时区,即上海时区.

使用sqlplus登录到数据库,分别执行查询:

select sysdate from dual;

 发现结果都是正确的.时间一致.

检查操作系统时区:

cat /etc/localtime

 发现也是一致的.

只能求助一下MOS,一般这种诡异的问题MOS上基本都有解决办法,确实MOS没有让我们失望,找到一篇文档:

单击此项可添加到收藏夹   How to Diagnose Wrong Time ( SYSDATE and SYSTIMESTAMP) After DST Change , Server Reboot , Database Restart or Installation When Connecting to a Database on an Unix Server (文档 ID 1627439.1)

 

这篇文章写的还是很详细的.基本上主要还是说环境变量,时区对系统时间的影响.

里面谈到了为何用sqlplus查询是正确的,但是通过监听查询却是错误的:

- PMON only reads the OS environment variables when the database is started. If TZ is changed after the database is started PMON will not pick up the changed value.

也就是说PMON启动的时候只读取数据库启动时刻的操作系统环境变量,如果你后面TZ变量变化了PMO并不会变.

所以我怀疑还是时区的问题,也就是数据库启动时刻的系统时区不对.

执行下面的查询查看数据库最近启动时刻的时区:

conn / as sysdba
SET SPACE 1 LINESIZE 80 PAGES 1000
SELECT * FROM (
select to_char(ORIGINATING_TIMESTAMP,'YYYY/MM/DD HH24:MI:SS TZH:TZM') 
from V$DIAG_ALERT_EXT 
WHERE trim(COMPONENT_ID)='rdbms' 
and MESSAGE_TEXT like ('PMON started with%') 
order by originating_timestamp desc ) 
WHERE rownum < 20;

结果发现节点1最近一次启动时刻的时区为-5,而节点2最近一次启动时刻的时区是+8,两者相差了13小时,这也是为什么节点1时间比节点2时间晚13小时的原因.

记录一次奇怪的sysdate时间错误问题_第1张图片

记录一次奇怪的sysdate时间错误问题_第2张图片

尝试手工export TZ环境变量,然后重启数据库发现可以恢复正常:

export TZ=Asia/Shanghai

那说明确实是时区的影响导致.那么数据库启动的时候读取的系统的时区,那么系统的时区在哪里配置呢?在操作系统上一顿操作,什么设置/etc/profile  ~/.bash_profile  /etc/localtime 都配置了一遍,但是还是不行.每次重启服务器,数据库重启之后时区又还是-05

那么继续按照MOS上面的进行检查,是否是集群做了配置导致的,查看集群的启动环境变量:

srvctl getenv database -d
srvctl getenv listener -l        --这里一般listener

-- If you are on 11.1 or lower, then use 'getenv nodeapps' instead of 'getenv listener' :
srvctl getenv nodeapps -n

-- get the ASM env
srvctl getenv asm

用上面的语句检查发现集群没有配置环境变量.

既然集群没有配置启动环境变量,那我们来配置一下吧,让集群启动的时候使用我们指定的TZ来启动监听和数据库:

使用root修改:

srvctl setenv database -d -t 'TZ= Asia/Shanghai>'
srvctl setenv listener -l -t 'TZ=Asia/Shanghai'

-- If you are on 11.1 or lower, then use 'setenv nodeapps' instead of 'setenv listener':
srvctl setenv nodeapps -n -t 'TZ=Asia/Shanghai>'

修改完成之后,重启服务器,数据库自动启动后也恢复正常.

到最后我也没弄明白,出问题的时候集群启动的时候读取的是哪里的时区信息.

不过oracle也是直接提供了setenv参数,管你系统环境是啥,我在集群里面设置一下,以后启动都是以集群配置为准,还是很方便的

 

 

你可能感兴趣的:(oracle,troubleshoting,oracle,rac,sysdate,时区)