故障排查77 分钟阅读
Oracle RAC 修改系统时区避坑指南(深挖篇)
大家好,这里是公众号 DBA学习之路,分享一些学习数据库路上的知识和经验。 @TOC目录 昨天遇到一个问题,Oracle RAC 安装完之后,客户反馈数据库查询的时间不对,经分析原来是系统时区与客户所属时区不一致(看来是
2024年8月21日
oraclerac
DBA 实战课程
系统学习 Oracle DBA
- 2738+ 篇实战文章
- 1500+ 步骤截图
- 10 大核心模块
开通会员 ¥128/月起
查看完整课程在知识库中专注阅读,并随时返回相关工具与课程
大家好,这里是公众号 DBA学习之路,分享一些学习数据库路上的知识和经验。

本章目标:掌握本章核心知识点 前置要求:完成前序章节学习 预计时长:60 分钟
昨天遇到一个问题,Oracle RAC 安装完之后,客户反馈数据库查询的时间不对,经分析原来是系统时区与客户所属时区不一致(看来是安装操作系统时选错了时区),需要修改系统时区。
本以为是一个很简单的操作,没想到踩坑了,修改系统时区之后,查询发现以下问题(已解决):
1## 使用 TNS 连接数据库查询时间时区为:上海 +08002$ sqlplus system/oracle@lucifer34SQL> select SYSTIMESTAMP from dual;56SYSTIMESTAMP7---------------------------------------------------------------------------821-AUG-24 01.19.41.557307 PM +08:00910## 使用本地连接数据库查询时间:越南 +070011$ sqlplus / as sysdba1213SQL> select SYSTIMESTAMP from dual;1415SYSTIMESTAMP16---------------------------------------------------------------------------1721-AUG-24 12.20.25.136498 PM +07:00于是把问题重现了一下进行分享,希望大家能够在遇到这种情况时可以及时避坑。
首先用 Oracle一键安装脚本 快速部署一套测试环境:
1./OracleShellInstall -n rocky9 `# RAC 主机名前缀`\2-hn rocky9-01,rocky9-02 `# RAC 主机名`\3-cn rocky9-cls `# RAC 集群名称`\4-sn rocky9-scan `# RAC SCAN 名称`\5-rp oracle `# 主机 root 用户密码`\6-lf ens33 `# 主机网卡名称`\7-pf ens34 `# 主机心跳网卡名称`\8-ri 192.168.6.160,192.168.6.161 `# RAC 公网 IP`\9-vi 192.168.6.162,192.168.6.163 `# RAC 虚拟 IP`\10-si 192.168.6.165 `# RAC SCAN IP`\11-od /dev/sdb `# OCR 磁盘盘符名称`\12-dd /dev/sdc `# DATA 磁盘盘符名称`\13-o lucifer `# 数据库名称`\14-dp 'Passw0rd#PST' `# sys/system 用户密码`\15-ds AL32UTF8 `# 数据库字符集`\16-ns AL16UTF16 `# 国家字符集`\17-redo 100 `# 在线重做日志大小(M)`\18-opd Y `# 是否优化数据库`默认使用专业版脚本。脚本下载:ora100.com/shell-install 耗时 45 分钟左右,下面重现下问题。
当前环境我的系统时区是 Asia/Shanghai (CST, +0800):
1## 节点一2[root@rocky9-01:/root]# ll /etc/localtime 3lrwxrwxrwx. 1 root root 35 Aug 15 10:17 /etc/localtime -> ../usr/share/zoneinfo/Asia/Shanghai4[root@rocky9-01:/root]# timedatectl 5 Local time: Wed 2024-08-21 11:56:42 CST6 Universal time: Wed 2024-08-21 03:56:42 UTC7 RTC time: Wed 2024-08-21 03:56:458 Time zone: Asia/Shanghai (CST, +0800)9System clock synchronized: no10 NTP service: active11 RTC in local TZ: no1213## 节点二14[root@rocky9-02:/root]# ll /etc/localtime 15lrwxrwxrwx. 1 root root 35 Aug 15 10:17 /etc/localtime -> ../usr/share/zoneinfo/Asia/Shanghai16[root@rocky9-02:/root]# timedatectl 17 Local time: Wed 2024-08-21 11:57:40 CST18 Universal time: Wed 2024-08-21 03:57:40 UTC19 RTC time: Wed 2024-08-21 03:57:4320 Time zone: Asia/Shanghai (CST, +0800)21System clock synchronized: no22 NTP service: active23 RTC in local TZ: no查看数据库时间:
1-- 使用 TNS 连接数据库查询时间时区为:上海 +08002SQL> select SYSTIMESTAMP from dual;34SYSTIMESTAMP5---------------------------------------------------------------------------621-AUG-24 11.59.33.946355 AM +08:0078-- 使用本地连接数据库查询时间:上海 +08009SQL> select SYSTIMESTAMP from dual;1011SYSTIMESTAMP12---------------------------------------------------------------------------1321-AUG-24 11.59.33.946355 AM +08:00修改之前可以发现两个方式查询的时间和时区是一致的。
首先停止数据库以及集群服务:
1## 关闭数据库2[oracle@rocky9-01:/home/oracle]$ srvctl stop db -d lucifer3## 关闭集群以及自启(两个节点)4[root@rocky9-01:/root]# crsctl stop crs5[root@rocky9-01:/root]# crsctl disable crs6[root@rocky9-02:/root]# crsctl stop crs7[root@rocky9-02:/root]# crsctl disable crs手动修改操作系统时区:
1## 修改时区为越南(两个节点)2## 节点一3[root@rocky9-01:/root]# timedatectl set-timezone "Asia/Ho_Chi_Minh"4[root@rocky9-01:/root]# timedatectl 5 Local time: Wed 2024-08-21 11:09:43 +076 Universal time: Wed 2024-08-21 04:09:43 UTC7 RTC time: Wed 2024-08-21 04:09:468 Time zone: Asia/Ho_Chi_Minh (+07, +0700)9System clock synchronized: no10 NTP service: active11 RTC in local TZ: no12[root@rocky9-01:/root]# ll /etc/localtime 13lrwxrwxrwx 1 root root 38 Aug 21 11:09 /etc/localtime -> ../usr/share/zoneinfo/Asia/Ho_Chi_Minh1415## 节点二16[root@rocky9-02:/root]# timedatectl set-timezone "Asia/Ho_Chi_Minh"17[root@rocky9-02:/root]# timedatectl 18 Local time: Wed 2024-08-21 11:09:28 +0719 Universal time: Wed 2024-08-21 04:09:28 UTC20 RTC time: Wed 2024-08-21 04:09:3121 Time zone: Asia/Ho_Chi_Minh (+07, +0700)22System clock synchronized: no23 NTP service: active24 RTC in local TZ: no25[root@rocky9-02:/root]# ll /etc/localtime 26lrwxrwxrwx 1 root root 38 Aug 21 11:09 /etc/localtime -> ../usr/share/zoneinfo/Asia/Ho_Chi_Minh可以发现时区已经修改成功,但是为了确保起见,重启一下两台服务器主机:
1[root@rocky9-01:/root]# reboot2[root@rocky9-02:/root]# reboot重启完成后,再次检查操作系统时区:
1## 节点一2[root@rocky9-01:/root]# timedatectl 3 Local time: Wed 2024-08-21 12:10:03 +074 Universal time: Wed 2024-08-21 05:10:03 UTC5 RTC time: Wed 2024-08-21 05:10:036 Time zone: Asia/Ho_Chi_Minh (+07, +0700)7System clock synchronized: no8 NTP service: active9 RTC in local TZ: no1011## 节点二12[root@rocky9-02:/root]# timedatectl 13 Local time: Wed 2024-08-21 12:10:07 +0714 Universal time: Wed 2024-08-21 05:10:07 UTC15 RTC time: Wed 2024-08-21 05:10:0716 Time zone: Asia/Ho_Chi_Minh (+07, +0700)17System clock synchronized: no18 NTP service: active19 RTC in local TZ: no确保没有问题后启动集群和数据库:
1## 启动集群(两个节点)2[root@rocky9-01:/root]# crsctl start crs3[root@rocky9-02:/root]# crsctl start crs4## 打开数据库5[oracle@rocky9-01:/home/oracle]$ srvctl start db -d lucifer正常启动:
1[root@rocky9-01:/root]# crsctl stat res -t2--------------------------------------------------------------------------------3NAME TARGET STATE SERVER STATE_DETAILS 4--------------------------------------------------------------------------------5Local Resources6--------------------------------------------------------------------------------7ora.DATA.dg8 ONLINE ONLINE rocky9-01 9 ONLINE ONLINE rocky9-02 10ora.LISTENER.lsnr11 ONLINE ONLINE rocky9-01 12 ONLINE ONLINE rocky9-02 13ora.OCR.dg14 ONLINE ONLINE rocky9-01 15 ONLINE ONLINE rocky9-02 16ora.asm17 ONLINE ONLINE rocky9-01 Started 18 ONLINE ONLINE rocky9-02 Started 19ora.gsd20 OFFLINE OFFLINE rocky9-01 21 OFFLINE OFFLINE rocky9-02 22ora.net1.network23 ONLINE ONLINE rocky9-01 24 ONLINE ONLINE rocky9-02 25ora.ons26 ONLINE ONLINE rocky9-01 27 ONLINE ONLINE rocky9-02 28--------------------------------------------------------------------------------29Cluster Resources30--------------------------------------------------------------------------------31ora.LISTENER_SCAN1.lsnr32 1 ONLINE ONLINE rocky9-02 33ora.cvu34 1 ONLINE ONLINE rocky9-01 35ora.lucifer.db36 1 ONLINE ONLINE rocky9-01 Open 37 2 ONLINE ONLINE rocky9-02 Open 38ora.oc4j39 1 ONLINE ONLINE rocky9-01 40ora.rocky9-01.vip41 1 ONLINE ONLINE rocky9-01 42ora.rocky9-02.vip43 1 ONLINE ONLINE rocky9-02 44ora.scan1.vip45 1 ONLINE ONLINE rocky9-02验证一下修改后的数据库时间:
1-- 使用 TNS 连接数据库查询时间时区为:上海 +08002SQL> select SYSTIMESTAMP from dual;34SYSTIMESTAMP5---------------------------------------------------------------------------621-AUG-24 01.26.09.483623 PM +08:0078-- 使用本地连接数据库查询时间:越南 +07009SQL> select SYSTIMESTAMP from dual;1011SYSTIMESTAMP12---------------------------------------------------------------------------1321-AUG-24 12.26.21.182588 PM +07:00问题成功复现了。
通过以上情况可以发现,本地的时区是正确的,但是使用 TNS 连接的时区是不对的,因为通过 TNS 连接数据库查询 SYSTIMESTAMP 是取的监听时间,也就是说监听可能存在问题。
这里可以参考 MOS 文档中的 point 9 & 11:Dates & Calendars - Frequently Asked Questions (Doc ID 227334.1)
19) Why is my SYSDATE / SYSTIMESTAMP time not the same as my system clock on Unix?2To debug situations in which you have a unexplained difference between the oracle SYSDATE / SYSTIMESTAMP and the system time you see on Unix, use the following method:34telnet/ssh to the Unix box5connect using sqlplus in the telnet session:671) once through the listener using a tnsnames alias8$sqlplus user/password @ [tnsnames alias]9SQL>select to_char(sysdate,'DD-MON-YY HH24:MI:SS') from dual;10112) once through a "local" ORACLE_SID connection12$env | egrep 'ORACLE_SID'13$sqlplus user/password14SQL>select to_char(sysdate,'DD-MON-YY HH24:MI:SS') from dual;1516Check that the time in the banner of sqlplus ( SQL*Plus: Release 10.1.0.4.0 - Production on Wo Jan 11 15:05:46 2006 ) is reflecting the time based on the current TZ set in the Unix (!) session.1718If the results are different this means that the listener is started with a different TZ setting than you current user environment. To resolve this simply stop and start listener with the TZ setting you want to use.19Make sure you double check what listener you are using when having multiple listeners. For more information about the TZ variable please see your OS documentation.202111)How do I see & set the TZ environment variable in a RAC environment22note 1390015.1 Incorrect SYSDATE shown when connected via Listener in RAC2324Note: If you stop and start a RAC database and/or listener "manual" on Unix (= with sqlplus or lsnrctl) then the above setting is NOT used but the TZ setting of the OS user that starts the database/listener, see point 9)2526How to use multiple timezones for current_timestamp ( NOT for sysdate !) please see Note 1531653.1 How to use multiple timezones with one Oracle RAC database .检查监听的时间是否正确:
1[grid@rocky9-01:/home/grid]$ lsnrctl stat23LSNRCTL for Linux: Version 11.2.0.4.0 - Production on 21-AUG-2024 12:28:5245Copyright (c) 1991, 2013, Oracle. All rights reserved.67Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=LISTENER)))8STATUS of the LISTENER9------------------------10Alias LISTENER11Version TNSLSNR for Linux: Version 11.2.0.4.0 - Production12Start Date 21-AUG-2024 13:13:3213Uptime 0 days 0 hr. 15 min. 20 sec14Trace Level off15Security ON: Local OS Authentication16SNMP OFF17Listener Parameter File /u01/app/11.2.0/grid/network/admin/listener.ora18Listener Log File /u01/app/grid/diag/tnslsnr/rocky9-01/listener/alert/log.xml19Listening Endpoints Summary...20 (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=LISTENER)))21 (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.6.160)(PORT=1521)))22 (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.6.162)(PORT=1521)))23Services Summary...24Service "+ASM" has 1 instance(s).25 Instance "+ASM1", status READY, has 1 handler(s) for this service...26Service "lucifer" has 1 instance(s).27 Instance "lucifer1", status READY, has 1 handler(s) for this service...28Service "luciferXDB" has 1 instance(s).29 Instance "lucifer1", status READY, has 1 handler(s) for this service...30The command completed successfully通过上面的输出可以发现一个很诡异的现象:
1## 查看监听的时间是 12:30,也就是越南时间2LSNRCTL for Linux: Version 11.2.0.4.0 - Production on 21-AUG-2024 12:30:3534## 然而监听启动时间是 13:13,也就是北京时间,明显是错误的5Start Date 21-AUG-2024 13:13:32为什么监听启动时间会是错误的呢?为了尽快解决问题,通过搜索 MOS 发现了一个文档有相关解决方案:How To Change Timezone for Grid Infrastructure (Doc ID 1209444.1)
其中有一段描述与我们遇到的情况极其相似:

可以看到从 11.2.0.2 版本开始,TZ 时区环境变量需要读取 $GRID_HOME/crs/install/s_crsconfig_<nodename>_env.txt 文件中的 TZ 变量值,这也会影响监听的启动时间。
检查文件中对应的 TZ 变量值:
1## 节点一2[grid@rocky9-01:/home/grid]$ cd $ORACLE_HOME/crs/install3[grid@rocky9-01:/u01/app/11.2.0/grid/crs/install]$ grep TZ s_crsconfig_rocky9-01_env.txt 4TZ=Asia/Shanghai56## 节点二7[grid@rocky9-02:/u01/app/11.2.0/grid/crs/install]$ grep TZ s_crsconfig_rocky9-02_env.txt 8TZ=Asia/Shanghai当前配置文件的 TZ 值明显为修改之前的时区,看来是符合的。
既然知道了解决方案,那解决就很简单了,修改 $GRID_HOME/crs/install/s_crsconfig_<nodename>_env.txt 文件中的 TZ 变量为正确的值即可:
1## 节点一2## 备份配置文件3[grid@rocky9-01:/u01/app/11.2.0/grid/crs/install]$ cp s_crsconfig_rocky9-01_env.txt s_crsconfig_rocky9-01_env.txt202408214## 修改 TZ 值5[grid@rocky9-01:/u01/app/11.2.0/grid/crs/install]$ sed -i 's/^TZ=.*/TZ=Asia\/Ho_Chi_Minh/' s_crsconfig_rocky9-01_env.txt6[grid@rocky9-01:/u01/app/11.2.0/grid/crs/install]$ grep TZ s_crsconfig_rocky9-01_env.txt7TZ=Asia/Ho_Chi_Minh89## 节点二10## 备份配置文件11[grid@rocky9-02:/u01/app/11.2.0/grid/crs/install]$ cp s_crsconfig_rocky9-02_env.txt s_crsconfig_rocky9-02_env.txt2024082112## 修改 TZ 值13[grid@rocky9-02:/u01/app/11.2.0/grid/crs/install]$ sed -i 's/^TZ=.*/TZ=Asia\/Ho_Chi_Minh/' s_crsconfig_rocky9-02_env.txt14[grid@rocky9-02:/u01/app/11.2.0/grid/crs/install]$ grep TZ s_crsconfig_rocky9-02_env.txt 15TZ=Asia/Ho_Chi_Minh修改后需要重启数据库和集群才能生效,最好重启主机:
1## 关闭数据库2[oracle@rocky9-01:/home/oracle]$ srvctl stop db -d lucifer3## 关闭集群以及恢复自启(两个节点)4[root@rocky9-01:/root]# crsctl stop crs5[root@rocky9-01:/root]# crsctl enable crs6[root@rocky9-02:/root]# crsctl stop crs7[root@rocky9-02:/root]# crsctl enable crs8[root@rocky9-01:/root]# reboot9[root@rocky9-02:/root]# reboot重启后检查监听:
1## 系统时间2[grid@rocky9-01:/home/grid]$ date3Wed Aug 21 01:07:01 PM +07 20244## 监听时间5[grid@rocky9-01:/home/grid]$ lsnrctl stat67LSNRCTL for Linux: Version 11.2.0.4.0 - Production on 21-AUG-2024 13:07:0289Copyright (c) 1991, 2013, Oracle. All rights reserved.1011Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=LISTENER)))12STATUS of the LISTENER13------------------------14Alias LISTENER15Version TNSLSNR for Linux: Version 11.2.0.4.0 - Production16Start Date 21-AUG-2024 13:05:0317Uptime 0 days 0 hr. 1 min. 59 sec18Trace Level off19Security ON: Local OS Authentication20SNMP OFF21Listener Parameter File /u01/app/11.2.0/grid/network/admin/listener.ora22Listener Log File /u01/app/grid/diag/tnslsnr/rocky9-01/listener/alert/log.xml23Listening Endpoints Summary...24 (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=LISTENER)))25 (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.6.160)(PORT=1521)))26 (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.6.162)(PORT=1521)))27Services Summary...28Service "+ASM" has 1 instance(s).29 Instance "+ASM1", status READY, has 1 handler(s) for this service...30Service "lucifer" has 1 instance(s).31 Instance "lucifer1", status READY, has 1 handler(s) for this service...32Service "luciferXDB" has 1 instance(s).33 Instance "lucifer1", status READY, has 1 handler(s) for this service...34The command completed successfully可以看到监听时间和系统时间已经保持一致,再次验证数据库时间:
1-- 使用 TNS 连接数据库查询时间时区为:越南 +07002SQL> select SYSTIMESTAMP from dual;34SYSTIMESTAMP5---------------------------------------------------------------------------621-AUG-24 01.08.20.889733 PM +07:0078-- 使用本地连接数据库查询时间:越南 +07009SQL> select SYSTIMESTAMP from dual;1011SYSTIMESTAMP12---------------------------------------------------------------------------1321-AUG-24 01.08.24.437260 PM +07:00时区一致,与客户确认后,已恢复正常。
问题解决,就结束了吗?不,还想深究下 3 个问题:
这个配置文件是什么时候生成的?通过分析 Grid 安装日志,大致算是搞清楚了,下面记录一下分析过程,通过倒退的方式。
首先在 $GRID_HOME/crs/install/s_crsconfig_lib.pm 文件中有一个函数:
1sub s_createConfigEnvFile2#---------------------------------------------------------------------3# Function: Create s_crsconfig_$HOST_env.txt file for Time Zone4# Args : none5# Notes : Valid <env_file> format6# (Please keep this in sync with has/utl/crswrapexec.pl)7# * Empty lines: lines with all white space8# * Comments: line starts with #.9# * <key>=<value>10# * <key> is all non-whitespace characters on the left of the11# first "=" character.12# * <value> is everything on the right of the first "=" character13# (including whitespaces).14# * Surrounding double-quote (") won't be stripped.15# * Key with blank <value> ('') will be undefined.16# (e.g: Hello=, Hello will be undefined)17#---------------------------------------------------------------------18{19 my $env_file = catfile($ORA_CRS_HOME, 'crs', 'install',20 's_crsconfig_' . $HOST . '_env.txt');2122 open (ENVFILE, ">$env_file") or die "Can't create $env_file: $!";2324 print ENVFILE "### This file can be used to modify the NLS_LANG environment"25 . " variable, which determines the charset to be used for messages.\n"26 . "### For example, a new charset can be configured by setting"27 . " NLS_LANG=JAPANESE_JAPAN.UTF8 \n"28 . "### Do not modify this file except to change NLS_LANG,"29 . " or under the direction of Oracle Support Services\n\n";3031 # get TZ32 if ($CFG->defined_param('TZ')) {33 my $tz = $CFG->params('TZ');34 $tz =~ s/'//g; # remove single quotes35 print ENVFILE "TZ=" . $tz . "\n";36 }37 ...38 ...39 ...40}我这里截取了其中重要的一部分,也就是创建 s_crsconfig_$HOST_env.txt 文件的代码,这段代码的主要目的是生成一个环境变量配置文件 s_crsconfig_<HOST>_env.txt,其中包含头注释信息,并且会写入 TZ(时区)变量的值。
当然,上面只是定义了一个函数,并没有在这个文件中被调用,调用函数的文件是 $GRID_HOME/crs/install/crsconfig_lib.pm,对应的代码段为:
use s_crsconfig_lib;
sub run_env_setup_modules { ... ... ...
1# create s_crsconfig_$HOST_env.txt file2s_createConfigEnvFile ();}
顺藤摸瓜,找到调用 run_env_setup_modules 函数的文件是 $GRID_HOME/crs/install/rootcrs.pl,对应的代码块是:
use crsconfig_lib;
run_env_setup_modules ();
那么 rootcrs.pl 文件是在哪里以及什么时候调用的呢?对 root.sh 执行过程比较熟悉的朋友应该已经知道了,不熟悉的朋友也没关系,继续顺藤摸瓜就行。
调用 rootcrs.pl 的文件是 $GRID_HOME/crs/config/rootconfig.sh,对应的代码块是:
1HA_CONFIG=false23# 这里 ROOTCRSPL 指向的就是 crs/install/rootcrs.pl 文件4ROOTCRSPL="$ORACLE_HOME/perl/bin/perl -I$ORACLE_HOME/perl/lib -I$ORACLE_HOME/crs/install $ORACLE_HOME/crs/install/rootcrs.pl"56# 当 HA_CONFIG 为 false 时调用了 `rootcrs.pl` 文件7if [ "$HA_CONFIG" = "true" ]; then8 ROOTSCRIPT=$ROOTHASPL9else10 ROOTSCRIPT=$ROOTCRSPL11fi接着就是 rootconfig.sh 被 $GRID_HOME/root.sh 文件调用,对应的代码块是:
1/u01/app/11.2.0/grid/crs/config/rootconfig.sh到这里,生成 s_crsconfig_$HOST_env.txt 文件的整个流程就很清晰了,大概如下:
$GRID_HOME/root.sh$GRID_HOME/crs/config/rootconfig.sh 脚本$GRID_HOME/crs/install/rootcrs.pl 脚本$GRID_HOME/crs/install/crsconfig_lib.pm 文件$GRID_HOME/crs/install/s_crsconfig_lib.pm 文件s_crsconfig_$HOST_env.txt 文件。第一个问题算是彻底研究明白了。
因为前面知道 s_crsconfig_$HOST_env.txt 文件的创建函数了,所以只要看下创建时 TZ 值是如何获取就知道了。
查看创建函数获取 TZ 变量值的代码段:
1# get TZ2 if ($CFG->defined_param('TZ')) {3 my $tz = $CFG->params('TZ');4 $tz =~ s/'//g; # remove single quotes5 print ENVFILE "TZ=" . $tz . "\n";6 }这段代码的主要作用是检查配置对象 $CFG 中是否定义了 TZ 参数,并在存在时获取其值,去除其中的单引号,然后将其以 TZ=<value> 的格式写入到文件中。
也就是说需要知道 $CFG 对象是如何定义的,这个对象是在 $GRID_HOME/crs/install/rootcrs.pl 脚本中定义的,对应的代码段是:
1# pull all parameters defined in crsconfig_params and s_crsconfig_defs (if2# it exists) as variables in Perl3my $paramfile_default = catfile (dirname ($0), "crsconfig_params");45our $PARAM_FILE_PATH = $paramfile_default;67# Read the config files and set up the configuration data for8# subsequent processing9my $cfg =10 crsconfig_lib->new(IS_SIHA => FALSE,11 paramfile => $PARAM_FILE_PATH,12 osdfile => $defsfile,13 addfile => $addparams,14 crscfg_trace => TRUE,15 CRSDelete => $g_delete,16 DEBUG => $DEBUG,17 HAS_USER => $SUPERUSER,18 HOST => $HOST,19 UPGRADE => $UPGRADE,20 UNLOCK => $g_unlock,21 unlock_crshome => $unlock_crshome,22 CRSPatch => $g_patch,23 DOWNGRADE => $DOWNGRADE,24 oldcrshome => $oldcrshome,25 oldcrsver => $oldcrsver,26 force => $g_force,27 deinstall => $g_deinstall,28 keepdg => $g_keepdg,29 lastnode => $g_lastnode,30 REMOTENODE => $REMOTENODE,31 destcrshome => $destcrshome32 );可以看到获取参数值的对应文件为当前目录下的 crsconfig_params 文件,查看文件中是否存在 TZ 相关的参数:
1## 以节点一为例2[grid@rocky9-01:/u01/app/11.2.0/grid/crs/install]$ grep TZ crsconfig_params3# dpham 03/17/10 - Add TZ variable (94620814TZ=Asia/Shanghai📢 注意:这里的 TZ 值还是 Asia/Shanghai,为什么没有影响到数据库的运行?因为这里仅用于安装时生成
s_crsconfig_$HOST_env.txt文件所用,所以不修改也无关大雅。
这个文件是由 crsconfig_params.sbs 生成,其中 TZ 参数:
1[grid@rocky9-01:/u01/app/11.2.0/grid/crs/install]$ grep TZ crsconfig_params.sbs 2# dpham 03/17/10 - Add TZ variable (94620813TZ=%oracle_install_crs_Timezone%可以看到 TZ 变量值是通过 %oracle_install_crs_Timezone% 获取。
在 Grid 安装过程中会生成一个静默文件 $GRID_HOME/inventory/response/oracle.crs_Complete.rsp,其中记录了 Grid 安装时获取到的 %oracle_install_crs_Timezone% 值:
1#-------------------------------------------------------------------------------2#Name : oracle_install_crs_Timezone3#Datatype : String4#Description: 5#-------------------------------------------------------------------------------6oracle_install_crs_Timezone="Asia/Shanghai"这个文件的值是来源于 $GRID_HOME/inventory/globalvariables/oracle.crs/globalvariables.xml,对应的安装日志中也有相关记录:
1## $GRID_HOME/inventory/globalvariables/oracle.crs/globalvariables.xml2<VAR NAME="oracle_install_crs_Timezone" TYPE="STRING" VALUE="Asia/Shanghai" ADVISE="T" COMPUTE_AT_CLONE="F" CALC_REQD="F" CLASS="oracle.sysman.oii.oiis.OiisVariable" EXTENDS_FROM="" ALLOW_ASSIGNMENT="T" HANDLE_ERRORS="F" VAL_REQD="F" SECURE="F" SUPPRESS_ON_SILENT="F" DESC_ID=""/>34## $GRID_HOME/cfgtoollogs/oui/installActions2024-08-15_04-05-22PM.log5INFO: The default response file generated with recorded values is /u01/app/11.2.0/grid/inventory/response/oracle.crs_Complete.rsp6INFO: -destinationFile option was not provided. Saving the default response file as /u01/app/11.2.0/grid/inventory/response/oracle.crs_Complete.rsp7INFO: Recording the installation in file /u01/app/11.2.0/grid/inventory/response/oracle.crs_Complete.rsp.89INFO: INFO: globalpropLocation= /soft/grid/install/../stage/globalvariables/globalvar.xml10INFO: INFO: oracle.install.tb.globalvarpath= /soft/grid/install/../stage/globalvariables/globalvar.xml1112INFO: Reading global variables from file /soft/grid/install/../stage/globalvariables/globalvar.xml1314INFO: ----------------------------------------------------------------------------------------------------15INFO: PROPERTY VALUE 16INFO: ----------------------------------------------------------------------------------------------------17INFO: oracle_install_crs_Timezone Asia/Shanghai 18INFO: adding the variable oracle_install_crs_Timezone to command line args table19INFO: Setting variable 'oracle_install_crs_Timezone' to 'Asia/Shanghai'. Received the value from the command line.2021## $GRID_HOME/install/root_rocky9-01_2024-08-15_16-14-17.log22Using configuration parameter file: /u01/app/11.2.0/grid/crs/install/crsconfig_params2324## $GRID_HOME/cfgtoollogs/crsconfig/rootcrs_rocky9-01.log252024-08-15 16:14:17: The configuration parameter file /u01/app/11.2.0/grid/crs/install/crsconfig_params is valid262024-08-15 16:14:17: ### Printing the configuration values from files:272024-08-15 16:14:17: /u01/app/11.2.0/grid/crs/install/crsconfig_params282024-08-15 16:14:17: paramfile=/u01/app/11.2.0/grid/crs/install/crsconfig_paramsTZ 的值是通过 /soft/grid/install/../stage/globalvariables/globalvar.xml 文件读取的,所以只需要搞清楚 globalvar.xml 的值是如何注入的就知道了。
这个可以在安装软件解压后的文件中找到相关定义:
1## stage/globalvariables/variable.properties2variables_xmls=globalvar.xml34## stage/globalvariables/globalvar.xml5<!-- GLOBAL VARIABLES FOR VENDOR CLUSTERWARE INSTALL -->6 <VAR NAME="oracle_install_crs_Timezone" TYPE="STRING" VALUE="" ALLOW_ASSIGNMENT="T"/>在软件包刚解压时,oracle_install_crs_Timezone 对应的 VALUE 值为空,在安装过程中被写入,至于如何写入的,这个在安装日志中没有找到,怀疑可能是核心 jar 包中获取写入的。
至于最后一个问题,监听为什么会受这个文件影响?这个就需要追溯到监听是在哪一步启动了,在前几天写过一篇:Oracle RAC 集群启动顺序 就有这个答案:

监听是由 oraagent 服务启动,所以需要查看 bin/oraagent 脚本文件,对应的代码段为:
1case $0 in2*.bin) 3 ORASYM=/u01/app/11.2.0/grid/bin/`basename $0 .bin`4 ;;5*) 6 ORASYM=$0.bin7 ;;8esac910exec $ORASYM "$@"这个文件是为了找 oraagent.bin 执行,看起来并没有相关 TZ 配置文件的调用,但是在脚本中我发现了:
1*ohasd*)2 CRSWRAPEXECE="/u01/app/11.2.0/grid/bin/crswrapexece.pl"3 ENV_FILE="${ORA_CRS_HOME}/crs/install/s_crsconfig_${MY_HOST}_env.txt"4 export ENV_FILE由此看来,这个文件是在调用 ohasd 时调用生效,而 ohasd 是最初启动的进程:

