任何軟體,特别是企業級系統元件的更新工作,是一個非常複雜的過程。更新路徑、資料留存預案、回退步驟、原有業務功能沖擊程度,都是需要反複測試論證的問題。所有的運維人員在遇到更新問題的時候,都要抱有謹慎的态度。
筆者最近接手一個更新過的系統,在測試過程中遇到了一些問題。經過查找MOS和網絡資源加以解決。記錄下來,留待需要的朋友。
<b>1</b><b>、環境介紹</b><b></b>
接手的是一個更新到10.2.0.4的Linux版。
SQL> select * from v$version;
BANNER
-----------------------------------------------
Oracle Database 10g Release 10.2.0.4.0 - 64bit Production
PL/SQL Release 10.2.0.4.0 - Production
CORE 10.2.0.4.0 Production
TNS for Linux: Version 10.2.0.4.0 - Production
NLSRTL Version 10.2.0.4.0 - Production
<b>2</b><b>、故障問題展示</b><b></b>
在巡檢中,發現記錄Oracle内部作業排程的視圖dba_scheduler_jobs不能支援查詢。
SQL> select * from dba_scheduler_jobs;
select * from dba_scheduler_jobs
ORA-01882: 未找到時區
1882錯誤的官方解釋資訊如下:
[oracle@allfirst ~]$ oerr ora 1882
01882, 00000, "timezone region %s not found"
// *Cause: The specified region name was not found.
// *Action: Please contact Oracle Customer Support.
但是,并不是所有的字段都不支援查詢動作。
SQL> select owner, job_name from dba_scheduler_jobs;
OWNER JOB_NAME
------------------------------ ------------------------------
SYS SQLSCRIPT_4084880
SYS AUTO_SPACE_ADVISOR_JOB
SYS GATHER_STATS_JOB
SYS FGR$AUTOPURGE_JOB
SYS PURGE_LOG
EXFSYS RLM$SCHDNEGACTION
EXFSYS RLM$EVTCLEANUP
ORACLE_OCM MGMT_STATS_CONFIG_JOB
ORACLE_OCM MGMT_CONFIG_JOB
9 rows selected
從字段性質看,值得懷疑與時區有關的字段是Time Zone。
SQL> select column_name, data_type from dba_tab_columns where owner='SYS' and table_name=upper('dba_scheduler_jobs') and data_type like '%TIME ZONE%';
COLUMN_NAME DATA_TYPE
START_DATE TIMESTAMP(6) WITH TIME ZONE
END_DATE TIMESTAMP(6) WITH TIME ZONE
LAST_START_DATE TIMESTAMP(6) WITH TIME ZONE
NEXT_RUN_DATE TIMESTAMP(6) WITH TIME ZONE
但是,也并不是所有的time zone類型字段都不能顯示。而且這樣的問題不止出現在這個視圖中。
SQL> select start_date from dba_scheduler_jobs;
START_DATE
-----------------------------------------------------
19-3月 -12 05.48.23.742796 下午 +08:00
28-1月 -14 02.42.49.000000 下午 +08:00
13-5月 -13 07.40.35.640706 下午 +08:00
13-5月 -13 07.32.40.314879 下午 +08:00
SQL> select * from SYS.scheduler$_job ;
select * from SYS.scheduler$_job
<b>3</b><b>、問題分析</b><b></b>
從直覺看,應該是資料庫部分資料表中與timezone有關的數值出現問題造成的。
時區TimeZone在Oracle中不僅僅是一個環境變量,而且是融入到資料取值儲存過程中的。Oracle字段類型中,與時區有關的字段類型隻有兩個:timestamp with time zone和timestamp with local time zone。
Oracle的時區是通過時區檔案來進行控制的,不同版本的資料庫,選擇不同版本的時區檔案。
SQL> select * from v$timezone_file;
FILENAME VERSION
------------ ----------
timezlrg.dat 4
一個經常發生的故障,是更新資料庫過程中,沒有更新time zone檔案。這樣導緻更新失敗現象。Time Zone檔案是歸屬在DST技術體系下。10.2.0.2使用的是DST版本為DSTv2、10.2.0.3使用DSTv3、10.2.0.4使用DSTv4。從我們剛才的測試來看,使用的DST版本是正确的。
時區問題的另一個特點是伺服器、用戶端特性差異。如果需要确定是否是伺服器問題,需要直接到伺服器上執行指令。
[oracle@allfirst /]$ sqlplus /nolog
SQL*Plus: Release 10.2.0.4.0 - Production on 星期二 1月 28 14:54:51 2014
Copyright (c) 1982, 2007, Oracle. All Rights Reserved.
SQL> conn / as sysdba
已連接配接。
ERROR:
ORA-01882: 未找到時區區域 %s
說明是資料庫伺服器端問題。如果是用戶端問題,則需要及時更新用戶端版本。
一種猜想是:當Oracle進行版本更新的時候,使用資料庫時區檔案的确是更新了,但是對應的内部資料還沒有進行更新。這樣就存在不相容的問題。
在MOS中,我們也檢查到了對應的讨論文章:Time Zone IDs for 7 Time Zones Changed in Time Zone Files Version 3 and Higher, Possible ORA-1882 After Upgrade (文檔 ID 414590.1)。
其中,介紹了使用檢查腳本進行修複的解決方案。
<b>4</b><b>、問題解決</b><b></b>
在MOS文章中,介紹了故障的解決方法,就是從中下載下傳SQL腳本Fix1882.sql,到界面上進行執行。
解壓之後,上傳到Server段的$ORACLE_HOME/rdbms/admin目錄下。注意:Oracle強烈推薦在服務端執行腳本。
[oracle@allfirst /]$ cd $ORACLE_HOME
[oracle@allfirst 10g]$ cd rdbms/admin/
[oracle@allfirst admin]$ ls -l | grep Fix
-rw-r--r-- 1 root root 11278 01-28 14:58 Fix1882.sql
更換執行權限。
[root@allfirst admin]# chown oracle:dba Fix1882.sql
[root@allfirst admin]# ls -l | grep Fix
-rw-r--r-- 1 oracle dba 11278 1月 28 14:58 Fix1882.sql
在SQLPLUS中執行程式。
[oracle@allfirst ~]$ sqlplus /nolog
SQL*Plus: Release 10.2.0.4.0 - Production on 星期二 1月 28 15:00:36 2014
SQL> @?/rdbms/admin/Fix1882.sql
PL/SQL 過程已成功完成。
會話已更改。
drop view FIX1882V
*
第 1 行出現錯誤:
ORA-00942: 表或視圖不存在
視圖已建立。
drop table FIX1882_PROGRESS *
表已建立。
drop table ADJUST_TZ_TAB
*
過程已建立。
ORA-1882 in SYS.SCHEDULER$_JOB(LAST_ENABLED_TIME), checking rows
Found ORA-1882 on SYS.SCHEDULER$_JOB(LAST_ENABLED_TIME): AAABPpAABAAACuiAAA
Row successfully modified: SYS.SCHEDULER$_JOB(LAST_ENABLED_TIME)
AAABPpAABAAACuiAAA
(篇幅原因,有省略……)
視圖已删除。
執行過程需要消耗幾分鐘,從輸出資訊看,Oracle腳本在檢查每個包括Time Zone相關字段,進行修改處理。輸出資訊裡面還包括了資料行的rowid資訊。
執行之後,檢查資料行。
SQL> select last_start_date from dba_scheduler_jobs;
LAST_START_DATE
----------------------------------------------
19-3月 -12 05.48.44.066014 下午 +08:00
27-1月 -14 10.00.02.601102 下午 +08:00
27-1月 -14 10.00.02.619984 下午 +08:00
18-3月 -12 03.00.00.095899 上午 PST8PDT
28-1月 -14 02.42.49.099626 下午 +08:00
28-1月 -14 02.40.35.095036 下午 +08:00
01-1月 -14 01.01.01.097621 上午 +08:00
27-1月 -14 10.00.02.633247 下午 +08:00
故障解決!
<b>5</b><b>、結論</b><b></b>
更新故障是我們日常運維經常遇到的問題。一套系統進行更新,問題、故障是不能避免的。對我們而言,詳細的規劃和前期研究,反複的測試實驗,可以最大程度的減少我們的風險和壓力。