21. 用exists替換distinct
當提交一個包含一對多表資訊(比如部門表和雇員表)的查詢時,避免在select子句中使用distinct.
一般可以考慮用exist替換
例如:
低效:
select distinct dept_no,dept_name
from dept d,emp e
where d.dept_no = e.dept_no
高效:
select dept_no,dept_name
from dept d
where exists ( select ‘x’
from emp e
where e.dept_no = d.dept_no);
exists 使查詢更爲迅速,因爲rdbms核心模組將在子查詢的條件一旦滿足後,立刻返回結果.
22. 識別’低效執行’的sql語句
用下列sql工具找出低效sql:
select executions , disk_reads, buffer_gets,
round((buffer_gets-disk_reads)/buffer_gets,2) hit_radio,
round(disk_reads/executions,2) reads_per_run,
sql_text
from v$sqlarea
where executions>0
and buffer_gets > 0
and (buffer_gets-disk_reads)/buffer_gets < 0.8
order by 4 desc;
(譯者按: 雖然目前各種關於sql優化的圖形化工具層出不窮,但是寫出自己的sql工具來解決問題始終是一個最好的方法)
23. 使用tkprof 工具來查詢sql性能狀態
sql trace 工具收集正在執行的sql的性能狀態資料並記錄到一個跟蹤文件中.
這個跟蹤文件提供了許多有用的資訊,例如解析次數.執行次數,cpu使用時間等.這些資料將可以用來優化你的系統.
設置sql trace在會話級別: 有效
alter session set sql_trace true
設置sql trace 在整個資料庫有效仿, 你必須將sql_trace參數在init.ora中設爲true,
user_dump_dest參數說明了生成跟蹤文件的目錄
(譯者按: 這一節中,作者並沒有提到tkprof的用法, 對sql trace的用法也不夠準確, 設置sql
trace首先要在init.ora中設定timed_statistics, 這樣才能得到那些重要的時間狀態.
生成的trace文件是不可讀的,所以要用tkprof工具對其進行轉換,tkprof有許多執行參數.
大家可以參考oracle手冊來瞭解具體的配置. )
24. 用explain plan 分析sql語句
explain plan 是一個很好的分析sql語句的工具,它甚至可以在不執行sql的情況下分析語句.
通過分析,我們就可以知道oracle是怎麽樣連接表,使用什麽方式掃描表(索引掃描或全表掃描)以及使用到的索引名稱.
你需要按照從裏到外,從上到下的次序解讀分析的結果. explain plan分析的結果是用縮進的格式排列的,
最內部的操作將被最先解讀, 如果兩個操作處於同一層中,帶有最小操作號的將被首先執行.
nested loop是少數不按照上述規則處理的操作, 正確的執行路徑是檢查對nested
loop提供資料的操作,其中操作號最小的將被最先處理.
譯者按:
通過實踐, 感到還是用sqlplus中的set trace 功能比較方便.
舉例:
sql> list
1 select *
2 from dept, emp
3* where emp.deptno = dept.deptno
sql> set autotrace traceonly /*traceonly 可以不顯示執行結果*/
sql> /
14 rows selected.
execution plan
———————————————————-
0 select statement optimizer=choose
1 0 nested loops
2 1 table access (full) of emp
3 1 table access (by index rowid) of dept
4 3 index (unique scan) of pk_dept (unique)
statistics
———————————————————-
0 recursive calls
2 db block gets
30 consistent gets
0 physical reads
0 redo size
2598 bytes sent via sql*net to client
503 bytes received via sql*net from client
2 sql*net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
14 rows processed
通過以上分析,可以得出實際的執行步驟是:
1. table access (full) of emp
2. index (unique scan) of pk_dept (unique)
3. table access (by index rowid) of dept
4. nested loops (joining 1 and 3)
注: 目前許多第三方的工具如toad和oracle本身提供的工具如oms的sql analyze都提供了極其方便的explain
plan工具.也許喜歡圖形化介面的朋友們可以選用它們.
25. 用索引提高效率
索引是表的一個概念部分,用來提高檢索資料的效率. 實際上,oracle使用了一個複雜的自平衡b-tree結構.
通常,通過索引查詢資料比全表掃描要快. 當oracle找出執行查詢和update語句的最佳路徑時, oracle優化器將使用索引.
同樣在聯結多個表時使用索引也可以提高效率. 另一個使用索引的好處是,它提供了主鍵(primary key)的唯一性驗證.
除了那些long或long raw資料類型, 你可以索引幾乎所有的列. 通常, 在大型表中使用索引特別有效. 當然,你也會發現,
在掃描小表時,使用索引同樣能提高效率.
雖然使用索引能得到查詢效率的提高,但是我們也必須注意到它的代價. 索引需要空間來
存儲,也需要定期維護, 每當有記錄在表中增減或索引列被修改時, 索引本身也會被修改. 這意味著每條記錄的insert ,
delete , update將爲此多付出4 , 5 次的磁片i/o .
因爲索引需要額外的存儲空間和處理,那些不必要的索引反而會使查詢反應時間變慢.
譯者按:
定期的重構索引是有必要的.
alter index rebuild
26. 索引的操作
oracle對索引有兩種訪問模式.
索引唯一掃描 ( index unique scan)
大多數情況下, 優化器通過where子句訪問index.
例如:
表lodging有兩個索引 :
建立在lodging列上的唯一性索引lodging_pk和建立在manager列上的非唯一性索引lodging$manager.
select *
from lodging
where lodging = ‘rose hill’;
在內部 , 上述sql將被分成兩步執行, 首先 , lodging_pk 索引將通過索引唯一掃描的方式被訪問 ,
獲得相對應的rowid, 通過rowid訪問表的方式 執行下一步檢索.
如果被檢索返回的列包括在index列中,oracle將不執行第二步的處理(通過rowid訪問表). 因爲檢索資料保存在索引中,
單單訪問索引就可以完全滿足查詢結果.
下面sql只需要index unique scan 操作.
select lodging
from lodging
where lodging = ‘rose hill’;
索引範圍查詢(index range scan)
適用於兩種情況:
1. 基於一個範圍的檢索
2. 基於非唯一性索引的檢索
例1:
select lodging
from lodging
where lodging like ‘m%’;
where子句條件包括一系列值, oracle將通過索引範圍查詢的方式查詢lodging_pk . 由於索引範圍查詢將返回一組值,
它的效率就要比索引唯一掃描
低一些.
例2:
select lodging
from lodging
where manager = ‘bill gates’;
這個sql的執行分兩步, lodging$manager的索引範圍查詢(得到所有符合條件記錄的rowid)
和下一步同過rowid訪問表得到lodging列的值.
由於lodging$manager是一個非唯一性的索引,資料庫不能對它執行索引唯一掃描.
由於sql返回lodging列,而它並不存在於lodging$manager索引中,
所以在索引範圍查詢後會執行一個通過rowid訪問表的操作.
where子句中, 如果索引列所對應的值的第一個字元由通配符(wildcard)開始, 索引將不被採用.
select lodging
from lodging
where manager like ‘%hanman’;
在這種情況下,oracle將使用全表掃描.
27. 基礎表的選擇
基礎表(driving table)是指被最先訪問的表(通常以全表掃描的方式被訪問). 根據優化器的不同,
sql語句中基礎表的選擇是不一樣的.
如果你使用的是cbo (cost based
optimizer),優化器會檢查sql語句中的每個表的物理大小,索引的狀態,然後選用花費最低的執行路徑.
如果你用rbo (rule based optimizer) , 並且所有的連接條件都有索引對應, 在這種情況下,
基礎表就是from 子句中列在最後的那個表.
舉例:
select a.name , b.manager
from worker a,
lodging b
where a.lodging = b.loding;
由於lodging表的loding列上有一個索引, 而且worker表中沒有相比較的索引, worker表將被作爲查詢中的基礎表.
28. 多個平等的索引
當sql語句的執行路徑可以使用分佈在多個表上的多個索引時, oracle會同時使用多個索引並在運行時對它們的記錄進行合併,
檢索出僅對全部索引有效的記錄.
在oracle選擇執行路徑時,唯一性索引的等級高於非唯一性索引. 然而這個規則只有
當where子句中索引列和常量比較才有效.如果索引列和其他表的索引類相比較. 這種子句在優化器中的等級是非常低的.
如果不同表中兩個想同等級的索引將被引用, from子句中表的順序將決定哪個會被率先使用.
from子句中最後的表的索引將有最高的優先順序.
如果相同表中兩個想同等級的索引將被引用, where子句中最先被引用的索引將有最高的優先順序.
舉例:
deptno上有一個非唯一性索引,emp_cat也有一個非唯一性索引.
select ename,
from emp
where dept_no = 20
and emp_cat = ‘a’;
這裏,deptno索引將被最先檢索,然後同emp_cat索引檢索出的記錄進行合併. 執行路徑如下:
table access by rowid on emp
and-equal
index range scan on dept_idx
index range scan on cat_idx
29. 等式比較和範圍比較
當where子句中有索引列, oracle不能合併它們,oracle將用範圍比較.
舉例:
deptno上有一個非唯一性索引,emp_cat也有一個非唯一性索引.
select ename
from emp
where deptno > 20
and emp_cat = ‘a’;
這裏只有emp_cat索引被用到,然後所有的記錄將逐條與deptno條件進行比較. 執行路徑如下:
table access by rowid on emp
index range scan on cat_idx
30. 不明確的索引等級
當oracle無法判斷索引的等級高低差別,優化器將只使用一個索引,它就是在where子句中被列在最前面的.
舉例:
deptno上有一個非唯一性索引,emp_cat也有一個非唯一性索引.
select ename
from emp
where deptno > 20
and emp_cat > ‘a’;
這裏, oracle只用到了dept_no索引. 執行路徑如下:
table access by rowid on emp
index range scan on dept_idx
譯者按:
我們來試一下以下這種情況:
sql> select index_name, uniqueness from user_indexes where
table_name = emp;
index_name uniquenes
—————————— ———
empno unique
emptype nonunique
sql> select * from emp where empno >= 2 and emp_type = a ;
no rows selected
execution plan
———————————————————-
0 select statement optimizer=choose
1 0 table access (by index rowid) of emp
2 1 index (range scan) of emptype (non-unique)
雖然empno是唯一性索引,但是由於它所做的是範圍比較, 等級要比非唯一性索引的等式比較低
oracle9i 的透明閘道的配置
oracle實現異種資料庫連接服務的技術叫做透明閘道(transparent gateway)。
目前oracle利用透明閘道可以實現和sql server、sybase、db2等多種主流資料庫的互聯。
筆者由於工作需要,通過oracle訪問sybase資料庫,把配置oracle9i transparent gateway for
sybase
的步驟寫成文檔,供需要的網友參考!
配置transparent gateway for sybase步驟
1.
oracle所在伺服器上安裝sybase client(或者在同一台server上安裝oracle、sybase伺服器)
確保能夠訪問sybase資料庫
2.
安裝transparent gateway for sybase選件,要用自定義安裝。
正確選擇sybase的安裝目錄
3.
選擇一個sid字串準備賦給sybase資料庫。如:tg4sybs
設置sybase的dll路徑到環境變數path(這一步很重要)
4.
修改初始化文件,默認的是:
oracle_home\tg4sybs\admin\inittg4sybs.ora
設置參數
hs_fds_connect_info
格式:hs_fds_connect_info= server_name. database_name[,interface=
interface_file]
server_name. database_name是大小寫敏感的。
interface可選
例子:如下
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
# this is a sample agent init file that contains the hs parameters
that are
# needed for the transparent gateway for sybase
#
# hs init parameters
#
hs_fds_connect_info=migration_serv.tax
hs_fds_trace_level=off
hs_fds_recovery_account=recover
hs_fds_recovery_pwd=recover
#
# environment variables required for sybase
#
set sybase=d:\sybase
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
上例中
server_name是migration_serv
database_name是tax
5.
配置oracle網路服務的listener,配置文件是:listener.ora
默認路徑:oracle_home\network\admin
加入如下
sid_list_listener=
(sid_list=
(sid_desc=
(sid_name= gateway_sid)
(oracle_home= oracle_home_directory)
(program=tg4sybs)
)
)
gateway_sid就是3選擇的sid字串
oracle_home_directory是oracle_home
tg4sybs若是sybase是特定的。如果是其他資料庫,會不同。
例子如下:
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
(sid_desc=
(sid_name=tg4sybs)
(oracle_home = d:\oracle\ora92)
(program=tg4sybs)
)
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
6.
停止監聽
lsnrctl stop
重新啓動監聽程式
lsnrctl start
7.
配置oracle server的tnsnames.ora使其能夠訪問sybase
connect_descriptor=
(description=
(address=
(protocol=tcp)
(host= host_name)
(port= port_number)
)
(connect_data=
(sid= gateway_sid))
(hs=ok))
connect_descriptor是連接串,任取,一般爲sybs
host_name:oracle server的name
port_number:oracle監聽埠
gateway_sid就是3選擇的sid字串
例子如下:
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
sybs=
(description=
(address_list =
(address=(protocol=tcp)(host= dw-server1)(port= 1521))
)
(connect_data=
(sid= tg4sybs)
)
(hs=ok)
)
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
8.建立database link
如:
create database link sybs connect to sa
identified by prient
using sbys ;
即可訪問sybase 資料庫。
需要注意的是,sybase資料庫的表名,欄位名,如果是小寫的,那麽在oracle裏訪問的時候要加上雙引號""
如:
sql〉select "a" from "b"@sybs;
ora-01034錯誤的解決辦法
--oracle常見錯誤之一
事先說明,oracle高手是不需要看本文的。
這是個oracle資料庫伺服器比較常見的錯誤。有經驗的用戶幾乎馬上就能解決這個錯誤,再不濟也能馬上到metalink(http://metalink.oracle.com)去搜索一下。
不幸的是,大多的時候,都是初級用戶遇到的這樣的問題(對他們提metalink也起不到什麽作用–一般都沒有上面的帳號:))。所以,這個小帖子可能還有一定的作用。
問題描述
=======
在試圖啓動資料庫的時候,oracle報告下列錯誤:
error:
ora-27101 shared memory realm does not exist
ora-01034 oracle not available
基本解釋
=======
error: ora-27101
text: shared memory realm does not exist
——————————————-
cause: unable to locate shared memory realm
action: verify that the realm is accessible
如何解決
=======
這個問題其實用一句話就可以說清楚:
oracle_home或者oracle_sid設置不正確。
在以前的版本中,如果oracle_sid不正確,一般都只提示ora-01034。oracle 8.1.7
給出一個額外的資訊:ora-27101。
->如果是unix,在shell裏把oracle_sid設置正確即可(注意大小寫敏感的問題)。
此外,檢查oracle_home環境變數。如何檢查參考如下的命令:
% echo $oracle_sid
% ps -ef |grep smon
->如果是windows,一般都是因爲系統中有多個實例造成的。
可以在命令行下 c:\>set oracle_sid=demo
把這裏的demo換爲你相應的實例名。
如果還不行的話,檢查註冊表中的oracle_home。
此外,在windows環境下有的時候連接不上遠端的資料庫,會報告如此的錯誤。
解決辦法是把sqlnet.ora文件中的
sqlnet.authentication_services = (nts) nts換爲none.
ora-03113錯誤分析 fenng(原作)
關鍵字 oracle 03113
fenng(fenng@itpub.net)
版權聲明:轉載請注明作者及出處
前言
每一個dba在進行資料庫管理的過程中不可避免的要遇到形形色色的錯誤(ora-xxxx).有些錯誤由於頻繁出現、原因複雜而被dba們戲稱之爲"經典的錯誤".其中ora-3113
"end of fileon communication channel" 就是這樣的一個.
我們可以簡單的把這個錯誤理解爲oracle用戶端進程和資料庫後臺進程連接中斷.不過,導致這個錯誤的原因實際上有很多種,對資料庫設置不當、任何能導致資料庫後臺進程崩潰的行爲都可能産生這個錯誤.這個錯誤的出現還經常伴隨著其他錯誤,比如說:ora-1034
oracle not available.
此外,該錯誤出現的場景複雜,可能出現在:
啓動的oracle的時侯;
試圖創建資料庫的時侯;
試圖對資料庫進行連接的時侯;
在客戶端正在運行sql/pl/sql的時侯;
備份/恢復資料庫的時侯;
其他一些情況下......
在論壇上也時常可以看到初級dba對這個問題的求救. 在這裏簡單的對該問題進行一下整理.不當之處,請多指教!
錯誤原因種種
根據網路上大家反映的情況來看,錯誤原因大約有這些:
unix核心參數設置不當
oracle執行文件許可權不正確/環境變數問題
用戶端通信不能正確處理
資料庫伺服器崩潰/作業系統崩潰/進程被kill
oracle 內部錯誤
特定sql、pl/sql引起的錯誤
空間不夠
防火牆的問題
其他原因
在開始解決問題之前,作如下幾件事情:
1、 回憶一下在出現錯誤之前你都做了什麽操作,越詳細越好;
2、 查看background_dump_dest目錄中的alertsid.log文件也是你要做的事情;
3、
google一下,在互聯網上有很多資訊等著你去發現,不要什麽都問別人.當然,如果你找到了一些對你非常有幫助的東西――這篇文檔就不用看了,別耽誤你的時間,呵呵.
unix核心參數設置不當/ init參數設置不當
如果資料庫在安裝過程中沒有設定正確的作業系統核心變數,可能在安裝資料庫文件的時侯
沒甚麽問題,在創建資料庫的時侯常常會出現03113錯誤.和此有關的另一個原因是init.ora
參數文件中的processes參數指定了不合理的值,啓動資料庫導致錯誤出現(當然這個歸根到
底也是核心參數的問題).
這個錯誤資訊一般如下:
ora-03113: end-of-file on communication channel
ora-01034: oracle not available
ora-27101: shared memory realm does not exist
解決辦法有兩個:
1修改核心參數,加大相應核心參數的值(推薦);
2減小init.ora參數的processes的值.
需要注意的是:
semmsl必須設定爲至少要10 + 進程數的最大值.
semmns 也依賴於每個資料庫上的進程參數值.
——————————————————————————-
注:
這個錯誤類型只在unix平臺上出現.在windows上如果processes的值過大,則會出現:
ora-00068: invalid value 24200001 for parameter
max_rollback_segments, must be
between 2 and 65535 /* 此時指定的參數值超過了65535 */
或者
ora-27102: out of memory /* 小於65535的一個大參數值 */
我的軟體環境:
windows 2000 version 5.0 service pack 3, cpu type 586
oracle rdbms version: 8.1.7.0.0.
——————————————————————————-
在特定平臺上更改核心參數可能會有差別,請參考oracle
technet(http://otn.oracle.com)上的安裝文檔.對特定unix平臺的安裝文檔也有對核心參數意義的解釋.
init.ora中的參數如果設置不當,會産生該錯誤.有經驗表明:shared_pool_size設置過小會出現錯誤,此外timed_statistics=true的設置也會帶來問題.
oracle執行文件許可權不正確/環境變數問題
這個問題只出現在unix平臺上.常見情況是有的時侯管理員爲了方便而使用unix
的tar命令處理過的壓縮包進行的安裝,或者是系統管理員指定了額外的os用戶也可以管理數
據庫卻沒有指定正確的環境變數.
oracle執行文件在$oracle_home/bin目錄下,如果出現問題,應該用如下unix類似命令來糾正:
chmod 7755 $oracle_home/bin/oracle
有的時侯要對oracle進行relink操作.
在unix上通過cp拷貝安裝的時候,常常會出現環境變數的問題,和個別執行程式連接問題.ld_
library_path如果設置的不正確會導致問題,在這種情況下,需要對oracle進行relink.如果
可執行文件oralcle被破壞,也要對其relink.
如果安裝了並行伺服器選項而distributed lock manager沒有安裝或正確運行也會導致錯誤.
用戶端通信不能正確處理
sql*net驅動器的問題:
如果使用的版本比較低的驅動器,請更換到新版本的驅動.sql*net
的驅動沒有連接到oracle可執行文件會導致錯誤.
檢查網路是否通暢
windows平臺的常見問題:
在windows平臺創建資料庫的時侯,如果出現該問題可以考慮用如下的方法:
首先檢查本地網路設置.查看網路上是否有同名的結點或有衝突的ip.如果問題依舊,可以保
守的用下面的方法:
1. 禁用網卡:將本地連接狀態改爲禁用;
2. 將sqlnet.ora文件打開(以記事本形式)將nts驗證注釋掉:
#sqlnet.authentication_services= (nts).
3. 創建資料庫;
4. 創建成功後,恢復本地連接.
資料庫伺服器崩潰/作業系統崩潰/進程被kill
在連接過程中,如果oracle資料庫的伺服器崩潰或者資料庫所在的作業系統崩潰,就會出現這
個錯誤.oracle
server崩潰的原因可能因爲主要後臺進程死掉.被錯誤的進行了kill操作.如果是這個原因還是比較容易解決的.此外,和os有關的應用程式存在記憶體泄漏(或者有病毒)的時侯也會導致oracle後臺程式問題.
推薦排錯辦法:
1、 查看應用軟體相關進程是否正常運行;
2、 查看有無記憶體泄漏;
3、 查殺病毒;
4、 確定系統管理員沒有進行誤操作;
5、 確定無黑客入侵行爲.
6、 其他不確定因素......
oracle 內部錯誤/ bug
如果查看background_dump_dest目錄中的alert.log發現有無ora-600等錯誤,可以到metalin
k站點上查看具體資訊及其解決方案.一般情況下要打軟體補丁.
特定sql、pl/sql引起的錯誤
嘗試把sql進行分開執行,也可以用sql_trace來進行跟蹤,找到導致問題的sql語句:
在sqlplus下:
alter session set sql_trace true;
sql語句中的非法字元和不合理的處理結果偶爾會帶來問題.
系統空間不夠
任何時侯都要確保資料庫系統有足夠的空間.如果 user_dump_dest
和background_dump_dest沒有剩餘空間的話,會導致此問題.此外,如果打開了審計,audit目錄要由足夠的空間.如果啟動了trace的話,trace目錄要由足夠的空間.
dave wotton的文檔表明,在對表進行插入資料的時侯,如果文件超過了2g(而文件系統有2g限制),會導致該問題.
防火牆的問題
如果資料要通過防火牆,請聯繫系統管理員,詢問是否對資料庫資料進行了過濾或者是突然禁
止了通行埠.如本地安裝有個人防火牆,請檢查本地設置.
其他方面說明
導致這個錯誤的原因有很多種,上面列到的只是一些典型情況.經常去一些資料庫技術論壇可
能會有幫助.比如說itpub(http://www.itpub.net)、cnoug(http://www.cnoug.org)等.
參考資訊/更多閱讀
http://metalink.oracle.com
oracle的技術支援站點,要有csi號碼才可以登錄.
參考note編號:
note:17613.1
ora-3113 on unix – what information to collect
note:131207.1
how to set unix environment variables
note:131321.1
how to relink oracle database software on unix
note:22080.1
http://www.google.com/grphp hl=zh-cn
google新聞組
http://www.jlcomp.demon.co.uk/faq/ora-3113.html
技術專家jonathan lewis的站點上的一個faq
http://home.clara.net/dwotton/dba/ora3113.htm
dave wotton總結的一個很經典的文檔.
在oracle管理和應用中,難免出現一些問題。通常,oracle會顯示錯誤標號和簡短說明,我們可以根據顯示的資訊去處理問題。但有時顯示的資訊很少,處理起來有些麻煩。本文討論了這樣幾個問題,根據一些資料和經驗,提出了解決方法。
一、 ora-00604 error occurred at recursive sql level
這個資訊表明,在資料庫執行內部sql語句時,發生了錯誤。比如,要往表中插入一行資料,但沒有可擴展的空間。oracle於是去查尋,哪兒可以建立下一個擴展空間,它有多大小,但沒有成功。一般在發生ora-00604錯誤時,還伴隨著其他的錯誤,例如:ora-1547等。
首先,應當檢查警告文件alertsid.log,查找有關ora-600類的資訊。
該錯誤最常見的原因是資料庫文件initsid.ora中的參數open_cursors值太小。可以修改initsid.ora文件,open_cursors的值一般爲255。修改完後,宕下oracle,再重新啓動。
還可以設置並啓動資料庫的事件跟蹤功能。在initsid.ora中加上一行:
event = "00604 trace name errorstack"
宕下並重新啓動oracle,使這個事件跟蹤參數起作用。這樣,當再發生ora-604錯誤時,有關資訊就保存在trace文件中。
造成ora-604錯誤的其他原因可能有:
–
initsid.ora中,參數dc_free_extents或row_cache_enqueues太低。可以根據作業系統和資料庫的情況,適當增加這兩個參數的值,宕下並重新啓動oracle。
– 運行超出空間(伴隨ora-1547錯誤)。這時,要對表空間添加新文件,即增加表空間的大小。
–
達到了max_extents(伴隨ora-1556錯誤)。如果這樣,就要修改表,允許更多的擴展。請從技術手冊中查找max_extents的最大值。如果已經達到了最大值,必須用compress
extents選項,把表卸出(export),再導入(import)資料庫中。
二、ora-03106 fatal two-task communication protocol error
這個資訊表明,在oracle進行網路通信工作時,發生了錯誤。比如,客戶應用程式使用sql*net訪問伺服器資料庫時,不能進行,oracle顯示ora-03106錯誤。
首先,應當檢查客戶應用與資料庫伺服器之間的相容性,這是ora-03106錯誤中最常見的原因。現已發現,developer/2000
v1.3預版與oracle v8.0.5 for digital unix不相容;oracle v7.0.1.6 for
scounix與oracle v8.0.5 for digital
unix不相容,等等。再檢查客戶應用與資料庫伺服器之間的nls(字元集)相容性。前些年電腦上的中文字元集一般設置爲zhs16cgb231280,近幾年一般設置爲zhs16gbk,英文作業系統下的設置一般爲us7ascii。最好在系統安裝時,把字元集設置爲同一種,這樣也方便資料庫之間資料的卸出和導入。
如果資料庫鏈路一直不通,並顯示ora-03106錯誤,那麽可能是sql*net的設置問題。要想使用資料庫鏈路,雙方資料庫文件initsid.ora中global_names的值應當是false,伺服器上的文件tnsnames.ora中要有對方的資料庫別名,該別名就是建立資料庫鏈路時使用的別名。尤其在雙機等組成的cluster系統中,人們常常在tnsnames.ora中只寫入帶有機器虛位址的資料庫虛別名,而忘記寫入帶有機器真位址的資料庫真別名。應當把實際應用所涉及到的資料庫別名都寫入tnsnames.ora。
另外,initsid.ora中open_links的值一般默認爲4,在應用程式使用多個資料庫鏈路時,需要適當增加該值。
還可以設置並啓動sql*net的事件跟蹤功能,獲得發生ora-03106錯誤時産生的有關資訊,有針對性地解決問題。
在比較極端的情況下,該問題表明oracle所使用的共用記憶體段崩潰了。可能需要用abort選項宕下資料庫,並釋放所有的semaphores(unix下)。因爲oracle使用semaphores來控制所有後臺進程的同步。semaphores也用來控制用戶進程和影子進程之間的雙任務通信。由於該種情況下牽涉的問題比較複雜,可以將整個機器系統宕下,再重新啓動。
三、從oracle8卸出資料並導入oracle7中
從oracle7卸出的dmp文件,可以導入oracle8中;但從oracle8卸出的dmp文件,不能導入oracle7中。如果用oracle7的實用程式,也不能卸出oracle8的資料。這對應用多種版本oracle的用戶是非常不方便的。
實際上,oracle8已經考慮到這一點。在伺服器目錄$oracle_home/rdbms/admin
中,有個文件catexp7.sql,就是用來解決這個問題的。首先,在oracle8的伺服器中,以sys帳戶登入oracle,接著運行這個catexp7.sql文件。oracle系統於是建立一些卸出視圖,從而使得在卸出時,oracle8資料庫仿佛是oracle7資料庫。這時,就可以用oracle7實用程式直接卸出oracle8的資料,然後便可以順利地導入oracle7中。
在用oracle7實用程式直接卸出oracle8的資料時,有些屬於oracle8特性的東西卸不出來。具體的情況,可以參考有關的技術手冊,比如《oracle8
utilities》。
四、ora-27101 shared memory realm does not exist
在出現上述錯誤資訊時,一般還伴有錯誤資訊:ora-01034: oracle not
available。原因是在同一個伺服器上,使用了不同的oracle_home。該問題常常是在oracle8.1.7伺服器版上出現的。
首先檢查文件initsid.ora和listener.ora等,看oracle_sid和oracle_home設置的正確與否,oracle8.1.7是否用該參數值啓動並運行。在unix環境中,字母大小寫的意義是不一樣的,這一點應當注意。如果oracle_home指向8.1.7版,而資料庫是用8.1.6版或8.1.5版建立的,也可能出現該種錯誤資訊。
在windows系統中,如果修改了機器名或ip地址,oracle8.1.7啓動時使用的機器名或ip地址就不是真正的機器名或ip位址,就會出現該種錯誤。可以查看目錄database下的文件oradim.log,根據內容確定原因。
在涉及到域(domain)的伺服器上,包括windows和unix,根據系統設置情況,可能需要在使用機器名時,後面添加功能變數名稱。
