字符集问题的初步探讨(七)----关于字符集更改的内部操作

原文链接:

http://www.eygle.com/special/NLS_CHARACTER_SET_07.htm

前面我们提到,通过修改props$的方式更改字符集在Oracle7之后是一种极其危险的方式,应该尽量避免。

我们又知道,通过ALTER DATABASE CHARACTER SET更改字符集虽然安全可靠,但是有严格的子集和超集的约束,实际上我们很少能够
用到这种方法。

实际上Oracle还存在另外一种更改字符集的方式.

如果你注意过的话,在Oracle的alert

  1<sid>.log文件中,你可能看到过这样的日志信息:    
  2  
  3
  4
  5&gt; 
  6&gt;     **alter database character set INTERNAL_CONVERT ZHS16GBK**
  7&gt;     Updating character set in controlfile to ZHS16GBK
  8&gt;      SYS.SNAP$ (REL_QUERY) - CLOB representation altered
  9&gt;      SYS.METASTYLESHEET (STYLESHEET) - CLOB representation altered
 10&gt;      SYS.EXTERNAL_TAB$ (PARAM_CLOB) - CLOB representation altered
 11&gt;      XDB.XDB$RESOURCE (SYS_NC00027$) - CLOB representation altered
 12&gt;      ODM.ODM_PMML_DTD (DTD) - CLOB representation altered
 13&gt;      OE.WAREHOUSES (SYS_NC00003$) - CLOB representation altered
 14&gt;      PM.ONLINE_MEDIA (SYS_NC00042$) - CLOB representation altered
 15&gt;      PM.ONLINE_MEDIA (SYS_NC00062$) - CLOB representation altered
 16&gt;      PM.ONLINE_MEDIA (PRODUCT_TEXT) - CLOB representation altered
 17&gt;      PM.ONLINE_MEDIA (SYS_NC00080$) - CLOB representation altered
 18&gt;      PM.PRINT_MEDIA (AD_SOURCETEXT) - CLOB representation altered
 19&gt;      PM.PRINT_MEDIA (AD_FINALTEXT) - CLOB representation altered
 20&gt;     Completed: alter database character set INTERNAL_CONVERT ZHS1
 21&gt;     
 22&gt;     
 23&gt;       
 24  
 25---  
 26  
 27在这里面,我们看到这样一条重要的,Oracle非公开的命令: 
 28
 29&gt; 
 30&gt;     **alter database character set INTERNAL_CONVERT/ INTERNAL_USE ZHS16GBK**
 31&gt;                             
 32  
 33---  
 34  
 35这个命令是当你选择了使用典型方式创建了种子数据库以后,Oracle会根据你选择的字符集设置,把当前种子数据库的字符集更改为期望字符   
 36集,这就是这条命令的作用. 
 37
 38在使用这个命令时,Oracle会跳过所有子集及超集的检查,在任意字符集之间进行强制转换,所以,使用这个命令时你必须十分小心,你必须   
 39清楚这一操作会带来的风险.   
 40我们之前讲过的内容仍然有效,你可以使用csscan扫描整个数据库,如果在转换的字符集之间确认没有严重的数据损坏,或者你可以使用有效   
 41的方式更改,你就可以使用这种方式进行转换.   
 42我们来看一下具体的操作过程及Oracle的内部操作: 
 43
 44这是alert.log文件中的记录信息:   
 45  
 46Tue Oct 19 16  :  26  :  30 2004   
 47  
 48Database Characterset is ZHS16GBK   
 49  
 50replication_dependency_tracking turned off  (  no async multimaster replication found  )   
 51  
 52Completed  :  ALTER DATABASE OPEN   
 53  
 54Tue Oct 19 16  :  27  :  07 2004   
 55  
 56alter database character set INTERNAL_USE ZHS16CGB231280   
 57  
 58Updating character set in controlfile to ZHS16CGB231280   
 59  
 60Tue Oct 19 16  :  27  :  15 2004   
 61  
 62Thread 1 advanced to log sequence 118   
 63  
 64Current log  # 2 seq# 118 mem# 0: /opt/oracle/oradata/primary/redo02.log   
 65  
 66Tue Oct 19 16  :  27  :  15 2004   
 67  
 68ARC0  :  Evaluating archive log 3 thread 1 sequence 117   
 69  
 70ARC0  :  Beginning to archive log 3 thread 1 sequence 117   
 71  
 72Creating archive destination LOG_ARCHIVE_DEST_1  :  '/opt/oracle/oradata/primary/archive/1_117.dbf'   
 73  
 74ARC0  :  Completed archiving log 3 thread 1 sequence 117   
 75  
 76Tue Oct 19 16  :  27  :  20 2004   
 77  
 78Completed  :  alter database character set INTERNAL_USE ZHS16CGB231280   
 79  
 80Shutting down instance  :  further logons disabled   
 81  
 82Shutting down instance  (  immediate  )   
 83  
 84License high water mark  =  1   
 85  
 86Tue Oct 19 16  :  29  :  06 2004   
 87  
 88ALTER DATABASE CLOSE NORMAL   
 89  
 90...   
 91  
 92...   
 93
 94
 95格式化10046跟踪文件,得到以下信息(摘要): 
 96
 97&gt; 
 98&gt;     alter session set events '10046 trace name context forever,level 12'
 99&gt;     
