Oracle数据库时区、时间的问题

Oracle数据库时区、时间的问题,会导致使用了系统时间的存储过程出现问题。

如下图所示:

java 时间入库之后 数据库中时间多了一个小时 数据库时间问题_系统时间

  • 这是一个定时任务,每天定时凌晨2点执行。但是日志记录的时间与真实时间不一致,相差8个小时。
  • 这就会导致定时任务中如果涉及到系统时间的情况,那么其生成、处理的数据时间都将是错误的系统时间

检查数据库时间

我们首先需要检查数据库时间是否有问题

-- 查询数据库时区
select dbtimezone from dual;
-- 查询数据库时间
select to_char(sysdate, 'yyyy-mm-dd hh24:mi:ss') from dual;

第一句是检查数据库的时区。如果是+08:00一般都是正确的东8时区。

java 时间入库之后 数据库中时间多了一个小时 数据库时间问题_系统时间_02


第二句是检查系统时间,根据查询出来的结果时间与实际时间对比,如果是一致的就是对的,不用再看下面的了。

java 时间入库之后 数据库中时间多了一个小时 数据库时间问题_bash_03

检查并处理时间问题

如果查询出来的系统时间与实际时间不一致,需要检查是什么情况。
一般情况下,系统时间不对。应该是数据库所在的服务器时间不对,这里要分两种情况:

  • Oracle是直接安装在服务器上的
  • Oracle是安装在docker容器中的

Oracle是直接安装在服务器上的

  • 方法一,修改时间需要重启

使用 date 命令查询系统时间,如果与实际时间不一致,可以用date -s命令修改时间(加如现在实际时间是21:19:34),修改完成后执行clock -w命令

[root@localhost ~]# date
2022年 08月 03日 星期三 13:19:34 CST
[root@localhost ~]# date -s 21:19:34 
[root@localhost ~]# clock -w
  • 方法二,直接替换时区文件

在root下,入职相应的时区文件,替换系统时区文件。在/usr/share/zoneinfo目录下存放这时区文件,一般我们采用Asia/Shanghai的时区文件。如下列命令

[root@localhost ~]# cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
-- 替换了时区文件之后,可以在执行date命令查看时间是否已经正常。
[root@localhost ~]# date  
2022年 08月 03日 星期三 13:19:34 CST

Oracle是安装在docker容器中的

对于在容器中的数据库,需要进入容器,修改容器的时间。

容器名称的查询,使用docker ps即可列出运行的容器信息。

NAMES列就是容器的名称。使用root权限进入容器,使用命令docker exec -it -u root 容器名称 /bin/bash。

[root@localhost ~]# docker ps  #查询容器信息
CONTAINER ID   IMAGE                 COMMAND             CREATED      STATUS       NAMES         PORTS 
*****          *****                 *****               *****        *****         test          *****
[root@localhost ~]# docker exec -it -u root test /bin/bash  #进入容器

进入容器后,采用替换时区文件的方法。进入/usr/share/zoneinfo/Asia目录下,查看是否又需要的时区文件。

  • 如果有,可以直接执行cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime命令,替换系统时区文件,再执行date -R查看时间是否正常
  • 如果没有,而且对应的文件夹也没有的话,需要先创建对应的文件夹,mkdir -p/usr/share/zoneinfo/Asia。创建好后,使用exit命令先退出回到宿主机,从宿主机中进入/usr/share/zoneinfo/Asia目录下找到对应的时区文件。 执行docker cp/usr/share/zoneinfo/Asia/Shanghai 容器ID或容器名:/usr/share/zoneinfo/Asia 命令,将宿主机中的时区文件拷贝得到docker容器中。再以root权限进入容器替换系统时区文件
bash-4.2# cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime  #修改容器的系统时区文件
bash-4.2# date -R   #检查时间是否正常
Wed, 03 Aug 2022 15:02:17 +0800

bash-4.2# mkdir -p/usr/share/zoneinfo/Asia  #如果没有对应的时区文件夹,就创建
bash-4.2# exit
exit
[root@localhost ~]# docker cp/usr/share/zoneinfo/Asia/Shanghai test:/usr/share/zoneinfo/Asia  #将宿主机的时区文件copy到容器对应的时区文件夹中
[root@localhost ~]# docker exec -it -u root test /bin/bash  #再次进入容器
bash-4.2# cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime   #修改容器的系统时区文件
bash-4.2# date -R   #检查时间是否正常
Wed, 03 Aug 2022 15:02:17 +0800

完成上面的步骤 Oracle数据库的时间问题也就解决了,可以在进入数据库,查询系统时间检查一下。