非RAC環境字符集修改
1.1 Oracle字符集問題總結
1.1.1 oracle字符集概念
oracle字符集是一個字節數據的解釋的符號集合,有大小之分,有相互的包容關系。ORACLE 支持國家語言的體系結構允許你使用本地化語言來存儲,處理,檢索數據。它使數據庫工具,錯誤消息,排序次序,日期,時間,貨幣,數字,和日歷自動適應本地化語言和平臺。
影響oracle數據庫字符集最重要的參數是NLS_LANG參數。格式:NLS_LANG = language_territory.charset
其中:Language 指定服務器消息的語言,territory 指定服務器的日期和數字格式,charset 指定字符集。如:AMERICAN _ AMERICA. ZHS16GBK。從NLS_LANG的組成我們可以看出,真正影響數據庫字符集的其實是第三部分。所以兩個數據庫之間的字符集只要第三部分一樣就可以相互導入導出數據,前面影響的只是提示信息是中文還是英文。
1.1.2 查詢Oracle的字符集
在做數據導入的時候,需要這三個字符集都一致:一是oracel server端的字符集,二是oracle client端的字符集;三是dmp文件的字符集。
A. 查詢oracle server端的字符集
SQL>select userenv('language') from dual;
結果類似:AMERICAN_AMERICA.ZHS16GBK
或者select * from V$_NLS_PARAMETERS
B. 如何查詢dmp文件的字符集
dmp文件的第2和第3個字節記錄了dmp文件的字符集。小dmp文件用UltraEdit打開(16進制方式),看第2第3個字節的內容,如0354,然后用以下SQL查出它對應的字符集:
SQL> select nls_charset_name(to_number('0354','xxxx')) from dual;
結果ZHS16GBK
dmp文件很大如2G以上,用文本編輯器打開很慢或者完全打不開,可以用命令(在unix主機上):
cat exp.dmp |od -x|head -1|awk '{print $2 $3}'|cut -c 3-6
然后用上述SQL也可以得到它對應的字符集。
C. 查詢oracle client端的字符集
windows注冊表里面相應OracleHome的NLS_LANG(如果裝配置臺等將總共有3個:ORACLE下一個、ID0下有一個、HOME0下一個)。還可以在dos窗口里面自己設置,如:set nls_lang=SIMPLIFIED CHINESE_CHINA.ZHS16GBK這樣就只影響這個窗口里面的環境變量;
在unix平臺下,就是環境變量NLS_LANG。$echo $NLS_LANG 如AMERICAN_AMERICA.ZHS16GBK
如果檢查的結果發現server端與client端字符集不一致,請統一修改為同server端相同的字符集(建議導入時直接在服務器上導入)
1.1.3 修改oracle的字符集
oracle的字符集有互相的包容關系。如us7ascii就是zhs16gbk的子集,從us7ascii到zhs16gbk不會有數據解釋上的問題,不會有數據丟失。在所有的字符集中utf8應該是最大,因為它基于unicode,雙字節保存字符(也因此在存儲空間上占用更多)。
一旦數據庫創建后,數據庫的字符集理論上講是不能改變的。字符集的轉換是從子集到超集受支持,反之不行。如果兩種字符集之間根本沒有子集和超集的關系,那么字符集的轉換是不受oracle支持的。一般來說,除非萬不得已,我們不建議修改oracle數據庫server端的字符集。特別說明,我們最常用的兩種字符集ZHS16GBK和ZHS16CGB231280之間不存在子集和超集關系,因此理論上講這兩種字符集之間的相互轉換不受支持。
A. 修改server端字符集(不建議使用)
在oracle 8之前,可以用直接修改數據字典表props$來改變數據庫的字符集。但oracle8之后,至少有三張系統表記錄了數據庫字符集的信息,只改props$表并不完全,可能引起嚴重的后果。正確的修改方法如下:
$sqlplus /nolog
SQL>conn / as sysdba;
若此時數據庫服務器已啟動,則先執行SHUTDOWN IMMEDIATE命令關閉數據庫服務器,然后執行以下命令:
SQL>STARTUP MOUNT;
SQL>ALTER SYSTEM ENABLE RESTRICTED SESSION;
SQL>ALTER SYSTEM SET JOB_QUEUE_PROCESSES=0;
SQL>ALTER SYSTEM SET AQ_TM_PROCESSES=0;
SQL>ALTER DATABASE OPEN;
SQL>ALTER DATABASE CHARACTER SET ZHS16GBK;
SQL>ALTER DATABASE national CHARACTER SET ZHS16GBK;
SQL>SHUTDOWN IMMEDIATE;
SQL>STARTUP
B. 修改dmp文件字符集
dmp文件的第2第3字節記錄了字符集信息,因此直接修改dmp文件的第2第3字節的內容就可以'騙'過oracle的檢查。這樣做理論上也僅是從子集到超集可以修改,但很多情況下在沒有子集和超集關系的情況下也可以修改,我們常用的一些字符集,如US7ASCII,WE8ISO8859P1,ZHS16CGB231280,ZHS16GBK基本都可以改。因為改的只是dmp文件,所以影響不大。
具體的修改方法比較多,最簡單的就是直接用UltraEdit修改dmp文件的第2和第3個字節。比如想將dmp文件的字符集改為ZHS16GBK,可以用以下SQL查出該種字符集對應的16進制代碼:
SQL> select to_char(nls_charset_id('ZHS16GBK'), 'xxxx') from dual;
0354
然后將dmp文件的2、3字節修改為0354即可。
RAC環境修改oracle字符集
2.1 RAC環境存在問題
在RAC環境下修改oracle服務器的字符集仍然按非RAC模式方法修改過程會遇到ORA-12720的錯誤信息
SQL>ALTER DATABASE CHARACTER SET ZHS16GBK;
ORA-12720:, operation requires database is in EXCLUSIVE mode. Cause:,
上述錯誤信息標明在RAC方式下無法對服務端字符集進行修改,需要將數據庫運行在但實例模式運行。
2.2 解決該問題的嘗試
為解決上述遇到的問題,嘗試將兩臺機器cluster軟件停止,在單節點上手工激活VG并啟動oracle,又會遇到ORA-32700的錯誤。錯誤信息如下:
ora-32700 error occurred in DIAG Group Service
在很多情況下都會報ORA-32700的錯誤,在此處的原因大概是因為沒有啟動雙機cluster軟件導致,如果將單節點的cluster進程啟動,oracle實例也會跟著啟動,修改時又會出現2.1節遇到的錯誤。
2.3 RAC環境修改字符集步驟
2.3.1 數據庫參數文件目錄備份
為解決2.1節遇到錯誤就必須將數據庫修改為單實例非cluster模式,需要對數據庫參數文件進行修改,但進行參數文件修改需要一些竅門和方法。
正常RAC模式下ORACLE_HOME/dbs目錄下文件如下列表
-rw-r--r-- 1 oracle dba 8385 Aug 17 16:18 init.ora
-rw-r--r-- 1 oracle dba 12920 Aug 17 16:18 initdw.ora
-rw-r--r-- 1 oracle dba 1424 Aug 17 16:18 initora92.ora
-rw-r--r-- 1 oracle dba 25 Aug 17 16:18 initora921.ora
-rw-r--r-- 1 oracle dba 25 Aug 17 16:18 initora922.ora
-rw-r----- 1 oracle dba 1536 Aug 17 16:18 orapw
-rwSr----- 1 oracle dba 1536 Aug 17 16:18 orapwora921
-rw-r----- 1 oracle dba 1536 Aug 17 16:18 orapwora922
兩個數據庫實例的pfile文件內容如下:
[icdnode1]$cat initora921.ora
SPFILE='/dev/rlv_spfile'
[icdnode1]$cat initora922.ora
SPFILE='/dev/rlv_spfile'
但initora92.ora文件是正常的有參數配置項目的文本文件,長度比較大,再次不列出內容。
雖然在dbs目錄下并沒有spfile文件,數據使用pfile啟動,但pfile又制定了spfile文件的位置,數據庫使用spfile文件啟動。
上述的兩個實例的pfile文件是無法修改的,需要將pfile文件修改為常規的文本文件配置項才能進行配置修改操作。
備份操作:
cd $ORACLE_HOME
cp –r dbs dbs_bak
2.3.2 修改數據庫參數文件
修改數據庫參數文件目的是修改配置項*.cluster_database=true → false,因此需要對pfile進行操作,可以用如下方法還原pfile文件。
正常啟動RAC數據庫的一個節點,另一個節點關機或停止cluster進程;
連接啟動的實例并使用spfile配置生成pfile:
Sqlplus ‘/as sysdba’
SQL>create pfile from spfile;
SQL>exit
此時ORACLE_HOME目錄的dbs目錄中文件列表如下:
-rw-r--r-- 1 oracle dba 8385 Aug 17 16:15 init.ora
-rw-r--r-- 1 oracle dba 12920 Aug 17 16:15 initdw.ora
-rw-r--r-- 1 oracle dba 1425 Aug 17 16:29 initora92.ora
-rw-r--r-- 1 oracle dba 1425 Aug 17 16:32 initora921.ora
-rw-r--r-- 1 oracle dba 25 Aug 17 16:15 initora922.ora.bak
-rw-r----- 1 oracle dba 1536 Aug 17 16:15 orapw
-rwSr----- 1 oracle dba 1536 Aug 17 16:15 orapwora921
-rw-r----- 1 oracle dba 1536 Aug 17 16:15 orapwora922
可以看到initora921.ora文件長度由原來的25字節變成1425,與initora92.ora文件長度一致,也變成可編輯的文本文件。
initora92.ora和initora921.ora配置文件前幾行是一致的,將true修改為false
*.aq_tm_processes=0
*.background_dump_dest='/home/oracle/app/oracle/admin/ora92/bdump'
*.cluster_database_instances=2
*.cluster_database=true
ora921.cluster_interconnects='192.168.1.1'
ora922.cluster_interconnects='192.168.1.2'
pfile文件修改完成后關閉此節點的cluster服務,數據庫也隨cluster關閉而關閉。
2.3.3 按非RAC模式操作指導修改字符集
將數據修改為非RAC模式后可按非RAC模式的操作指導進行修改操作,操作時需要手工激活oracle系統vg。
2.3.4 修改完成后備份恢復
在非RAC模式完成字符集修改完成后,關閉數據庫將原dbs目錄恢復,重新啟動cluster軟件,在兩臺機器兩個實例查詢oracle服務器端字符集已經成功修改。
2.4 RAC環境修改字符集快速步驟
總結上述操作步驟即操作過程,從理論上可以用以下步驟完成快速修改:
2.4.1 先修改spfile的參數
停止一個節點的cluster程序,在另一個節點執行
Sqlplus ‘/as sysdba’
SQL> Alter system set cluster_database=false scope=spfile;
SQL>exit
2.4.2 進行字符集修改
停止主節點的cluster程序,然后varyonvg oravg
然后用修改單機的操作步驟進行字符集修改。
2.4.3 恢復spfile配置和RAC模式
Sqlplus ‘/as sysdba’
SQL> Alter system set cluster_database=true scope=spfile;
SQL>shutdown immediate
SQL>exit
啟動兩個節點的cluster進程,進行驗證測試
posted on 2009-05-14 18:56
YangRj 閱讀(212)
評論(0) 編輯 收藏