100&gt;     
101&gt;     **alter database character set INTERNAL_USE ZHS16CGB231280**
102&gt;     
103&gt;     call     count       cpu    elapsed       disk      query    current        rows
104&gt;     ------- ------  -------- ---------- ---------- ---------- ----------  ----------
105&gt;     Parse        1      0.00       0.00          0          0          0           0
106&gt;     Execute      1      4.88       6.04        910      16825      18099           0
107&gt;     Fetch        0      0.00       0.00          0          0          0           0
108&gt;     ------- ------  -------- ---------- ---------- ---------- ----------  ----------
109&gt;     total        2      4.88       6.04        910      16825      18099           0
110&gt;     
111&gt;     Misses in library cache during parse: 1
112&gt;     Optimizer goal: CHOOSE
113&gt;     Parsing user id: SYS
114&gt;     
115&gt;     Elapsed times include waiting on following events:
116&gt;       Event waited on                             Times   Max. Wait  Total Waited
117&gt;       ----------------------------------------   Waited  ----------  ------------
118&gt;       control file sequential read                    4        0.00          0.00
119&gt;       control file parallel write                     2        0.05          0.08
120&gt;       log file sync                                   2        0.08          0.08
121&gt;       SQL*Net message to client                       1        0.00          0.00
122&gt;       SQL*Net message from client                     1       18.06         18.06
123&gt;     ********************************************************************************
124&gt;     
125&gt;     ....
126&gt;     
127&gt;     update col$ set charsetid = :1 
128&gt;     where
129&gt;      charsetform = :2
130&gt;     
131&gt;     ....
132&gt;     
133&gt;     update argument$ set charsetid = :1 
134&gt;     where
135&gt;      charsetform = :2
136&gt;     
137&gt;     ....
138&gt;     
139&gt;     update collection$ set charsetid = :1 
140&gt;     where
141&gt;      charsetform = :2
142&gt;     
143&gt;     ....
144&gt;     
145&gt;     update attribute$ set charsetid = :1 
146&gt;     where
147&gt;      charsetform = :2
148&gt;     ....
149&gt;     
150&gt;     update parameter$ set charsetid = :1 
151&gt;     where
152&gt;      charsetform = :2
153&gt;     ....
154&gt;     
155&gt;     update result$ set charsetid = :1 
156&gt;     where
157&gt;      charsetform = :2
158&gt;     
159&gt;     ....
160&gt;     
161&gt;     update partcol$ set spare1 = :1 
162&gt;     where
163&gt;      charsetform = :2
164&gt;     
165&gt;     ....
166&gt;     
167&gt;     update subpartcol$ set spare1 = :1 
168&gt;     where
169&gt;      charsetform = :2
170&gt;     
171&gt;     ....
172&gt;     
173&gt;     **update props$ set value$ = :1 
174&gt;     where
175&gt;      name = :2**
176&gt;     ....
177&gt;     
178&gt;     update "SYS"."KOTAD$" set SYS_NC_ROWINFO$ = :1 
179&gt;     where
180&gt;      SYS_NC_OID$ = :2
181&gt;     ....
182&gt;     
183&gt;     update seq$ set increment$=:2,minvalue=:3,maxvalue=:4,cycle#=:5,order$=:6,
184&gt;       cache=:7,highwater=:8,audit$=:9,flags=:10 
185&gt;     where
186&gt;      obj#=:1
187&gt;     
188&gt;     ....
189&gt;     
190&gt;     update kopm$ set metadata = :1,  length 
191&gt;       = :2 
192&gt;     where
193&gt;      name='DB_FDO'
194&gt;     
195&gt;     ....
196&gt;     
197&gt;     ALTER DATABASE CLOSE NORMAL
198&gt;                             
199  
200---  
201  
202此处生成的日志你可以在这里下载(供参考): 
203
204http://www.eygle.com/special/primary_ora_13730.zip    
205http://www.eygle.com/special/primary_ora_13730.tkf.log 
206
207我们看到这个过程和之前ALTER DATABASE CHARACTER SET操作的内部过程是完全相同的,也就是说INTERNAL_USE提供的帮助就是使   
208Oracle数据库绕过了子集与超集的校验.   
209这一方法在某些方面是有用处的,比如测试;应用于产品环境大家应该格外小心,除了你以外,没有人会为此带来的后果负责:   
210
211
212结语(我们不妨再说一次): 
213
214对于DBA来说,有一个很重要的原则就是:不要把你的数据库置于危险的境地! 
215
216这就要求我们,在进行任何可能对数据库结构发生改变的操作之前,先做有效的备份,很多DBA没有备份的操作中得到了惨痛的教训。 
217
218本文作者:   
219eygle,Oracle技术关注者,来自中国最大的Oracle技术论坛  itpub  .   
220www.eygle.com  是作者的个人站点.你可通过  [email protected]  来联系作者.欢迎技术探讨交流以及链接交换. 
221
222* * *
223
224原文出处: 
225
226http://www.eygle.com/special/NLS_CHARACTER_SET_07.htm 
227
228* * *</sid>
Published At
Categories with 数据库类
Tagged with
comments powered by Disqus