如何診斷rac環境下sysdate 返回錯誤時間問題,racsysdate

來源:互聯網
上載者:User

如何診斷rac環境下sysdate 返回錯誤時間問題,racsysdate
最近處理了一些rac環境下訪問sysdate返回錯誤時間的問題,而這種問題往往出現在資料庫連結是通過Listener建立的情況下,而且,大部分情況下都是和時區設定相關的。在這篇文章中我們會針對如何診斷這種問題進行解釋。這篇文章適用於版本11.2.0.2 及以上版本。

首先,對問題當中涉及到的知識進行介紹。
1. 從版本11.2.0.2 開始oracle 叢集(GI)開始擁有了自己的時區和一些其他配置,這些配置儲存在設定檔<gi_home>/crs/install/s_crsconfig_<節點名>_env.txt中。
例如:
TZ=Asia/Shanghai
NLS_LANG=AMERICAN_AMERICA.AL32UTF8
TNS_ADMIN=
ORACLE_BASE=
我們能看到變數TZ 用於定義叢集的時區。當然,這個叢集的時區是在安裝GI時從作業系統獲得的。既然叢集有了時區,那麼我們就需要保證GI的時區和作業系統的設定是一致的,並且當作業系統的時區發生改變時,GI的時區也需要改變。而修改叢集時區的基本步驟是(修改<gi_home>/crs/install/s_crsconfig_<節點名>_env.txt檔案,重啟節點)。
2. 當資料庫或者listner 使用srvctl 命令或者隨著GI啟動被啟動時,環境變數會繼承GI的時區。您也可以通過下面的命令來手動設定資料庫和listener資源的環境變數。
srvctl setenv database -d <dbname> -t 'TZ=<時區>'
srvctl setenv listener -l <listenername> -t 'TZ=<時區>'
3. sysdate返回的值並不依賴於資料庫的時區設定,oracle 只是簡單的從作業系統擷取系統時間返回(例如:調用os 函數gettimeofday)。所以,修改資料庫的時區對於這種問題並沒有協助。而對應的伺服器處理序所使用的環境變數TZ才會影響返回的系統時間。


接下來,我們簡單介紹一下用戶端通過listener 串連到資料庫時會經過那些過程。我們會通過一個具體的例子來解釋。在這個例子中,我們使用sqlplus 建立資料庫連結,並對listener進程搜集truss 資訊
1.用戶端串連資料庫
sqlplus scott/tiger@test
2.listner 進程收到了對應的連結,併產生了對應的server process.
524732: psargs: /u01/app/11.2.0/grid/bin/tnslsnr LISTENER -inherit
......
524732: kfork() = 496094
496094: kfork() (returning as child ...) = 0
......
496094: kfork() = 483742
483742: kfork() (returning as child ...) = 0
3. 為server process指定環境變數。
483742: execve(0x0FFFFFFFFFFF2660, 0x0000000110773730, 0x000000011077B670) argc: 2
483742: argv: oracle<sid name> (LOCAL=NO) <<<<<<<< 伺服器處理序環境變數被指定
483742: envp: _=/u01/app/11.2.0/grid/bin/oraagent.bin LANG=en_US LOGIN=root
483742: __CLSAGENT_INCARNATION=2 _ORA_AGENT_ACTION=TRUE PATH=
483742: NLS_LANG=AMERICAN_AMERICA.WE8ISO8859P1 __CLSAGENT_USER_NAME=oracle
......
483742: ENV_FILE=/u01/app/11.2.0/grid/crs/install/s_crsconfig_<node name>_env.txt
......
483742: __CLSAGENT_LOGDIR_NAME=crsd PWD=/ TZ=Asia/Shanghai <<<< 時區被指定。

我們能看到環境變數TZ的值在建立伺服器處理序時會被綁定到server process 中。當然,如果您沒有對lisetner 搜集truss 輸出。您也可以通過作業系統命令獲得對應進程的環境變數,例如:ps eauwww <pid from above>,您可以通過MOS note 373303.1 中的內容獲得不同平台的命令。另外,以上的資料庫是通過GI agent 啟動的,如果資料庫是手動啟動的(例如:startup 命令),那麼,輸出會不同。當然, pmon在註冊資料庫服務到listener時也會將自己的環境變數註冊到對應的service上。

所以,在診斷RAC 環境下sysdate 返回錯誤時間的問題時,我們需要檢查以下資訊。
1. 作業系統層級的時區設定,並確保作業系統命令date 能返回正確的時間。對於如何查看不同平台的時區設定,請參考note 1209444.1
2. 確認GI 設定檔<gi_home>/crs/install/s_crsconfig_<節點名>_env.txt檔案中的變數TZ和作業系統的TZ 設定一致。
3. 確認是否在database或listener資源層面設定了TZ變數。如果設定了,是否和OS,GI的設定是一致的。
4. 另外,server process的環境變數LIBPATH 或 LD_LIBRARY_PATH 也會對oracle訪問作業系統函數產生影響。而且GI 的agent進程(適用於版本11.2.0.3 及以上的版本)在啟動資源時(例如:database資源)會自動的將進程的以下環境變數清空
LD_LIBRARY_PATH, SHLIB_PATH (HP-UX), LD_LIBPATH_PATH_64 (Solaris), LIBPATH(AIX)
所以,如果您的database是使用srvctl 命令啟動的,就需要確認上面的環境變數被設定正確。
例如:srvctl setenv database -d <db_name> -t 'LIBPATH=<gi_home/lib>'
注意:不同的Unix平台,以上命令可能會不同。
所以,我們也去要確認database 資源的LIBPATH 或 LD_LIBRARY_PATH 變數是否被設定。
例如:srvctl getenv database -d <db_name>
另外,在診斷這種問題時,需要搜集以下資訊。
1. <gi_home>/crs/install/s_crsconfig_<節點名>_env.txt檔案
2. 作業系統時區設定(cat /etc/sysconfig/clock) 和環境變數TZ的設定。以及pmon進程的環境變數。
3. database和 listener資源的環境變數
例如:srvctl getenv database -d <db_name>
srvctl getenv listener -l <listener name>
4. 如果以上的資訊沒有問題,那麼就需要搜集listener 進程的truss(或strace) 輸出找到有問題的環境變數設定。
5. 如果1—4 中的資訊仍然無法找到問題的原因,請搜集用戶端和伺服器端的sqlnet trace,以便確認是否有任何的’alter session set ...’命令修改了會話的時區或者相關的變數。
用戶端sqlnet trace:設定以下參數到用戶端的sqlnet.ora 檔案中。
trace_level_client=16
trace_directory_client=c:\tmp ==> 確保該路徑存在
trace_file_client=client
trace_unique_client=on
trace_timestamp_client=on
伺服器端sqlnet trace:設定以下參數到伺服器端的sqlnet.ora檔案中
trace_level_server=16
trace_file_server=server
trace_directory_server=/tmp ==> 確保該路徑存在
trace_timestamp_server=ON


希望以上的解釋對大家診斷類似問題會有所協助。

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.