查看 $GRID_HOME/log/rocky9-01/client/crswrapexece.log 日志也可以看到:
120-Aug-24 12:46 Executed cmd: /u01/app/11.2.0/grid/bin/crswrapexece.pl /u01/app/11.2.0/grid/crs/install/s_crsconfig_rocky9-01_env.txt /u01/app/11.2.0/grid/bin/ohasd.bin reboot220-Aug-24 12:46 executing "/u01/app/11.2.0/grid/bin/ohasd.bin reboot"这样的话,一切就说的通了,在 ohasd 服务启动时,会去获取 s_crsconfig_${MY_HOST}_env.txt 文件作为环境变量文件 ENV_FILE,然后生效该环境变量文件,自然也就生效了 TZ 时区变量,后续启动监听时也会读取 TZ 变量值。
虽然还是有一些疑问❓没有得到解答,比如 TZ 到底是如何从操作系统层面获取并赋值的?但是通过这一次深挖,确实对 Grid 的安装启动流程了解更加清晰了,希望能对大家也有所帮助!
一篇文章让你彻底掌握 Python 🔥
一篇文章让你彻底掌握 Shell 🔥
Oracle 监控 EMCC 13.5 安装部署超详细教程 🔥
Oracle 一键巡检自动生成 Word 报告 🔥
Oracle一键安装脚本的 21 个疑问与解答 🔥
Oracle一键巡检脚本的 21 个疑问与解答 🔥
全网首发:Oracle 23ai 一键安装脚本 🔥
Oracle 19C 最新 RU 补丁 19.24 ,一键安装! 🔥
Oracle Linux 6 一键安装 Oracle 11GR2 RAC
Oracle Linux 7.9 一键安装 Oracle 19C
Oracle Linux 8.9 一键安装 Oracle 19C RAC
Oracle Linux 9.4(aarch64) 一键安装 Oracle 19C 🔥
openEuler 20.03 LTS SP4 一键安装 Oracle 19C 🔥
openEuler 22.03 LTS SP4 一键安装 Oracle 19C RAC
RHEL 7.9 一键安装 Oracle 19C 19.23 RAC
Redhat 8.4 一键安装 Oracle 11GR2
RedHat 9.4(aarch64) 一键安装 Oracle 19C
龙蜥 Anolis 7.9 一键安装 Oracle 19C 19.23
龙蜥 Anolis OS 8.8 一键安装 Oracle 19C
SUSE 15 SP5 一键安装 Oracle 19C
统信 UOS V20 1070(a) 一键安装 Oracle 11GR2
Ubuntu 22.04 一键安装 Oracle 19C
Ubuntu 14.04 一键安装 Oracle 19C
银河麒麟 Kylin V10 SP3 一键安装 Oracle 19C 🔥
银河麒麟 Kylin V10 SP3 一键安装 Oracle 11GR2 RAC
Oracle DataGuard GAP 修复手册 🔥
优化 Oracle:最佳实践与开发规范
DBA 必备:Linux 软件源配置全攻略 🔥
Linux 一键配置时钟同步全攻略 🔥
Starwind 配置 ISCSI 共享存储
SUSE 15 SP3 安装 Oracle 19C RAC 数据库
达梦 8 数据库安装手册 🔥
Oracle 12CR2 RAC 安装避坑宝典
Linux7 安装 Oracle 19C RAC 详细图文教程 🔥
Oracle ADG 搭建 RAC to Single 详细教程
Oracle DataGuard GAP 修复手册 🔥
Oracle 分区表之在线重定义
AutoUpgrade 快速升级 Oracle 数据库
Oracle 数据库巡检命令手册 🔥
Oracle 数据坏块的 N 种修复方式 🔥
数据库 SQL 开发入门教程
超全 Linux 基础命令总结 🔥
VMware 虚拟机安装 Linux 系统
Linux 安装 MySQL 详细教程
教你玩转 SQLPLUS,工作效率提升 200%
