Oracle常用問題及解答
Oracle基礎操作類
1.請寫出如何新增資料檔案的語句
Alter tablespace data add datafile ‘/oracle/oradata/CFGDB/data01.dbf’ size 100m
2.請寫出如何啟動歸檔模式
Shutdown immediate startup mount alter database archivelog alter database open
3.請寫出如何檢視當前被鎖的表
Select t1.object_name from dba_objects t1,v$session t2,v$locked_object t3 where t1.object_id=t3.object_id and t2.sid=t3.session_id;
4.請寫出如何檢視某張表的索引
Select * from dba_indexes where table_name=’’;
5.請寫出如何檢視某張表的大小
Select * from dba_segments where segment_name=’’ and segment_type=’TABLE’;
6.請寫出如何檢視某使用者使用的預設表空間
Select username,default_tablespace,temporary_tablespace from dba_users where username=’’;
7.請寫出如何檢視各個表空間的大小
select tablespace_name,bytes/1024/1024 from dba_data_files;
8.請寫出如何檢視當前資料庫存在的等待事件
select * from v$session_wait; select * from v$waitstat; desc v$waitstat
9.請寫出如何生成AWR報告
@$ORACLE_HOME/rdbms/admin/awrrpt.sql
@$ORACLE_HOME/rdbms/admin/ashrpt.sql
10.請寫出切換日誌的語句
alter system switch logfile;
11.請寫出如何透過sqlid獲得該SQL的執行計劃
explain plan for select * from ...
select * from table(DBMS_XPLAN.DISPLAY_AWR(SQL_ID));10G以後。
SELECT * FROM table (DBMS_XPLAN.DISPLAY_AWR ('danxh10kwn2s3',NULL,NULL,‘BASIC’));可以把BASIC 換成 ADVANCE 和TYPICAL試試。
12.請寫出如何鎖住某個使用者
alter user SN account lock;
alter user SN account unlock;
13.請寫出如何查詢某表的統計資訊
dbms_stats.gather_table_stats(user,'table',cascade=>true);
DBMS_STATS包中用於收集統計資訊的過程包括:
dbms_stats.gather_table_stats 收集表、列和索引的統計資訊;
dbms_stats.gather_schema_stats 收集SCHEMA下所有物件的統計資訊;
dbms_stats.gather_index_stats 收集索引的統計資訊;
dbms_stats.gather_system_stats 收集系統統計資訊。
dbms_stats.delete_table_stats 刪除表的統計資訊
dbms_stats.export_table_stats 輸出表的統計資訊
dbms_stats.create_state_table
dbms_stats.set_table_stats 設定 表的統計
dbms_stats.auto_sample_size
dbms_stats.gather_database_stats: 收集資料庫中所有物件的統計資訊;
14.請寫出如何跟蹤某session執行的sql
exec dbms_system.set_sql_trace_in_session(sid,serial#,&sql_trace);
select sid,serial# from v$session where sid = (select sid from v$mystat where rownum = 1);
exec dbms_system.set_ev(&sid,&serial#,&event_10046,&level_12,'');
15.請寫出如何檢視當前資料庫在執行的事務
select * from v$transaction;
16.請寫出設定sga_target為10G的語句
alter system set sga_target=10240m
17.請寫出如何根據sqlid獲得該SQL是否使用繫結變數
select sql_id,sql_text,executions from v$sqlarea; 看executions的數量特別大說明沒有繫結變數
減產前40個字元相同, 有多於5個不同sql版本的sql語句
select substr(sqltext,1,40) sql_text,count(*) from v$sql group by substr(sqltext,1,40) having count(*) >= 5;
18.請寫出如何獲得某latch的sleep數量
select name,gets,misses,immediate_gets,immediate_misses,sleeps from v$latch;
19.請寫出如何根據作業系統程式號獲得oracle 會話號
select s.sid from v$session s,v$process p where p.addr=s.PADDR and p.spid='25783'
select sid from v$session where process='25817';
SQL語句殺掉長期沒有釋放非正常的鎖:
alter system kill session 'sid,serial#';
20.請寫出如何查詢當前資料庫日誌的切換時間
select archived,status,first_time from v$log;
Oracle概念類
1.請簡述oracle SGA中各記憶體區域的功能
buffer cache,log buffer,shared pool,big pool,java pool,streams pool
資料高速緩衝區(buffer cache):
用來儲存使用者最近從磁碟資料檔案訪問的資料塊的副本,這樣當再由使用者訪問相同的資料時,則可以直接從資料高速緩衝區讀取,不用再訪問磁碟(注:磁碟I/O的速率是毫米級的,而記憶體I/O的速率為納秒級)
包括三個型別區
髒的區(dirty buffer):用來儲存從磁碟資料檔案讀取來的、已經修改過、並且還沒有寫入磁碟資料檔案的資料。
自由區(free buffer):沒有任何資料,並且可以寫入資料的空閒記憶體區;
保留區(pinned buffer):用來儲存正在被使用,或者明確留作將來使用的資料,主要指,從磁碟資料檔案內讀取到、等待伺服器程式更改的資料,或者正在被更改的資料。
資料高速緩衝區可配置一個或2個或3個緩衝區池,我們在create或alter表或索引時,可以指定該表或索引屬於哪個緩衝區池;
保持緩衝區池(db_keep_cache_size):用來儲存一些需要頻繁訪問的小表,防止這些小表的資料被LRU命中;
回收緩衝區池(db_recycle_cache_size):用來儲存一些很少使用的大表,在緩區處理完之後,立即清除,節省快取空間;
預設緩衝區池(db_cache_size):用來儲存除db_keep_cache_size和db_recycle_cache_size之外的所有資料;
子快取記憶體(db_nk_cache_size):主要針對不同的oracle塊尺寸來設定的,
資料高速緩衝區尺寸=db_keep_cache_size+db_recycle_cache_size+db_cache_size+db_nk_cache_size;
重做日誌快取(log buffer):
用來儲存資料庫內的變更,由LGWR立即寫入聯機重做日誌檔案
共享池(shared_pool_size):
包括庫快取記憶體和資料字典高速緩衝兩部分
庫快取記憶體:主要用來儲存分析過的sql程式碼,所謂的“分析”是指,校驗使用者請求sql程式碼的語法,並且判斷sql程式碼涉及的表和欄位在資料庫內是否存在;
調優手段:透過動態檢視v$librarycache,判斷公式:sum(reloads)/sum(pins),如果結果約等於0,則證明庫快取記憶體命中率是合適的;如果結果>1,則需要增大共享池設定(shared_pool_size);
資料字典快取記憶體:主要用來儲存伺服器最近從磁碟資料字典內訪問過的資料,主要包括表結構、使用者、實體等資訊,如果再有使用者請求時,則伺服器程式會首先從資料字典快取記憶體內檢索,在緩衝區內是否存在該請求使用者的相關許可權資訊,如果沒有的話,需要訪問磁碟資料字典(注:訪問磁碟資料字典是最消耗資源的,相對於訪問其他磁碟檔案來說)
調優手段:透過動態檢視v$rowcache,判斷公式:(1-sum(getmisses)/(sum(getmiss)+sum(getmisses)))*100,如果結果>90,證明命中率是合適的,否則需要增大共享池設定;(注:oracle沒有直接設定庫高速緩衝和資料字典高速緩衝的地方,需要透過調整共享池尺寸實現)
大型池(large_pool_size):
主要為執行一些非常複雜並且耗時很長的sql程式碼提供空間,例如在執行備份操作時,需要存放備份緩衝區;
Java池(java_pool_size):
主要為例項化的Java物件提供的堆空間,如果資料庫中存在大量的java程式碼,就可以使用該設定,不用佔用常規的sga;
流池(streams_pool_size):
oracle支援流傳輸,主要用來實現與不同型別資料庫,或者在不同應用環境下的資料共享;
其他結構(包括資料控制和鎖的管理)
pga(程式全域性區):每個使用者會話都會在pga上佔用一段獨佔的記憶體空間,pga上從屬於該使用者會話的記憶體空間,只允許該使用者使用,其他使用者不能訪問。pga透過pga_size_mode可以設定自動或是手動記憶體配置。
2.如何檢視執行計劃,檢視執行計劃的作用是什麼
一、explain plan for select * from ......
select * from table(DBMS_XPLAN.Display)
二、set autotrace on;
SET AUTOTRACE OFF ---------------- 不生成AUTOTRACE 報告,這是預設模式
SET AUTOTRACE ON EXPLAIN ------ AUTOTRACE只顯示最佳化器執行路徑報告
SET AUTOTRACE ON STATISTICS -- 只顯示執行統計資訊
SET AUTOTRACE ON ----------------- 包含執行計劃和統計資訊
SET AUTOTRACE TRACEONLY ------ 同set autotrace on,但是不顯示查詢
三、SQL_TRACE
1.alter session set sql_trace=true;
2.執行sql
3.alter session set sql_trace=false;
4.檢視相應的sql trace檔案。
作用:
語句所引用表的順序;
語句所涉及的表的訪問方法;
語句中連線操作所影響到的各表的連線方法。
----各種表訪問方式需要明白
3.請寫出控制檔案的作用
作用:
二進位制檔案
記錄了資料庫當前例項的結構和行為,資料檔案日誌檔案的資訊,維護資料庫一致性
引數檔案中定義了控制檔案的位置和大小
很小的二進位制檔案,一般不超過100m
mount階段open以後,一直在用
一套控制檔案只能連線一個database
分散放置,至少一份,至多八份
control files作用:
引數檔案init.ora 記錄了控制檔案的位置,控制檔案是一個非常小的二進位制檔案,最大可以增長到64MB,控制檔案包括如下主要資訊:
·資料庫的名字,檢查點資訊,資料庫建立的時間戳
·所有的資料檔案,聯機日誌檔案,歸檔日誌檔案資訊
·備份資訊等
有了這些資訊,Oracle 就知道那些檔案是資料檔案,現在的重做日誌檔案是哪些,這些都是系統啟動和執行的基本條件,所以他是Oracle 執行的根本。如果沒有控制檔案系統是不可能啟動的。控制檔案是非常重要的,一般採用多個鏡相複製來保護控制檔案,或採用RAID 來保護控制檔案。控制檔案的丟失,將使資料庫的恢復變的很複雜。控制檔案資訊可以從V$Controlfile 中查詢獲得
一.控制檔案的作用
控制檔案記錄了物理資料庫的當前狀態。一般為3個,三個控制檔案都是一摸一樣的,最好是分開放在不同的磁碟上。
二.控制檔案的內容
2.1資料庫的名字;
資料庫的標示符:建立資料庫是oracle自動生成的;
資料庫建立的時間戳:它是在資料庫建立時生成的;
聯機重做日誌檔案的名字和準確位置;
當前日誌的學歷號:它是在日誌切換時oracle記錄的;
日誌的歷史資訊:它是在日誌切換時oracle記錄的;
歸檔日誌檔案的準確位置和狀態;
資料檔案的名字和準確位置;
表空間的資訊;
備份的準確位置和狀態;
三.新增和移動控制檔案
5.1在一個已經安裝的的oracle資料庫中使用正文初始化引數檔案(pfile)新增或者移動控制檔案的具體步驟。
a).利用資料字典v$controlfile來獲取現有的控制檔名字;
b).正常關閉資料庫,用命令shutdown或者shutdown immediate;
c).將新的控制檔名新增到引數檔案的control_files引數中;//區別
d).使用作業系統命令將現有的控制檔案複製到指定位置;
e).重新啟動資料庫,用命令startup;
f).利用資料字典v$controlfile來驗證新的控制檔名字是否正確;
g).如果有誤,重複上述操作;如果無誤,就刪除無用的舊的控制檔案;
5.2如果使用了伺服器初始化引數(spfile),步驟會有些區別。下面是具體步驟;
a).利用資料字典v$controlfile來獲取現有的控制檔名字;
b).修改spfile,使用alter system set control_files命令來改變控制檔案的位置;//區別
c).正常關閉資料庫,用命令shutdown或者shutdown immediate;
d).使用作業系統命令將現有的控制檔案複製到指定位置;
e).重新啟動資料庫,用命令startup;
f).利用資料字典v$controlfile來驗證新的控制檔名字是否正確;
g).如果有誤,重複上述操作;如果無誤,就刪除無用的舊的控制檔案;
相關檢視:
v$controlfile ---- 列出例項的所有控制檔案的名字和狀態
v$parameter ---- 列出所有引數的位置和狀態(where name='control_files')
v$controlfile_recode_section ---- 提供控制檔案的記錄部分的資訊
show parameter control_files ---- 列出控制檔案的名字、狀態和位置
檢視控制檔案內容:
strings $ORACLE_BASE/oradata/$ORACLE_SID/control01.ctl
alter database backup controlfile to trace as ''
轉儲控制檔案:
alter system set events 'immediate trace name controlf level 10'
level 1 塊頭
level 2 檔案內容
level 3 1+2
level 10 全部
管理控制檔案:
spfile 修改spfile引數control_files(alter……)
一致性關閉資料庫
增加或減少控制檔案
啟動資料庫使用spfile
驗證結果
pfile 一致性關閉資料庫
修改pfile引數
增加或減少控制檔案
啟動資料庫使用spfile
驗證結果
狀態查詢:引數和具體檔案是否對應、磁碟空間剩餘、控制檔案<100M
熱備控制檔案:
資料庫歸檔模式下,alter database backup controlfile to ''
其他模式下:alter database backup controlfile to trace as ''得到建立控制檔案指令碼
資料庫歸檔模式下rman備份:
rman target /
>backup current controlfile; or
>backup database include current controlfile;
rman自動備份控制檔案:
>show all中的configure controlfile autobackup設定為on
>configure controlfile autobackup on
問題解決:
控制檔案不一致:
1. 複製新版本的控制檔案到舊版本檔案
2. 修改引數檔案,只使用新版本的檔案(alter system set……),重啟
控制檔案丟失:
【mount階段,使用archive log list可以檢視資料庫是否在歸檔模式下】
1. 控制檔案無備份
a.資料庫非歸檔,資料檔案聯機日誌檔案存在 --- 重建控制檔案
>create controlfile reuse database noarchivelog noresetlogs datafile logfile
2. 控制檔案有備份
a.資料庫歸檔,資料檔案聯機和歸檔日誌檔案存在 --- 還原控制檔案
先全備,再將控制檔案複製到引數指定的路徑,然後>alter database recover database using backup controlfile until change;
4.請寫出SCN的作用
SCN是當Oracle資料庫更新後,由DBMS自動維護去累積遞增的一個數字。Oracle資料庫中一共有4種SCN分別為
系統檢查點SCN: 系統檢查點SCN位於控制檔案中,當檢查點程式啟動時(ckpt),Oracle就把系統檢查點的SCN儲存到控制檔案中。該SCN是全域性範圍的,當發生檔案級別的SCN時,例如將表空間置於只讀狀態,則不會更新系統檢查點SCN。
資料檔案檢查點scn:當ckpt程式啟動時,包括全域性範圍的(比如日誌切換)以及檔案級別的檢查點(將表空間置為只讀、begin backup或將某個資料檔案設定為offline等),這時會在控制檔案中記錄的scn。
結束scn:每個資料檔案都有一個結束scn,在資料庫的正常執行中,只要資料檔案線上且是可讀寫的,結束scn為null。否則則存在具體的scn值。結束scn也記錄在控制檔案中。
開始scn:不同於上述的SCN資料檔案開始scn記錄在每個資料檔案中。當發生系統及檔案級別的檢查點後,不僅將這時的SCN號記錄在控制檔案中,同樣也記錄在資料檔案中。
SCN的機制 資料庫執行時的SCN
Oracle事務
我們先看下oracle事務中的資料變化是如何寫入資料檔案的:
一、事務開始;
二、在buffer cache中找到需要的資料塊,如果沒有找到,則從資料檔案中載入buffer cache中;
三、事務修改buffer cache的資料塊,該資料被標識為“髒資料”,並被寫入log buffer中; ----這個“髒資料”是什麼程式寫入到log buffer中的
四、事務提交,LGWR程式將log buffer中的“髒資料”寫入redo log file中;
五、當發生checkpoint,CKPT程式更新所有資料檔案的檔案頭中的資訊,DBWr程式則負責將Buffer Cache中的髒資料寫入到資料檔案中。
5.請寫出log file sync等待事件的產生原因
①.高提交頻率
解決方法是簡單的消除不必要的提交,事務是工作單元。工作單元應該是全部成功或全部失敗。
②.緩慢的I/O子系統
較高的IO吞吐量可以改善log file sync和log file parallel write事件的平均等待時間。頻繁的提交會弄亂資料庫佈局和IO子系統。
解決辦法是將日誌檔案放裸裝置上或繫結在RAID 0或RAID 0+1中,而不是繫結在RAID 5中。
③.過大的日誌緩衝區
過大的日誌緩衝區也可能延長log file sync等待。大型的日誌緩衝區減少後臺寫入的數量,允許LGWR變得懶惰,並導致更多的重做條目堆積在日誌緩衝區中。同時可以調整引數_LOG_IO_SIZE引數,其預設值是LOG_BUFFER的1/3或1MB,取兩者之中較小的值。換句話說,你可以具有較大的日誌緩衝區,但較小的_LOG_IO_SIZE將增加後臺寫入,從而減少log file sync的等待時間。
Statspack之十四-"log file sync" 等待事件:
當一個使用者提交(commits)或者回滾(rollback),session的redo資訊需要寫出到redo logfile中.
使用者程式將通知LGWR執行寫出操作,LGWR完成任務以後會通知使用者程式.
這個等待事件就是指使用者程式等待LGWR的寫完成通知.
對於回滾操作,該事件記錄從使用者發出rollback命令到回滾完成的時間.
如果該等待過多,可能說明LGWR的寫出效率低下,或者系統提交過於頻繁.
針對該問題,可以關注:
log file parallel write等待事件
user commits,user rollback等統計資訊可以用於觀察提交或回滾次數
解決方案:
1.提高LGWR效能。儘量使用快速磁碟,不要把redo log file存放在raid 5的磁碟上
2.使用批次提交
3.適當使用NOLOGGING/UNRECOVERABLE等選項
6.請寫出同一條記錄insert,delete,update操作中產生undo資訊的大致內容
insert操作無論是1條或者多條,一次產生一條undo資料
delete操作產生的undo條數取決於delete操作本身影響的記錄數
update操作產生的undo條數取決於被update的資料的原值和新值存在差異的記錄數量
測試中表沒有主鍵,如果有主鍵,所有操作都會增加一條undo資料.在刪除或者update大量資料時候會產生大量undo,
所以建議這兩種操作進行分批提交.
select used_ublk,used_urec from v$session s, v$transaction t where s.audsid=sys_context('userenv', 'sessionid') and s.taddr = t.addr;
7.請寫出latch的工作原理
latch是一種輕量級用於保護oracle共享記憶體結構,使用者併發操作一致性的序列化鎖定機制,如SGA中,各種資料被反覆從磁碟讀取到記憶體,又被重新寫回到磁碟上,如果有併發使用者做相同的事情,oracle必須使用一種機制來保證資料在讀取的時候,只能由一個會話來完成,這就是latch,latch 不會造成阻塞,是隻會等待,與每個latch相聯絡的還有一個清除過程,當持有latch的程式成為死程式時,系統清除過程就會被呼叫,系統lock導致 使用者等待,需要考慮系統的邏輯設計是否有問題,如多使用者對主鍵的刪除或者修改,是否有使用者使用select… for update這樣的語法,外來鍵是否建立索引。latch 爭用多半要考慮系統及資料庫自身設計問題,如繫結變數,熱塊及引數設定是否合理。
spin:比如資料快取中的某個塊要被讀取,我們會獲得這個塊的 latch,這個過程叫做spin,另外一個程式恰好要修改這個塊,他也要spin這個塊,此時他必須等待,當前一個程式釋放latch後才能spin 住,然後修改,如果多個程式同時請求的話,他們之間將出現競爭,沒有一個入隊機制,一旦前面程式釋放鎖定,後面的程式就蜂擁而上,沒有先來後到的概念,並且這一切都發生的非常快,因為Latch的特點是快而短暫。
spin與休眠:
休眠意味著暫時的放棄CPU,進行上下文切換(context switch),這樣CPU要儲存當前程式執行時的一些狀態資訊,比如堆疊,訊號量等資料結構,然後引入後續程式的狀態資訊,處理完後再切換回原來的程式狀態,這個過程如果頻繁的發生在一個高事務,高併發程式的處理系統裡面,將是個很昂貴的資源消耗,所以Oracle選擇了spin,讓程式繼續佔有 CPU,執行一些空指令,之後繼續請求,繼續spin,直到達到_spin_count值,這時會放棄CPU,進行短暫的休眠,再繼續剛才的動作。
oracle中,latch是一種輕量級的鎖。一般來說,latch由三種記憶體元素成:pid(程式id),記憶體地址和記憶體長度。Latch保證對共享資料結構的排它性訪問,以此來保證記憶體結構的完整性不受到損壞。在多個會話同時修改或者檢視(inspect)sga中同一個記憶體結構時,必須序列化訪問以保證sga中資料結構的完整性。
程式獲取latch有兩種模式:willing-to-wait和No_wait。no-wait模式只在少數latch中使用。透過no-wait模式 獲取latch的統計資訊記錄在immediate_gets immediate_misses列中,這些列在v$latch,v$latch_parent,v$latch_children檢視中都存在。一般來 說,no-wait模式在第一次獲取一些有很多子latch的latch比如redo copy時使用。如果一個程式第一次獲取這些子latch中的任何一個失敗,它會立即使用no-wait模式詢問下一個。只有當採用no-wait模式試圖獲取所有的子latch都失敗以後,才會轉而採用willing-to-wait模式。
透過willing-to-wait模式獲取latch的統計資訊存放在gets和misses列中。每當一個程式用willing-to-wait模式去獲取一個latch時,gets都會增加。
如果程式在第一次請求latch時,latch可用,就會直接獲得該latch。在修改任何受到保護的資料結構之前,程式會將一些恢復資訊寫入到latch恢復區,這樣當獲得latch的程式發生異常時,pmon程式才能夠清理該程式持有的latch。
如果請求latch時,該latch不可用,程式就會在cpu中等待一小段時間(spin)然後重新請求latch。如果latch一直不可用,該過程(spin一段時間然後重新請求)會一直重複。重複的次數由隱含引數_spin_count決定,預設值2000。如果在請_spin_count次之內 獲得了latch,就對spin_gets和misses列各加一,否則,程式v$session_wait中記錄latch free等待事件,然後釋放cpu,轉入睡眠狀態。睡眠一定時間後,程式被喚醒並重覆上面的過程,一直到獲得latch。在成功獲得latch後,才會更行sleep列得統計資訊。
由於程式只有在獲得latch後才會停止對latch得請求,如果某個持有latch的程式發生異常,其他請求該latch的程式該怎麼辦?豈不是要一直等待下去?不會的。當一個程式請求latch失敗一定次數後,它會請求pmon程式檢視該latch的持有者,如果持有程式異常,pmon就會清理該程式,釋放latch。
每個latch都有一個從0到13的優先順序編號。父latch和獨立latch的優先順序編號是在oracle核心程式碼中固定的。子latch是在例項啟動時建立,其優先順序編號從其父latch繼承。使用優先順序可以避免死鎖。
當一個程式請求no-wait模式的latch時,該latch的優先順序編號必須和它當前已經持有的latch的優先順序編號相同。
當一個程式請求willing-to-wait模式的latch時,該latch的優先順序編號必須比它當前已經持有的latch的優先順序編號要大。
程式獲取Latch的過程:
任何時候,只有一個程式可以訪問記憶體中的某一個資料塊,如果程式因為別的程式正佔用塊而無法獲得Latch時,他會對CPU進行一次spin(旋轉),時間非常的短暫,spin過後繼續獲取,不成功仍然spin,直到 spin次數到達閥值限制(這個由隱含引數_spin_count指定),此時程式會停止spin,進行短期的休眠,休眠過後會繼續剛才的動作,直到獲取塊上的Latch為止。程式休眠的時間也是存在演算法的,他會隨著spin次數而遞增,以釐秒為單位,休眠的閥值限制由隱含引數 _max_exponential_sleep控制,預設是2秒,如果當前程式已經佔用了別的Latch,則他的休眠時間不會太長(過長會引起別的程式的 Latch等待),此時的休眠最大時間有隱含引數_max_sleep_holding_latch決定,預設是4釐秒。這種時間限制的休眠又稱為短期等待。另外一種情況是長期等待鎖存器(Latch Wait Posting),此時等待程式請求Latch不成功,進入休眠,他會向鎖存器等待連結串列(Latch Wait List)壓入一條訊號,表示獲取Latch的請求,當佔用程式釋放Latch時會檢查Latch Wait List,向請求的程式傳遞一個訊號,啟用休眠的程式。Latch Wait List是在SGA區維護的一個程式列表,他也需要Latch來保證其正常執行,預設情況下share pool latch和library cache latch是採用這個機制。
如果將隱含引數_latch_wait_posting設定為2,則所有Latch都採用這種等待方式,使用這種方式能夠比較精確的喚醒某個等待的程式, 但維護Latch Wait List需要系統資源,並且對Latch Wait List上Latch的競爭也可能出現瓶頸。
資料緩衝池Latch爭用
訪問頻率非常高的資料塊被稱為熱快(Hot Block),當很多使用者一起去訪問某幾個資料塊時,就會導致一些Latch爭用,最常見的latch爭用有:
(1) buffer busy waits
(2) cache buffer chain
Cache buffer chian產生原因:
當一個會話需要去訪問一個記憶體塊時,它首先要去一個像連結串列一樣的結構中去搜尋這個資料塊是否在記憶體中,當會話訪問這個連結串列的時候需要獲得一個Latch,如果獲取失敗,將會產生Latch cache buffer chain 等待,導致這個等待的原因是訪問相同的資料塊的會話太多或者這個列表太長(如果讀到記憶體中的資料太多,需要管理資料塊的hash列表就會很長,這樣會話掃描列表的時間就會增加,持有chache buffer chain latch的時間就會變長,其他會話獲得這個Latch的機會就會降低,等待就會增加)。
Buffer busy waits 產生原因:
當一個會話需要訪問一個資料塊,而這個資料塊正在被另一個使用者從磁碟讀取到記憶體中或者這個資料塊正在被另一個會話修改時,當前的會話就需要等待,就會產生一個buffer busy waits等待。
產生這些Latch爭用的直接原因是太多的會話去訪問相同的資料塊導致熱塊問題,造成熱塊的原因可能是資料庫設定導致或者重複執行的SQL頻繁訪問一些相同的資料塊導致。
latch有40餘種,但作為DBA關心的主要應有以下幾種:
Cache buffers chains latch: 當使用者程式搜尋SGA尋找database cache buffers時需要使用此latch。
Cache buffers LRU chain latch: 當使用者程式要搜尋buffer cache中包括所有 dirty blocks的LRU (least recently used) 鏈時使用該種latch。
Redo log buffer latch: 這種latch控制redo log buffer中每條redo entries的空間分配。
Row cache objects latch: 當使用者程式訪問快取的資料字典數值時,將使用Row cache objects latch。
下 面我們將著重介紹一下如何檢測和減少redo log buffer latch的衝突。對redo log buffer的訪問是由redo log buffer latch來控制的,這種latch有兩種型別, redo allocation latch和redo copy latch。
Redo allocation latch控制redo entries在redo log buffer中的空間分配。Oracle的一個使用者程式只有得到redo allocation latch後才能為redo entries在redo log buffer中分配空間,又由於一個instance只有一個redo allocation latch,所以一次只有一個使用者程式在buffer中分配空間。當使用者程式獲得latch後,首先為redo entry分配空間,然後程式繼續持有latch並複製entry到buffer中,這種複製稱為“在redo allocation latch上的複製”(copying on the redo allocation latch),複製完畢後,使用者程式釋放該latch。
一個“在redo allocation latch上的複製”的redo entry的最大值是由初始化引數LOG_SMALL_ENTRY_MAX_SIZE定義的,根據作業系統的不同而不同。
Redo Copy Latch只應用於多CPU的系統。在多CPU的instance中,如果一個redo entry太大,超過了LOG_SMALL_ENTRY_MAX_SIZE定義值,則不能進行“在redo allocation latch上的複製”, 此時使用者程式必須獲取redo copy latch。一個instance中可以有多個redo copy latch,其數目由初始引數LOG_SIMULTANEOUS_COPIES決定,預設值為CPU數目。
在單CPU情況下,不存在redo copy latch,所有的redo entry無論大小, 都進行“在redo allocation latch上的複製”。
對redo log buffer的過多訪問將導致redo log buffer latch的衝突,latch衝突將降低系統效能,我們可透過如下查詢來檢測這種latch衝突:
col name for a40
SELECT ln.name,gets,misses,immediate_gets,immediate_misses
FROM v$latch l,v$latchname ln
WHERE ln.name IN('redo allocation','redo copy') AND ln.latch#=l.latch#
/
若misses與gets的比例超過1%或immediate_misses與(immediate_gets+immediate_misses)比例超過1%時,應考慮採取措施減少latch的衝突。
大 多數的redo log buffer latch衝突是在多個CPU情況下,兩個或多個Oracle程式試圖同時得到相同的latch發生的。由於一個instance只有一個redo allocation latch,為減少redo allocation latch的衝突,應減少單個程式持有latch的時間,這可以透過減小初始引數LOG_SMALL_ENTRY_MAX_SIZE以減小redo entry的數目和大小來實現。如果觀察到有redo copy latch衝突,可以透過增大LOG_SIMULTANEOUS_COPIES 初始引數來加大latch數目,其預設值為CPU數目,最大可增大到CPU數目的兩倍。
8.請寫出rownum與rowid的區別
rownum只是你查詢出來結果集的一個臨時排列序號,必須從1開始,可以看作是隨便可以變化的!
rowid是對於每一條資料的地址,你可以把它看作是固定的(頻繁更新,刪除操作除外)
當你從某個表中查詢資料的時候,返回的結果集中都會帶有rownum這個欄位,而且有時候也可以使用rownum進行一些條件查詢。
rownum是在得到結果集的時候產生的,用於標記結果集中結果順序的一個欄位,這個欄位被稱為“偽數列”,也就是事實上不存在的一個數列。它的特點是按順序標記,而且是逐次遞加的,換句話說就是隻有有rownum=1的記錄,才可能有rownum=2的記錄。
和rownum相似,oracle還提供了另外一個偽數列:rowid。不過rowid和rownum不同,一般說來每一行資料對應的rowid是固定而且唯一的,在這一行資料存入資料庫的時候就確定了。可以利用rowid來查詢記錄,而且透過rowid查詢記錄是查詢速度最快的查詢方法。(這個我沒有試過,另外要記住一個長度在18位,而且沒有太明顯規律的字串是一個很困難的事情,所以我個人認為利用rowid查詢記錄的實用性不是很大)rowid只有在表發生移動(比如表空間變化,資料匯入/匯出以後),才會發生變化。
1、ROWNUM
定義: ROWNUM是一個偽列,標識了select從一個表或一組連線(JOIN)的表中查詢資料時,返回記錄的順序。
Oracle在執行select查詢時,會按照返回的row的順序,依次為row分配一個序號:
返回的第一條row的序號為1,第二條row的序號為2,以此類推。
這個序號即為每條row的rownum。
注意1:同一個查詢語句中,如果ROWNUM後,含有ORDER BY子句時:
Oracle先返回未應用ORDER BY處理的結果,分配ROWNUM後,再根據ORDER BY子句的要求排序。
因此,返回的結果中,ROWNUM順序是混亂的。如:
SQL> SELECT ROWNUM,DEPT.* FROM SCOTT.DEPT ORDER BY DNAME;
ROWNUM DEPTNO DNAME LOC
-------------- ------------- -------------------- -------------
1 10 ACCOUNTING NEW YORK
4 40 OPERATIONS BOSTON
2 20 RESEARCH DALLAS
3 30 SALES CHICAGO
未應用ORDER BY的結果為:
SQL> SELECT ROWNUM,DEPT.* FROM SCOTT.DEPT;
ROWNUM DEPTNO DNAME LOC
-------------- ------------- ---------------------- -------------
1 10 ACCOUNTING NEW YORK
2 20 RESEARCH DALLAS
3 30 SALES CHICAGO
4 40 OPERATIONS BOSTON
欲使ORDER BY後的ROWNUM連續,可將ORDER BY放入子查詢,如:
SQL> SELECT ROWNUM,T.* FROM (SELECT DEPT.* FROM SCOTT.DEPT ORDER BY LOC) T;
ROWNUM DEPTNO DNAME LOC
-------------- ------------- --------------------- -------------
1 40 OPERATIONS BOSTON
2 30 SALES CHICAGO
3 20 RESEARCH DALLAS
4 10 ACCOUNTING NEW YORK
注意2:對ROWNUM應用>,>=,=,between...and條件,返回結果都為空:
因為,當返回第一條記錄,作為結果的第1條,分配rownum=1,
應用>,>=,=,between...and條件判斷時,不滿足條件,記錄刪除;
返回下一條記錄時,仍作為結果的第1條,分配rownum=1,仍不滿足條件,依次類推,結果為空。
select rownum from test where rownum=1; //返回1條記錄(結果集中的第一條)
select rownum from test where rownum=2;
//返回0條。根據ROWNUM定義,不難看出,返回第1條記錄時,因ROWNUM=1,因此過濾掉。
select rownum from test where rownum>10;
select rownum from test where rownum between 2 and 4;
應用:
1)可透過ROWNUM限制返回結果的記錄數(行數)
SQL> select rownum from test where rownum<10;
2)透過ROWNUM為表中某列產生一個唯一(UNIQUE)值
SQL> UPDATE table_name SET column_name = ROWNUM;
//將rownum指定為該行某列的值。
二、ROWID
(一)、概念:行的ROWID標識了該行資料的地址,ROWID包含如下資訊:
資料物件編號、
該行資料,在資料檔案中的塊編號
該行在資料塊中的位置(第一行為0)
儲存該行資料的資料檔案的編號(第一個資料檔案為1)
ROWID在插入資料時建立,在刪除資料時,刪除。
不能手動設定或刪除ROWID,ORACLE內部透過ROWID組建索引;
(二)、型別
1、物理ROWID:儲存普通表(不含索引組織的表IOT)、聚合表(clustered table)、分割槽和子分割槽表、索引、分割槽和子分割槽索引中行的地址;
2、邏輯ROWID:儲存索引組織表(IOT)的地址;
(三)、物理ROWID
1、型別:物理ROWID包含擴充套件ROWID與受限ROWID兩類
1)、擴充套件ROWID(extended rowid)
支援表空間關聯的資料塊地址,有效標識分割槽表、分割槽索引以及普通表和索引中的行。
Oracle 8i及更高版本支援extended rowid。
2)、受限ROWID(restricted rowid)
為了向後相容,如oracle 7及更低版本。
2、擴充套件ROWID(extended rowid)
a.擴充套件ROWID使用base64為每一行資料的實體地址進行編碼,包含A-Z,a-z,0-9,+以及/。如下查詢:
SQL> select rowid,dept.* from dept;
ROWID DEPTNO DNAME LOC
-------------------------------- ------------ -------------------- ----------------
AAAMfKAAEAAAAAQAAA 10 ACCOUNTING NEW YORK
AAAMfKAAEAAAAAQAAB 20 RESEARCH DALLAS
AAAMfKAAEAAAAAQAAC 30 SALES CHICAGO
AAAMfKAAEAAAAAQAAD 40 OPERATIONS BOSTON
b.擴充套件ROWID格式
擴充套件ROWID共18位,包含4部分,OOOOOOFFFBBBBBBRRR
a)000000:資料物件編號,標識了資料庫中的段;
b)FFF:表空間相關的資料檔案編號;
c)BBBBBB:資料檔案中的資料塊編號;
d)RRR:在資料塊中的行編號;
c.DBMS_ROWID包
a)dbms_rowid.rowid_object透過ROWID,獲取該資料的物件編號
SQL> select dbms_rowid.rowid_object('AAAMfKAAEAAAAAQAAC') as object_id from dual;
OBJECT_ID
----------------
51146
b)dbms_rowid.rowid_relative_fno透過ROWID獲取資料檔案編號
SQL> select dbms_rowid.rowid_relative_fno('AAAMfKAAEAAAAAQAAC') as file_no from dual;
FILE_NO
-------------
4
c)dbms_rowid.rowid_block_number透過ROWID,獲取該資料的資料塊編號
SQL> select dbms_rowid.rowid_block_number('AAAMfKAAEAAAAAQAAC') as block_number from dual;
BLOCK_NUMBER
------------------------
16
d)dbms_rowid.rowid_row_number透過ROWID,獲取資料塊中的行編號
SQL> select dbms_rowid.rowid_row_number('AAAMfKAAEAAAAAQAAC') as row_no from dual;
ROW_NO
----------
2
3、受限ROWID(resticted rowid)
a.受限rowid用二進位制表示每行資料的實體地址,當使用SQL Plus查詢時,二進位制表示法被轉換為varchar2或16進製表示。
SQL> select dbms_rowid.rowid_to_restricted(rowid,1) as restricted_rowid,dept.* from scott.dept;
RESTRICTED_ROWID DEPTNO DNAME LOC
------------------------------- ------------- --------------------- ------------------
00000010.0000.0004 10 ACCOUNTING NEW YORK
00000010.0001.0004 20 RESEARCH DALLAS
00000010.0002.0004 30 SALES CHICAGO
00000010.0003.0004 40 OPERATIONS BOSTON
b.受限rowid格式:
共16位,包含3部分:AAAAAAAA.BBBB.CCCC
a)AAAAAAAA:儲存該行資料的資料塊編號
b)BBBB:該行資料在資料塊中的行編號
c)CCCC:包含該行資料的資料檔案編號
(四)、邏輯ROWID(logical rowid)
1、概述:索引組織的表(IOT)中,row儲存在索引的葉子節點,可以在塊內或塊間移動。
因此,這些rows沒有固定的實體地址,無法根據實體地址來唯一標識。
Oracle提供了邏輯ROWID,來標識IOT中的行,邏輯ROWID是基於表的主鍵;
Oracle可根據這些邏輯ROWID為IOT建立第二索引。
每個第二索引使用的邏輯ROWID都包含一個physical guess;physical guess標識了當建立第二索引時,IOT中每個row的塊位置;
9.請寫出丟失非當前重做日誌時應如何處理
Oracle的重做日誌檔案(Online redo logfile)迴圈記錄了資料庫所有的事務。它的大小、個數和儲存位置對資料庫效能和恢復有重要影響。它一般由大小相同的幾組檔案構成。我們可以檢視資料庫檢視v$logfile知道redo logfile的個數和儲存位置。對每一個Oracle資料庫都要求至少具有兩個聯機重做日誌。
每一次新的事務提交時,Oracle將該事務寫入日誌檔案,但並非此時也將修改的資料塊寫回原資料檔案。由於記憶體讀寫和磁碟I/O存在幾個數量級的效率差別,Oracle透過減少資料檔案的物理I/O讀寫來大大提高資料庫的效能;同時,又透過優先寫日誌檔案來保證資料的正確性和一致性。基於這種機制,重做日誌檔案在資料庫的例項恢復和介質恢復時至關重要,是oracle資料庫最重要的物理檔案之一。
如果資料庫在啟動時檢測到重做日誌丟失,資料庫將無法啟動。如果資料庫在執行時切換日誌檔案組,檢測到下一組或者全部的重做日誌丟失,資料庫將會崩潰。由於磁碟介質損壞或者人為的誤刪除檔案,造成嚴重後果的事件近期時有發生。本文列舉了重做日誌丟失的資料庫恢復,但如果按照冗餘原則合理分佈日誌檔案組的成員,如果工程師瞭解日誌檔案的基本原理和使用原則,就完全可以避免出現下列問題。
恢復方法
故障現象
SQL> startup mount
Oracle Instance Started
Database mounted
ORA-00313: open failed for members of log group 1 of thread 1
ORA-00312: online log 1 thread 1: '/ORACLE/ORADATA/H817/REDO01.LOG'
ORA-27041: unable to open file
OSD-04002: unable to open file
O/S-Error: (OS 2) The system cannot find the file specified.
恢復注意事項
以下所列舉的恢復方法,都屬於不完全恢復或者強制恢復,會丟失當前重做日誌中的事務資料。一旦操作不當,將帶來資料丟失等嚴重後果,請遵循以下幾個恢復原則:
1.請勿在生產系統上試用。
2.如果生產系統出現重做日誌檔案丟失的故障,請勿自行操作破壞現場,應該立刻聯絡Oracle工程師。
3.恢復成功之後,需要馬上做一次資料庫的全備份。
4.建議重做日誌檔案一定要實現鏡象在不同的磁碟上,避免這種情況的發生。
恢復方法
1.首先檢查重做日誌檔案狀態,看看報錯的日誌檔案的狀態是否為Current
SQL> select * from v$log;
SQL> select * from v$logfile;
2.如果重做日誌檔案狀態為Inactive,我們可以直接清除該日誌檔案的內容:
SQL> alter database clear logfile '/ORACLE/ORADATA/H817/REDO01.LOG';
3.如果重做日誌檔案狀態為Current,恢復工作較為複雜,有以下四種情況:
1)透過下面步驟,資料庫順利開啟
SQL> recover database until cancel;
Type Cancel when prompted
SQL>alter database open resetlogs;
2)第一種情況的'recover database until cancel' 操作遇到ORA-01547,ORA-01194,ORA-01110錯誤,需要整個資料庫的物理備份,並根據歸檔日誌恢復到錯誤時間點,前提是資料庫是歸檔模式。
restore old backup
SQL> startup mount
SQL> recover database until cancel using backup controlfile;
SQL> alter database open resetlogs;
3)如果資料庫是非歸檔模式,只能恢復整個物理備份,然後直接開啟資料庫。這種情況將丟失物理備份至故障發生前的全部資料。
4)如果資料庫是非歸檔模式,且沒有物理備份,只能透過特殊的隱含引數,允許資料庫不一致的狀況下開啟資料庫。這種恢復方法是沒有辦法之後的恢復方法,將導致資料庫不一致,一般情況下不要採用。如確有需要,請在Oracle的技術人員指導下使用該方法。
l 關閉資料庫
SQL>shutdown immediate
l 在init.ora中加入如下引數
_allow_resetlogs_corruption=TRUE
l 重新啟動資料庫,利用until cancel恢復
SQL>recover database until cancel;
Cancel
l 開啟資料庫
SQL>alter database open resetlogs;
l 資料庫被開啟後,馬上執行一個全庫匯出。
關閉資料庫,在init.ora中去掉_all_resetlogs_corrupt引數
10.請寫出引數檔案的作用
下面是是我對引數檔案的一點總結
分為二類:
1.初始引數檔案:pfile(initialization parameter file)
2.伺服器引數檔案:spfile(server-side parameter file)
主要的區別是:
1.pfile是文字檔案,spfile是二進位制檔案
2.pfile可以透過文字編輯器修改,spfile主要是透過alter system set parameter=value [scope=memory|spfile|both]修改
oracle啟動時,讀取引數檔案的順序是:
1.spfile$ORACLE_SID.ORA(建立資料庫時建立的spfile)
2.spfile.ora(oracle預設spfile檔案)
3.init$ORACLE_SID.ora(建立資料庫時建立的pfile)
4.init.ora(oracle預設pfile檔案)
oracle會按順序讀出這些引數檔案,如果在1沒有找到就去找2,直到找到。
和引數檔案相關常用SQL如下:
1.檢視當前使用的spfile和pfile的位置:
show parameter spfile/show parameter pfile
2.檢視引數檔案的具體設定
show parameters
3.從spfile獲取pfile
create pfile='pfilesid.ora' from spfile或者
create pfile='pfilesid.ora' from spfile='/$ORACLE_HOME/dbs/spfile.ora'
4.修改引數
alter system set parameter=value [scope=memory|spfile|both]
1.修改後當前就起作用,重啟資料庫不起作用
scope=memory
2.修改後當前不起作用,下次重啟資料庫才起作用
scope=spfile
3.修改後當前起作用,下次重啟資料庫也起作用
scope=both
Notice:命令alter system set parameter=value在沒有加scope選項時,預設值是什麼呢?多數朋友可能不加思索就會回答both這答案,實際的情況是,當oracle在以spfile引數啟動時,預設值是both,而以pfile啟動時,預設值是memory,也就是隻修改當前值。所以如果不能確定啟動的引數檔案,可以用show parameter spfile檢視。
5.指定初始引數檔案啟動資料庫
startup pfile='/$ORACLE_HOME/dbs/init$ORACLE_SID.ora'
不能以指定伺服器引數檔案spfile來啟動資料庫
可以先將spfile轉換成pfile,再用這個命令來達到目的
6.檢視系統是以pfile還是spfile啟動
show parameter spfile
如果是null值,就是pfile啟動的
11.請寫出event 10053的作用是什麼
藉助Oracle的10053事件event,我們可以監控到CBO對SQL進行成本計算和路徑選擇的過程和方法。
10053事件有兩個級別:
Level 2:2級是1級的一個子集,它包含以下內容:
Column statistics
Single Access Paths
Join Costs
Table Joins Considered
Join Methods Considered (NL/MS/HA)
Level 1: 1級比2級更詳細,它包含2級的所有內容,在加如下內容:
Parameters used by the optimizer
Index statistics
啟用10053事件
ALTER SESSION SET EVENTS '10053 trace name context forever, level 1';
ALTER SESSION SET EVENTS '10053 trace name context forever, level 2';
關閉10053事件:
ALTER SESSION SET EVENTS '10053 trace name context off';
說明:
1、sqlplus中開啟autotrace看到的執行計劃實際上是用explain plan 命令得到的,explain plan 命令不會進行bind peeking。
應該透過v$sql_plan檢視SQL的真實的執行計劃。
2、10053只對CBO有效,而且如果一個sql語句已經解析過,就不會產生新的trace資訊。
3、10053事件產生的trace檔案不能用tkprof格式化。
12.請寫出hash join 與nest loop的實現原理
nest loop:多用於聯機業務 OLTP (exists)
巢狀迴圈連線的工作方式是這樣的:
1、 Oracle首先選擇一張表作為連線的驅動表,這張表也稱為外部表(Outer Table)。由驅動表進行驅動連線的表或資料來源稱為內部表(Inner Table)。
2、 提取驅動表中符合條件的記錄,與被驅動表的連線列進行關聯查詢符合條件的記錄。在這個過程中,Oracle首先提取驅動表中符合條件的第一條記錄,再與內部表的連線列進行關聯查詢相應的記錄行。在關聯查詢的過程中,Oracle會持續提取驅動表中其他符合條件的記錄與內部表關聯查詢。這兩個過程是並行進行的,因此巢狀迴圈連線返回前幾條記錄的速度是非常快的。在這裡需要說明的是,由於Oracle最小的IO單位為單個資料塊,因此在這個過程中Oracle會首先提取驅動表中符合條件的單個資料塊中的所有行,再與內部表進行關聯連線查詢的,然後提取下一個資料塊中的記錄持續地迴圈連線下去。當然,如果單行記錄跨越多個資料塊的話,就是一次單條記錄進行關聯查詢的。
Hash join:多用於批處理業務 (in)
一般用於一張小表和一張大表進行join時。Hash join的過程大致如下(下面所說的記憶體就指sort area,關於過程,後面會作詳細討論):
1.一張小表被hash在記憶體中。因為資料量小,所以這張小表的大多數資料已經駐入在記憶體中,剩下的少量資料被放置在臨時表空間中;
2.每讀取大表的一條記錄,就和小表中記憶體中的資料進行比較,如果符合,則立即輸出資料(也就是說沒有讀取臨時表空間中的小表的資料)。而如果大表的資料與小表中臨時表空間的資料相符合,則不直接輸出,而是也被儲存臨時表空間中。
3.當大表的所有資料都讀取完畢,將臨時表空間中的資料以其輸出。
如果小表的資料量足夠小(小於hash area size),那所有資料就都在記憶體中了,可以避免對臨時表空間的讀寫。
如果是並行環境下,前面中的第2步就變成如下了:
2.每讀取一條大表的記錄,和記憶體中小表的資料比較,如果符合先做join,而不直接輸出,直到整張大表資料讀取完畢。如果記憶體足夠,Join好的資料就儲存在記憶體中。否則,就儲存在臨時表空間中。
NESTED LOOP
對於被連線的資料子集較小的情況,nested loop連線是個較好的選擇。nested loop就是掃描一個表,每讀到一條記錄,就根據索引去另一個表裡面查詢,沒有索引一般就不會是 nested loops。
一般在nested loop中, 驅動表滿足條件結果集不大,被驅動表的連線欄位要有索引,這樣就走nestedloop。如果驅動表返回記錄太多,就不適合nested loops了。如果連線欄位沒有索引,則適合走hash join,因為不需要索引。
可用ordered提示來改變CBO預設的驅動表,可用USE_NL(table_name1 table_name2)提示來強制使用nested loop。
HASH JOIN
hash join是CBO 做大資料集連線時的常用方式。最佳化器掃描小表(或資料來源),利用連線鍵(也就是根據連線欄位計算hash 值)在記憶體中建立hash表,然後掃描大表,每讀到一條記錄就來探測hash表一次,找出與hash表匹配的行。
當小表可以全部放入記憶體中,其成本接近全表掃描兩個表的成本之和。如果表很大不能完全放入記憶體,這時最佳化器會將它分割成若干不同的分割槽,不能放入記憶體的部分就把該分割槽寫入磁碟的臨時段,此時要有較大的臨時段從而儘量提高I/O 的效能。臨時段中的分割槽都需要換進記憶體做hash join。這時候成本接近於全表掃描小表+分割槽數*全表掃描大表的代價和。
至於兩個表都進行分割槽,其好處是可以使用parallel query,就是多個程式同時對不同的分割槽進行join,然後再合併。但是複雜。
使用hash join時,HASH_AREA_SIZE初始化引數必須足夠的大,如果是9i,Oracle建議使用SQL工作區自動管理,設定WORKAREA_SIZE_POLICY 為AUTO,然後調整PGA_AGGREGATE_TARGET即可。
以下條件下hash join可能有優勢:
兩個巨大的表之間的連線。
在一個巨大的表和一個小表之間的連線。
可用ordered提示來改變CBO預設的驅動表,可用USE_HASH(table_name1 table_name2)提示來強制使用hash join。
SORT MERGE JOIN
sort merge join的操作通常分三步:對連線的每個表做table access full;對table access full的結果進行排序;進行merge join對排序結果進行合併。sort merge join效能開銷幾乎都在前兩步。一般是在沒有索引的情況下,9i開始已經很少出現了,因為其排序成本高,大多為hash join替代了。
通常情況下hash join的效果都比sort merge join要好,然而如果行源已經被排過序,在執行sort merge join時不需要再排序了,這時sort merge join的效能會優於hash join。
在全表掃描比索引範圍掃描再透過rowid進行表訪問更可取的情況下,sort merge join會比nested loops效能更佳。
可用USE_MERGE(table_name1 table_name2)提示強制使用sort merge join。
13.請描述行連線與行遷移的原理
有兩種情況會導致表中某行資料過大,一個資料塊(data block)無法容納。
行連結:當一行資料被插入時一個資料塊就無法容納。在這種情況下Oracle將這行資料儲存在段內的一個資料塊鏈(chain)中。在插入資料量大的行時常會發生行連結(row chaining),例如一個包含資料型別為 LONG 或 LONG RAW 列的資料行。此時行連結不可避免。
行遷移:原本儲存在一個資料塊(data block)內的資料行,因為更新操作導致長度增長,而所在資料塊的可用空間也不能容納增長後的資料行。在這種情況下,Oracle將此行資料遷移(migrate)到新的資料塊中。Oracle在被遷移資料行原來所在位置儲存一個指向新資料塊的指標。被遷移資料行的 rowid 保持不變。
當資料行發生連結(chain)或遷移(migrate)時,對其訪問將會造成 I/O 效能降低,因為Oracle為獲取這些資料行的資料時,必須訪問更多的資料塊(data block)。
14.請寫出pctfree及pctused的作用
PCTFREE 引數用來設定一個資料塊(data block)中至少需要保留(reserve)多少可用空間(百分比值),為資料塊中已有資料更新時可能發生的資料量增長做準備。例如,當使用者用 CREATE TABLE 語句建立表時指定了以下引數:PCTFREE 20
這個引數設定了此表對應的資料段(data segment)中的每個資料塊(data block)至少保留20%的可用空間,以備塊中已有資料更新時使用。只要資料塊中行資料區與資料塊頭的容量之和不超過資料塊總容量的80%,使用者就可以向其中插入新資料,資料行被放入行資料區(row data area),相關資訊被寫入資料塊頭(overhead area)。
PCTUSED 引數用於決定一個資料塊(data block)是否可被用於插入新資料,她的依據是資料區(row data)與資料塊頭(overhead)的容量之和佔資料塊全部容量的最大百分比。當一個資料塊中的可用空間比例小於 PCTFREE 引數的規定時,Oracle就認為此資料塊無法被用於插入新資料,直到資料塊中的佔用容量比例小於 PCTUSED 引數的限定。在佔用容量比例大於 PCTUSED 引數的限定之前,Oracle只在更新資料塊內已有資料時才會使用此資料塊的可用空間。例如,當使用者用 CREATE TABLE 語句建立表時指定了以下引數:PCTUSED 40
在例子中,當此表的某資料塊佔用容量比例高於40%時,Oracle不會將此資料塊用於插入新資料行(假設此資料塊的可用空間曾經低於 PCTFREE 的限定)。
15.請寫出分割槽表的作用
分割槽表的作用:提高查詢速度(查詢資料的時候不會再對錶進行全部掃描,而掃描相應的分割槽表),在表進行分割槽之後,邏輯上還是一張表,實際上已經把插入的資料分到了各個分割槽表中,資料物理的分到不同的分割槽表中。當一個分割槽損壞後,不影響其他分割槽中的資料。
分割槽表的型別:1)按範圍進行分割槽2)列表分割槽3)雜湊分割槽4)範圍列表組合5)範圍散弄組合。
分割槽技術能夠帶來以下好處:
1)利用分割槽技術,使用者可以在分割槽級(partition level)進行資料載入(data load),索引建立及重建,或備份恢復等資料管理操作,而非針對整個表執行。這大大減少了此類操作所需時間。
2)分割槽技術能夠提高查詢效能。在很多情況下,查詢的結果集可能來自幾個分割槽,而非整個表。 對於某些查詢,這種技術(稱為分割槽剪除(partition pruning))能夠帶來幾個資料量級的效能提升。
3)分割槽技術能夠顯著縮短維護操作導致的停機時間。
4)由於對各分割槽的維護操作可以相互獨立地進行,使用者可以同時對錶或索引的不同分割槽進行維護操作。使用者還能在維護的同時對未受維護操作影響的分割槽執行 SELECT 及 DML 操作。
5)利用分割槽技術儲存資料庫中的關鍵表及索引,能夠縮短此類物件的維護視窗(maintenance window),及恢復時間,並減少此類物件發生故障時對系統的影響,從而提高資料庫的可用性。
6)採用分割槽技術時,使用者無需對原有應用程式進行任何修改。例如,當使用者將一個非分割槽錶轉化為分割槽表後,無需修改訪問此表的 SELECT 語句及 DML 語句。使用者無需重寫應用程式程式碼就可以發揮分割槽技術的優勢。
16.請寫出引數session_cached_cursors 的作用
open_cursors:該引數含義是同一個session同時開啟最多在使用的遊標數。在Oracle10.2.0.1.0版本中預設為300。
session_cached_cursors:SESSION_CACHED_CURSORS, 就是說的是一個session可以快取多少個cursor,讓後續相同的SQL語句不再開啟遊標,從而避免軟解析的過程來提高效能。(繫結變數是解決硬解析的問題),軟解析同硬解析一樣,比較消耗資源.所以這個引數非常重要。在Oracle10.2.0.1.0版本中預設為20。
show parameter open_cursors ----每個session(會話)最多能同時開啟多少個cursor(遊標)
show parameter session_cached_cursors ----每個session(會話)最多可以快取多少個關閉掉的cursor
select count(*) from v$open_cursor; ----是指當前例項的某個時刻的開啟的cursor數目 COUNT(*)
a、兩個引數之間沒有任何關係,相互也不會有任何影響。
b、兩個引數有著相同的作用:讓後續相同的sql語句不在開啟遊標,從而避免軟解析過程來提供應用程式的效率。
cursor的作用 open ->close. 頻繁的開關會產生開銷。SESSION_CACHED_CURSORS適當的增加提高了快取open cursor的數量,減少了頻繁開關的開銷。
使用下面的sql判斷session_cached_cursors的使用情況。如果使用率為100%則增大這個引數值。
Select 'session_cached_cursors' Parameter,
Lpad(Value, 5) Value,
Decode(Value, 0, ' n/a', To_Char(100 * Used / Value, '990') || '%') Usage
From (Select Max(s.Value) Used
From V$statname n, V$sesstat s
Where n.Name = 'session cursor cache count'
And s.Statistic# = n.Statistic#),
(Select Value From V$parameter Where Name = 'session_cached_cursors')
Union All
Select 'open_cursors',
Lpad(Value, 5),
To_Char(100 * Used / Value, '990') || '%'
From (Select Max(Sum(s.Value)) Used
From V$statname n, V$sesstat s
Where n.Name In
('opened cursors current', 'session cursor cache count')
And s.Statistic# = n.Statistic#
Group By s.Sid),
(Select Value From V$parameter Where Name = 'open_cursors');
17.請寫出臨時表空間的作用
1、臨時表空間的作用:
臨時表空間主要用途是在資料庫進行排序運算、管理索引、訪問檢視等操作時提供臨時的運算空間,當運算完成之後系統會自動清理。
當臨時表空間不足時,表現為運算速度異常的慢,並且臨時表空間迅速增長到最大空間(擴充套件的極限),並且一般不會自動清理了。
2、迅速增長的原因:
一般原因是sql演算法不正確,可能導致出現了迪卡爾積。
另外一個原因是檢視的建立問題(本人遇到的正是該問題!)。Oracle資料庫中多張表聯合查詢時,極限的表單數量為4張,一般將以為3張!有時需要大於4張表聯合查詢時,怎麼辦呢?可以建立子檢視:
如view0(聯合table0,table1,table2),view1(聯合table0,table3,table4),view2(聯合table0,table5,table6)
然後將view0、view1、view2聯合成view。
這樣可以解決臨時表空間迅速增長的問題!
臨時表空間使用注意:
1.臨時表空間 是用於在進行排序操作(如大型查詢,建立索引和聯合查詢期間儲存臨時資料)
每個使用者都有一個臨時表空間
2.對於大型操作頻繁,(大型查詢,大型分類查詢,大型統計分析等),應指定單獨的臨時表空間,以方便管理
3.分配使用者單獨臨時表空間,一般是針對 大型產品資料庫,OLTP資料庫,資料庫倉庫
對於小型產品不需要單獨制定臨時表空間,使用預設臨時表空間
當然解決方法也很簡單:1、設定臨時資料檔案自動擴充套件,或者2、增大臨時表空間。
擴充套件臨時表空間:
方法一、增大臨時檔案大小:
SQL> alter database tempfile ‘/u01/app/oracle/oradata/orcl/temp01.dbf’ resize 100m;
Database altered.
方法二、將臨時資料檔案設為自動擴充套件:
SQL> alter database tempfile ‘/u01/app/oracle/oradata/orcl/temp01.dbf’ autoextend on next 5m maxsize unlimited;
Database altered.
方法三、向臨時表空間中新增資料檔案:
SQL> alter tablespace temp add tempfile ‘/u01/app/oracle/oradata/orcl/temp02.dbf’ size 100m;
18.請寫出全域性索引及本地索引的區別
區域性索引local index
1. 區域性索引一定是分割槽索引,分割槽鍵等同於表的分割槽鍵,分割槽數等同於表的分割槽數,一句話,區域性索引的分割槽機制和表的分割槽機制一樣。
2. 如果區域性索引的索引列以分割槽鍵開頭,則稱為字首區域性索引。
3. 如果區域性索引的列不是以分割槽鍵開頭,或者不包含分割槽鍵列,則稱為非字首索引。
4. 字首和非字首索引都可以支援索引分割槽消除,前提是查詢的條件中包含索引分割槽鍵。
5. 區域性索引只支援分割槽內的唯一性,無法支援表上的唯一性,因此如果要用區域性索引去給表做唯一性約束,則約束中必須要包括分割槽鍵列。
6. 區域性分割槽索引是對單個分割槽的,每個分割槽索引只指向一個表分割槽,全域性索引則不然,一個分割槽索引能指向n個表分割槽,同時,一個表分割槽,也可能指向n個索引分割槽, 對分割槽表中的某個分割槽做truncate或者move,shrink等,可能會影響到n個全域性索引分割槽,正因為這點,區域性分割槽索引具有更高的可用性。
7. 點陣圖索引只能為區域性分割槽索引。
8. 區域性索引多應用於資料倉儲環境中。
全域性索引global index
1. 全域性索引的分割槽鍵和分割槽數和表的分割槽鍵和分割槽數可能都不相同,表和全域性索引的分割槽機制不一樣。
2. 全域性索引可以分割槽,也可以是不分割槽索引,全域性有分割槽索引必須是字首索引,即全域性索引的索引列必須是以索引分割槽鍵作為其前幾列。
3. 全域性分割槽索引的索引條目可能指向若干個分割槽,因此,對於全域性分割槽索引,即使只動,截斷一個分割槽中的資料,都需要rebulid若干個分割槽甚至是整個索引。
4. 全域性索引多應用於oltp系統中。
5. 全域性分割槽索引只按範圍或者雜湊hash分割槽,hash分割槽是10g以後才支援。
6. oracle9i以後對分割槽表做move或者truncate的時可以用update global indexes語句來同步更新全域性分割槽索引,用消耗一定資源來換取高度的可用性。
7. 表用a列作分割槽,索引用b做區域性分割槽索引,若where條件中用b來查詢,那麼oracle會掃描所有的表和索引的分割槽,成本會比分割槽更高,此時可以考慮用b做全域性分割槽索引。
19.請寫出如何定位消耗資源多的SQL
statspack-- 在你庫上業務最忙得時候抓15分鐘的report,看裡面的top sql///////awr/ash
1 top找到消耗資源多的pid
2 確定是oracle的應用程式還是後臺程式
3 根據v$session,v$process,v$sqlarea定位
用oem帶的top session
SELECT hash_value, executions, buffer_gets, disk_reads, parse_calls FROM V$SQLAREA
WHERE buffer_gets > 10000000 OR disk_reads > 1000000
ORDER BY buffer_gets + 100 * disk_reads DESC
1. 值得懷疑的SQL
select substr(to_char(s.pct, '99.00'), 2) || '%' load, s.executions executes, p.sql_text from (select address,disk_reads,executions,pct,rank() over(order by disk_reads desc) ranking from (select address,disk_reads,executions,100 * ratio_to_report(disk_reads) over() pct from sys.v_$sql where command_type != 47) where disk_reads > 50 * executions) s, sys.v_$sqltext p where s.ranking <= 5 and p.address = s.address order by 1, s.address, p.piece;
2、檢視消耗記憶體多的sql
select b.username,a. buffer_gets,a.executions,a.disk_reads / decode(a.executions, 0, 1, a.executions),a.sql_text SQL from v$sqlarea a, dba_users b where a.parsing_user_id = b.user_id and a.disk_reads > 10000 order by disk_reads desc;
3.邏輯讀多的SQL
select * from (select buffer_gets, sql_text from v$sqlarea where buffer_gets > 500000 order by buffer_gets desc) where rownum <= 30;
4.執行次數多的SQL
select sql_text, executions from (select sql_text, executions from v$sqlarea order by executions desc) where rownum < 81;
5. 讀硬碟多的SQL
select sql_text, disk_reads from (select sql_text, disk_reads from v$sqlarea order by disk_reads desc) where rownum < 21;
6. 排序多的SQL
select sql_text, sorts from (select sql_text, sorts from v$sqlarea order by sorts desc) where rownum < 21;
7.分析的次數太多,執行的次數太少,要用綁變數的方法來寫sql
set pagesize 600;
set linesize 120;
select substr(sql_text, 1, 80) "sql", count(*), sum(executions) "totexecs" from v$sqlarea where executions < 5 group by substr(sql_text, 1, 80) having count(*) > 30 order by 2;
8.遊標的觀察
set pages 300;
select sum(a.value), b.name from v$sesstat a, v$statname b where a.statistic# = b.statistic# and b.name = 'opened cursors current'group by b.name;
select count(0) from v$open_cursor;
select user_name, sql_text, count(0) from v$open_cursor group by user_name, sql_text having count(0) > 30;
9.檢視當前使用者&username執行的SQL
select sql_text from v$sqltext_with_newlines where (hash_value, address) in (select sql_hash_value, sql_address from v$session where username = '&username') order by address, piece;
20.請寫出oracle主要後臺程式的作用
Oracle中的程式共分為三類:使用者程式、服務程式、後臺程式。其中後臺程式伴隨例項的啟動而啟動,他們主要是維護資料庫的穩定,相當於一個企業中的管理者及內部服務人員。他們並不會直接給使用者提過服務。
一:database write:DBWn資料寫入
作用:把SGA中被修改的資料同步到磁碟檔案中。保證Buffer Cache中有足夠的空閒資料塊數量。
觸發條件:1,檢查點
2,一個服務程式在設定的時間內沒有找到空閒塊。
3,每3秒自動喚醒一次。
設定:DB_WRITER_PROCESSES用來定義DBWn程式數量。(commit命令只是把記錄修改寫入日誌檔案,不是把修改後的資料寫入資料檔案,下面還會提到。)
二:log write LGWR:日誌檔案寫入
作用:把log buffer中的日誌內容寫入聯機的日誌檔案中,釋放log使用者buffer空間呢。
觸發條件:1,使用者發出commit指令。(在oracle中稱為快速提交機制(fast commit):把redo log buffer中的記錄寫入日誌檔案,寫入一條已提交的記錄)。
2,三秒鐘定時喚醒。
3,log buffer超過1/3,或日誌數量超過1M。
4,DBWR程式觸發:DBWn試圖將髒資料塊寫入磁碟先檢查他的相關redo記錄是否寫入聯機日誌檔案,如果沒有就通知LGWR程式。
在oracle中稱為提前寫機制(write ahead):redo記錄先於資料記錄被寫入磁碟。
三:checkpoint CKPT:檢查點事件
作用:維護資料庫一致性狀態。檢查點時刻資料檔案與SGA中的內容一致。這不是一個單獨的程式,要和前兩個程式一起工作。DBWR寫入髒資料,同時觸發LGWR程式。
CKPT更新控制檔案中的檢查點記錄。
觸發條件:日誌切換(log switch)會觸發檢查點。
四:process monitor PMON :維護使用者程式
作用:1,發現使用者程式異常終止,並進行清理。釋放佔用資源。(清理異常終止使用者使用的鎖)。
2,向監聽程式動態的註冊例項。
觸發條件:定時被喚醒,其他程式也會主動喚醒他。
五:system monitor SMON:例項維護
作用:1,負責例項恢復,前滾(Roll Forward)恢復到例項關閉時刻的狀態,使用最後一次檢查點後的日誌進行重做。這時包括提交和未提交的事務。開啟資料庫,進行回滾(Roll Back):回滾未提交的事務。
(Oracle承諾commit之後的資料不會丟失,現在我們可以大致的瞭解Oracle是如何實現這個承諾的,以及在資料的安全性和資料庫效能之間的平衡選擇。)
2,負責清理臨時段,以釋放空間;
觸發條件:定期被喚醒或者被其他事務主動喚醒。
六:archive ARCn:歸檔操作
作用:發生日誌切換時把寫滿的聯機日誌檔案複製到歸檔目錄中。
觸發條件:日誌切換時被LGWR喚醒。
設定:LOG_ARCHIVE_MAX_PROCESSES可以設定oracle啟動的時候ARCn的個數。
七:manageability monitor MMON:AWR主要的程式。
作用:1收集AWR必須的統計資料,把統計資料寫入磁碟。10g中儲存在SYSAUX表空間中。
2,生成server-generated報警。
每一個小時把shard pool中的統計資訊寫入磁碟,或shard pool佔用超過5%。
八:manageability monitor light MMNL:輕量級的MMON;
九:memory manager MMAN:自動記憶體管理
作用:每分鐘都檢查AWR效能資訊,並根據這些資訊來決定SGA元件最佳分佈。
設定:STATISTICS_LEVEL:統計級別
SGA_TARGET:SGA總大小
十:job queue coordinator CJQO:資料庫定時任務
十一:recover writer RVWR:為flashback database提供日誌記錄。把資料塊的前映象寫入日誌。
十二:change tracking writer CTWR:跟蹤資料塊的變化,把資料塊地址記錄到change_tracking file檔案中。RMAN的增量備份將使用這個檔案來確定那些資料塊發生了變化,並進行備份。
以上是oracle中比較常見的後臺程式,不是所有的程式。其中DBWn,ARCn可以設定資料庫啟動時的數量。這些程式在系統中可以不止一個。
Oracle實戰類:
1.表tab1,由5列組成,存在1000萬條記錄,現查詢該表非常慢,請問如何解決該問題
首先先用查詢條件(order by等)查詢一下 如果還慢,檢視是否有索引,沒有建立索引,有索引重新建立索引。
索引結構
如何再不行,重新將表分割槽。
2.資料庫突然變得非常緩慢,請寫出診斷思路
看是否有哪些sql語句發生死鎖,堵塞
看看alert檔案有什麼錯誤或警告沒有,此外在慢的時候查查v$session_wait有什麼等待事件
看回滾空間佔用率是多少,temp空間佔用率是多少。
如果回滾空間佔用率太多,就看是什麼程式在其中佔用了大量的回滾空間,而且沒有自我釋放,一直在執行,從中,可以判斷出是什麼問題。
然後在殺資料庫的程式,將死迴圈或者其他死程式給殺了。
還有可能是臨時表空間滿了
awr
3.資料庫alert日誌中報錯ORA-01555,請寫出診斷思路
Linux下執行:oerr ora 1555檢視錯誤解釋
先看報錯,是否因為undo表空間太小,如果是,擴大undo表空間;如果不是,增加引數undo_retention;
undo基本資訊:
select inst_id,name,value from gv$parameter where upper(name) like '%UNDO%';
select distinct status,count(*) extent_num , sum(bytes/1024/1024) undosize from dba_undo_extents group by status;
4.資料庫在備份時報錯塊損壞,請寫出處理思路
如果是物理損壞,換盤,如果是邏輯損壞,先定位到塊損壞的位置。////如何定位資料塊的位置。
停止資料庫備份:用bbed來修復壞塊
recover datafile'/u01/oracle/oracle10g/oradata/TEST/test.dbf';恢復資料檔案。
5.資料庫突然異常關閉,請寫出處理思路
先重新啟動如果不行檢視alert
總結:
當發生1102錯誤時,可以按照以下流程檢查、排錯:
如果是HA系統,檢查其他節點是否已經啟動例項;
檢查Oracle程式是否存在,如果存在則殺掉程式;
檢查訊號量是否存在,如果存在,則清除訊號量;
檢查共享記憶體段是否存在,如果存在,則清除共享記憶體段;
檢查鎖記憶體檔案lk和sgadef.dbf是否存在,如果存在,則刪除。
伺服器異常斷電,導致oracle 資料庫無法開啟:
SQL> alter database open;
alter database open
*
ERROR at line 1:
ORA-16038: log 1 sequence# 8 cannot be archived
ORA-19504: failed to create file ""
ORA-00312: online log 1 thread 1: '/oracle/oradate/orcl/redo1.log'
處理過程是:
SQL> select group#, sequence# from v$log;
GROUP# SEQUENCE#
------- ----------
1 10
2 11
3 12
SQL> alter database clear unarchived logfile group 1;
Database altered.
SQL> alter database open;
Database altered.
當時沒能建立歸檔日誌的原因是對歸檔資料夾的操作許可權不夠。賦予足夠許可權以後
SQL> alter system archive log start;
System altered.
某系統突然掉電,系統啟動後發現Oracle無法啟動。啟動時報如下錯誤:
ORA-01102 cannot mount database in EXCLUSIVE mode
出現1102錯誤可能有以下幾種可能:
一、在HA系統中,已經有其他節點啟動了例項,將雙機共享的資源(如磁碟陣列上的裸裝置)佔用了;
二、說明Oracle被異常關閉時,有資源沒有被釋放,一般有以下幾種可能,
1、 Oracle的共享記憶體段或訊號量沒有被釋放;
2、 Oracle的後臺程式(如SMON、PMON、DBWn等)沒有被關閉;
3、 用於鎖記憶體的檔案lk和sgadef.dbf檔案沒有被刪除。
首先,雖然我們的系統是HA系統,但是備節點的例項始終處在關閉狀態,這點透過在備節點上查資料庫狀態可以證實。
其次、是因系統掉電引起資料庫當機的,系統在接電後被重啟,因此我們排除了第二種可能種的1、2點。最可疑的就是第3點了。
查$ORACLE_HOME/dbs目錄:
$ cd $ORACLE_HOME/dbs$ ls sgadef*sgadef* not found$ ls lk*lkORA92
果然,lk檔案沒有被刪除。將它刪除掉
$ rm lk*
再啟動資料庫,成功。
如果懷疑是共享記憶體沒有被釋放,可以用以下命令檢視:
$ipcs -mopIPC status from /dev/kmem
as of Thu Jul 6 14:41:43 2006T ID KEY MODE OWNER GROUP NATTCH CPID LPIDShared Memory:m 0 0x411c29d6
--rw-rw-rw- root root 0 899 899m 1 0x4e0c0002
--rw-rw-rw- root root 2 899 901m 2 0x4120007a
--rw-rw-rw- root root 2 899 901m 458755 0x0c6629c9
--rw-r----- root sys 2 9113 17065m 4 0x06347849
--rw-rw-rw- root root 1 1661 9150m 65541 0xffffffff
--rw-r--r-- root root 0 1659 1659m 524294 0x5e100011
--rw------- root root 1 1811 1811m 851975 0x5fe48aa4
--rw-r----- oracle oinstall 66 2017 25076
然後它ID號清除共享記憶體段:
$ipcrm –m 851975
對於訊號量,可以用以下命令檢視:
$ ipcs -sopIPC status from /dev/kmem
as of Thu Jul 6 14:44:16 2006T ID KEY MODE OWNER GROUPSemaphores:s 0 0x4f1c0139
--ra------- root root... ...s 14 0x6c200ad8
--ra-ra-ra- root roots 15 0x6d200ad8
--ra-ra-ra- root roots 16 0x6f200ad8
--ra-ra-ra- root roots 17 0xffffffff
--ra-r--r-- root roots 18 0x410c05c7
--ra-ra-ra- root roots 19 0x00446f6e
--ra-r--r-- root roots 20 0x00446f6d
--ra-r--r-- root roots 21 0x00000001
--ra-ra-ra- root roots 45078 0x67e72b58
--ra-r----- oracle oinstall
根據訊號量ID,用以下命令清除訊號量:
$ipcrm -s 45078
如果是Oracle程式沒有關閉,用以下命令查出存在的oracle程式:
$ ps -ef|grep ora oracle 29976 1 0 Jun 22 ? 0:52 ora_dbw0_ora92 oracle 29978 1 0 Jun 22 ? 0:51 ora_dbw1_ora92 oracle 5128 1 0 Jul 5 ? 0:00 oracleora92 (LOCAL=NO)... ...
然後用kill -9命令殺掉程式
$kill -9
1.請寫出如何新增資料檔案的語句
Alter tablespace data add datafile ‘/oracle/oradata/CFGDB/data01.dbf’ size 100m
2.請寫出如何啟動歸檔模式
Shutdown immediate startup mount alter database archivelog alter database open
3.請寫出如何檢視當前被鎖的表
Select t1.object_name from dba_objects t1,v$session t2,v$locked_object t3 where t1.object_id=t3.object_id and t2.sid=t3.session_id;
4.請寫出如何檢視某張表的索引
Select * from dba_indexes where table_name=’’;
5.請寫出如何檢視某張表的大小
Select * from dba_segments where segment_name=’’ and segment_type=’TABLE’;
6.請寫出如何檢視某使用者使用的預設表空間
Select username,default_tablespace,temporary_tablespace from dba_users where username=’’;
7.請寫出如何檢視各個表空間的大小
select tablespace_name,bytes/1024/1024 from dba_data_files;
8.請寫出如何檢視當前資料庫存在的等待事件
select * from v$session_wait; select * from v$waitstat; desc v$waitstat
9.請寫出如何生成AWR報告
@$ORACLE_HOME/rdbms/admin/awrrpt.sql
@$ORACLE_HOME/rdbms/admin/ashrpt.sql
10.請寫出切換日誌的語句
alter system switch logfile;
11.請寫出如何透過sqlid獲得該SQL的執行計劃
explain plan for select * from ...
select * from table(DBMS_XPLAN.DISPLAY_AWR(SQL_ID));10G以後。
SELECT * FROM table (DBMS_XPLAN.DISPLAY_AWR ('danxh10kwn2s3',NULL,NULL,‘BASIC’));可以把BASIC 換成 ADVANCE 和TYPICAL試試。
12.請寫出如何鎖住某個使用者
alter user SN account lock;
alter user SN account unlock;
13.請寫出如何查詢某表的統計資訊
dbms_stats.gather_table_stats(user,'table',cascade=>true);
DBMS_STATS包中用於收集統計資訊的過程包括:
dbms_stats.gather_table_stats 收集表、列和索引的統計資訊;
dbms_stats.gather_schema_stats 收集SCHEMA下所有物件的統計資訊;
dbms_stats.gather_index_stats 收集索引的統計資訊;
dbms_stats.gather_system_stats 收集系統統計資訊。
dbms_stats.delete_table_stats 刪除表的統計資訊
dbms_stats.export_table_stats 輸出表的統計資訊
dbms_stats.create_state_table
dbms_stats.set_table_stats 設定 表的統計
dbms_stats.auto_sample_size
dbms_stats.gather_database_stats: 收集資料庫中所有物件的統計資訊;
14.請寫出如何跟蹤某session執行的sql
exec dbms_system.set_sql_trace_in_session(sid,serial#,&sql_trace);
select sid,serial# from v$session where sid = (select sid from v$mystat where rownum = 1);
exec dbms_system.set_ev(&sid,&serial#,&event_10046,&level_12,'');
15.請寫出如何檢視當前資料庫在執行的事務
select * from v$transaction;
16.請寫出設定sga_target為10G的語句
alter system set sga_target=10240m
17.請寫出如何根據sqlid獲得該SQL是否使用繫結變數
select sql_id,sql_text,executions from v$sqlarea; 看executions的數量特別大說明沒有繫結變數
減產前40個字元相同, 有多於5個不同sql版本的sql語句
select substr(sqltext,1,40) sql_text,count(*) from v$sql group by substr(sqltext,1,40) having count(*) >= 5;
18.請寫出如何獲得某latch的sleep數量
select name,gets,misses,immediate_gets,immediate_misses,sleeps from v$latch;
19.請寫出如何根據作業系統程式號獲得oracle 會話號
select s.sid from v$session s,v$process p where p.addr=s.PADDR and p.spid='25783'
select sid from v$session where process='25817';
SQL語句殺掉長期沒有釋放非正常的鎖:
alter system kill session 'sid,serial#';
20.請寫出如何查詢當前資料庫日誌的切換時間
select archived,status,first_time from v$log;
Oracle概念類
1.請簡述oracle SGA中各記憶體區域的功能
buffer cache,log buffer,shared pool,big pool,java pool,streams pool
資料高速緩衝區(buffer cache):
用來儲存使用者最近從磁碟資料檔案訪問的資料塊的副本,這樣當再由使用者訪問相同的資料時,則可以直接從資料高速緩衝區讀取,不用再訪問磁碟(注:磁碟I/O的速率是毫米級的,而記憶體I/O的速率為納秒級)
包括三個型別區
髒的區(dirty buffer):用來儲存從磁碟資料檔案讀取來的、已經修改過、並且還沒有寫入磁碟資料檔案的資料。
自由區(free buffer):沒有任何資料,並且可以寫入資料的空閒記憶體區;
保留區(pinned buffer):用來儲存正在被使用,或者明確留作將來使用的資料,主要指,從磁碟資料檔案內讀取到、等待伺服器程式更改的資料,或者正在被更改的資料。
資料高速緩衝區可配置一個或2個或3個緩衝區池,我們在create或alter表或索引時,可以指定該表或索引屬於哪個緩衝區池;
保持緩衝區池(db_keep_cache_size):用來儲存一些需要頻繁訪問的小表,防止這些小表的資料被LRU命中;
回收緩衝區池(db_recycle_cache_size):用來儲存一些很少使用的大表,在緩區處理完之後,立即清除,節省快取空間;
預設緩衝區池(db_cache_size):用來儲存除db_keep_cache_size和db_recycle_cache_size之外的所有資料;
子快取記憶體(db_nk_cache_size):主要針對不同的oracle塊尺寸來設定的,
資料高速緩衝區尺寸=db_keep_cache_size+db_recycle_cache_size+db_cache_size+db_nk_cache_size;
重做日誌快取(log buffer):
用來儲存資料庫內的變更,由LGWR立即寫入聯機重做日誌檔案
共享池(shared_pool_size):
包括庫快取記憶體和資料字典高速緩衝兩部分
庫快取記憶體:主要用來儲存分析過的sql程式碼,所謂的“分析”是指,校驗使用者請求sql程式碼的語法,並且判斷sql程式碼涉及的表和欄位在資料庫內是否存在;
調優手段:透過動態檢視v$librarycache,判斷公式:sum(reloads)/sum(pins),如果結果約等於0,則證明庫快取記憶體命中率是合適的;如果結果>1,則需要增大共享池設定(shared_pool_size);
資料字典快取記憶體:主要用來儲存伺服器最近從磁碟資料字典內訪問過的資料,主要包括表結構、使用者、實體等資訊,如果再有使用者請求時,則伺服器程式會首先從資料字典快取記憶體內檢索,在緩衝區內是否存在該請求使用者的相關許可權資訊,如果沒有的話,需要訪問磁碟資料字典(注:訪問磁碟資料字典是最消耗資源的,相對於訪問其他磁碟檔案來說)
調優手段:透過動態檢視v$rowcache,判斷公式:(1-sum(getmisses)/(sum(getmiss)+sum(getmisses)))*100,如果結果>90,證明命中率是合適的,否則需要增大共享池設定;(注:oracle沒有直接設定庫高速緩衝和資料字典高速緩衝的地方,需要透過調整共享池尺寸實現)
大型池(large_pool_size):
主要為執行一些非常複雜並且耗時很長的sql程式碼提供空間,例如在執行備份操作時,需要存放備份緩衝區;
Java池(java_pool_size):
主要為例項化的Java物件提供的堆空間,如果資料庫中存在大量的java程式碼,就可以使用該設定,不用佔用常規的sga;
流池(streams_pool_size):
oracle支援流傳輸,主要用來實現與不同型別資料庫,或者在不同應用環境下的資料共享;
其他結構(包括資料控制和鎖的管理)
pga(程式全域性區):每個使用者會話都會在pga上佔用一段獨佔的記憶體空間,pga上從屬於該使用者會話的記憶體空間,只允許該使用者使用,其他使用者不能訪問。pga透過pga_size_mode可以設定自動或是手動記憶體配置。
2.如何檢視執行計劃,檢視執行計劃的作用是什麼
一、explain plan for select * from ......
select * from table(DBMS_XPLAN.Display)
二、set autotrace on;
SET AUTOTRACE OFF ---------------- 不生成AUTOTRACE 報告,這是預設模式
SET AUTOTRACE ON EXPLAIN ------ AUTOTRACE只顯示最佳化器執行路徑報告
SET AUTOTRACE ON STATISTICS -- 只顯示執行統計資訊
SET AUTOTRACE ON ----------------- 包含執行計劃和統計資訊
SET AUTOTRACE TRACEONLY ------ 同set autotrace on,但是不顯示查詢
三、SQL_TRACE
1.alter session set sql_trace=true;
2.執行sql
3.alter session set sql_trace=false;
4.檢視相應的sql trace檔案。
作用:
語句所引用表的順序;
語句所涉及的表的訪問方法;
語句中連線操作所影響到的各表的連線方法。
----各種表訪問方式需要明白
3.請寫出控制檔案的作用
作用:
二進位制檔案
記錄了資料庫當前例項的結構和行為,資料檔案日誌檔案的資訊,維護資料庫一致性
引數檔案中定義了控制檔案的位置和大小
很小的二進位制檔案,一般不超過100m
mount階段open以後,一直在用
一套控制檔案只能連線一個database
分散放置,至少一份,至多八份
control files作用:
引數檔案init.ora 記錄了控制檔案的位置,控制檔案是一個非常小的二進位制檔案,最大可以增長到64MB,控制檔案包括如下主要資訊:
·資料庫的名字,檢查點資訊,資料庫建立的時間戳
·所有的資料檔案,聯機日誌檔案,歸檔日誌檔案資訊
·備份資訊等
有了這些資訊,Oracle 就知道那些檔案是資料檔案,現在的重做日誌檔案是哪些,這些都是系統啟動和執行的基本條件,所以他是Oracle 執行的根本。如果沒有控制檔案系統是不可能啟動的。控制檔案是非常重要的,一般採用多個鏡相複製來保護控制檔案,或採用RAID 來保護控制檔案。控制檔案的丟失,將使資料庫的恢復變的很複雜。控制檔案資訊可以從V$Controlfile 中查詢獲得
一.控制檔案的作用
控制檔案記錄了物理資料庫的當前狀態。一般為3個,三個控制檔案都是一摸一樣的,最好是分開放在不同的磁碟上。
二.控制檔案的內容
2.1資料庫的名字;
資料庫的標示符:建立資料庫是oracle自動生成的;
資料庫建立的時間戳:它是在資料庫建立時生成的;
聯機重做日誌檔案的名字和準確位置;
當前日誌的學歷號:它是在日誌切換時oracle記錄的;
日誌的歷史資訊:它是在日誌切換時oracle記錄的;
歸檔日誌檔案的準確位置和狀態;
資料檔案的名字和準確位置;
表空間的資訊;
備份的準確位置和狀態;
三.新增和移動控制檔案
5.1在一個已經安裝的的oracle資料庫中使用正文初始化引數檔案(pfile)新增或者移動控制檔案的具體步驟。
a).利用資料字典v$controlfile來獲取現有的控制檔名字;
b).正常關閉資料庫,用命令shutdown或者shutdown immediate;
c).將新的控制檔名新增到引數檔案的control_files引數中;//區別
d).使用作業系統命令將現有的控制檔案複製到指定位置;
e).重新啟動資料庫,用命令startup;
f).利用資料字典v$controlfile來驗證新的控制檔名字是否正確;
g).如果有誤,重複上述操作;如果無誤,就刪除無用的舊的控制檔案;
5.2如果使用了伺服器初始化引數(spfile),步驟會有些區別。下面是具體步驟;
a).利用資料字典v$controlfile來獲取現有的控制檔名字;
b).修改spfile,使用alter system set control_files命令來改變控制檔案的位置;//區別
c).正常關閉資料庫,用命令shutdown或者shutdown immediate;
d).使用作業系統命令將現有的控制檔案複製到指定位置;
e).重新啟動資料庫,用命令startup;
f).利用資料字典v$controlfile來驗證新的控制檔名字是否正確;
g).如果有誤,重複上述操作;如果無誤,就刪除無用的舊的控制檔案;
相關檢視:
v$controlfile ---- 列出例項的所有控制檔案的名字和狀態
v$parameter ---- 列出所有引數的位置和狀態(where name='control_files')
v$controlfile_recode_section ---- 提供控制檔案的記錄部分的資訊
show parameter control_files ---- 列出控制檔案的名字、狀態和位置
檢視控制檔案內容:
strings $ORACLE_BASE/oradata/$ORACLE_SID/control01.ctl
alter database backup controlfile to trace as '
轉儲控制檔案:
alter system set events 'immediate trace name controlf level 10'
level 1 塊頭
level 2 檔案內容
level 3 1+2
level 10 全部
管理控制檔案:
spfile 修改spfile引數control_files(alter……)
一致性關閉資料庫
增加或減少控制檔案
啟動資料庫使用spfile
驗證結果
pfile 一致性關閉資料庫
修改pfile引數
增加或減少控制檔案
啟動資料庫使用spfile
驗證結果
狀態查詢:引數和具體檔案是否對應、磁碟空間剩餘、控制檔案<100M
熱備控制檔案:
資料庫歸檔模式下,alter database backup controlfile to '
其他模式下:alter database backup controlfile to trace as '
資料庫歸檔模式下rman備份:
rman target /
>backup current controlfile; or
>backup database include current controlfile;
rman自動備份控制檔案:
>show all中的configure controlfile autobackup設定為on
>configure controlfile autobackup on
問題解決:
控制檔案不一致:
1. 複製新版本的控制檔案到舊版本檔案
2. 修改引數檔案,只使用新版本的檔案(alter system set……),重啟
控制檔案丟失:
【mount階段,使用archive log list可以檢視資料庫是否在歸檔模式下】
1. 控制檔案無備份
a.資料庫非歸檔,資料檔案聯機日誌檔案存在 --- 重建控制檔案
>create controlfile reuse database
2. 控制檔案有備份
a.資料庫歸檔,資料檔案聯機和歸檔日誌檔案存在 --- 還原控制檔案
先全備,再將控制檔案複製到引數指定的路徑,然後>alter database recover database using backup controlfile until change;
4.請寫出SCN的作用
SCN是當Oracle資料庫更新後,由DBMS自動維護去累積遞增的一個數字。Oracle資料庫中一共有4種SCN分別為
系統檢查點SCN: 系統檢查點SCN位於控制檔案中,當檢查點程式啟動時(ckpt),Oracle就把系統檢查點的SCN儲存到控制檔案中。該SCN是全域性範圍的,當發生檔案級別的SCN時,例如將表空間置於只讀狀態,則不會更新系統檢查點SCN。
資料檔案檢查點scn:當ckpt程式啟動時,包括全域性範圍的(比如日誌切換)以及檔案級別的檢查點(將表空間置為只讀、begin backup或將某個資料檔案設定為offline等),這時會在控制檔案中記錄的scn。
結束scn:每個資料檔案都有一個結束scn,在資料庫的正常執行中,只要資料檔案線上且是可讀寫的,結束scn為null。否則則存在具體的scn值。結束scn也記錄在控制檔案中。
開始scn:不同於上述的SCN資料檔案開始scn記錄在每個資料檔案中。當發生系統及檔案級別的檢查點後,不僅將這時的SCN號記錄在控制檔案中,同樣也記錄在資料檔案中。
SCN的機制 資料庫執行時的SCN
Oracle事務
我們先看下oracle事務中的資料變化是如何寫入資料檔案的:
一、事務開始;
二、在buffer cache中找到需要的資料塊,如果沒有找到,則從資料檔案中載入buffer cache中;
三、事務修改buffer cache的資料塊,該資料被標識為“髒資料”,並被寫入log buffer中; ----這個“髒資料”是什麼程式寫入到log buffer中的
四、事務提交,LGWR程式將log buffer中的“髒資料”寫入redo log file中;
五、當發生checkpoint,CKPT程式更新所有資料檔案的檔案頭中的資訊,DBWr程式則負責將Buffer Cache中的髒資料寫入到資料檔案中。
5.請寫出log file sync等待事件的產生原因
①.高提交頻率
解決方法是簡單的消除不必要的提交,事務是工作單元。工作單元應該是全部成功或全部失敗。
②.緩慢的I/O子系統
較高的IO吞吐量可以改善log file sync和log file parallel write事件的平均等待時間。頻繁的提交會弄亂資料庫佈局和IO子系統。
解決辦法是將日誌檔案放裸裝置上或繫結在RAID 0或RAID 0+1中,而不是繫結在RAID 5中。
③.過大的日誌緩衝區
過大的日誌緩衝區也可能延長log file sync等待。大型的日誌緩衝區減少後臺寫入的數量,允許LGWR變得懶惰,並導致更多的重做條目堆積在日誌緩衝區中。同時可以調整引數_LOG_IO_SIZE引數,其預設值是LOG_BUFFER的1/3或1MB,取兩者之中較小的值。換句話說,你可以具有較大的日誌緩衝區,但較小的_LOG_IO_SIZE將增加後臺寫入,從而減少log file sync的等待時間。
Statspack之十四-"log file sync" 等待事件:
當一個使用者提交(commits)或者回滾(rollback),session的redo資訊需要寫出到redo logfile中.
使用者程式將通知LGWR執行寫出操作,LGWR完成任務以後會通知使用者程式.
這個等待事件就是指使用者程式等待LGWR的寫完成通知.
對於回滾操作,該事件記錄從使用者發出rollback命令到回滾完成的時間.
如果該等待過多,可能說明LGWR的寫出效率低下,或者系統提交過於頻繁.
針對該問題,可以關注:
log file parallel write等待事件
user commits,user rollback等統計資訊可以用於觀察提交或回滾次數
解決方案:
1.提高LGWR效能。儘量使用快速磁碟,不要把redo log file存放在raid 5的磁碟上
2.使用批次提交
3.適當使用NOLOGGING/UNRECOVERABLE等選項
6.請寫出同一條記錄insert,delete,update操作中產生undo資訊的大致內容
insert操作無論是1條或者多條,一次產生一條undo資料
delete操作產生的undo條數取決於delete操作本身影響的記錄數
update操作產生的undo條數取決於被update的資料的原值和新值存在差異的記錄數量
測試中表沒有主鍵,如果有主鍵,所有操作都會增加一條undo資料.在刪除或者update大量資料時候會產生大量undo,
所以建議這兩種操作進行分批提交.
select used_ublk,used_urec from v$session s, v$transaction t where s.audsid=sys_context('userenv', 'sessionid') and s.taddr = t.addr;
7.請寫出latch的工作原理
latch是一種輕量級用於保護oracle共享記憶體結構,使用者併發操作一致性的序列化鎖定機制,如SGA中,各種資料被反覆從磁碟讀取到記憶體,又被重新寫回到磁碟上,如果有併發使用者做相同的事情,oracle必須使用一種機制來保證資料在讀取的時候,只能由一個會話來完成,這就是latch,latch 不會造成阻塞,是隻會等待,與每個latch相聯絡的還有一個清除過程,當持有latch的程式成為死程式時,系統清除過程就會被呼叫,系統lock導致 使用者等待,需要考慮系統的邏輯設計是否有問題,如多使用者對主鍵的刪除或者修改,是否有使用者使用select… for update這樣的語法,外來鍵是否建立索引。latch 爭用多半要考慮系統及資料庫自身設計問題,如繫結變數,熱塊及引數設定是否合理。
spin:比如資料快取中的某個塊要被讀取,我們會獲得這個塊的 latch,這個過程叫做spin,另外一個程式恰好要修改這個塊,他也要spin這個塊,此時他必須等待,當前一個程式釋放latch後才能spin 住,然後修改,如果多個程式同時請求的話,他們之間將出現競爭,沒有一個入隊機制,一旦前面程式釋放鎖定,後面的程式就蜂擁而上,沒有先來後到的概念,並且這一切都發生的非常快,因為Latch的特點是快而短暫。
spin與休眠:
休眠意味著暫時的放棄CPU,進行上下文切換(context switch),這樣CPU要儲存當前程式執行時的一些狀態資訊,比如堆疊,訊號量等資料結構,然後引入後續程式的狀態資訊,處理完後再切換回原來的程式狀態,這個過程如果頻繁的發生在一個高事務,高併發程式的處理系統裡面,將是個很昂貴的資源消耗,所以Oracle選擇了spin,讓程式繼續佔有 CPU,執行一些空指令,之後繼續請求,繼續spin,直到達到_spin_count值,這時會放棄CPU,進行短暫的休眠,再繼續剛才的動作。
oracle中,latch是一種輕量級的鎖。一般來說,latch由三種記憶體元素成:pid(程式id),記憶體地址和記憶體長度。Latch保證對共享資料結構的排它性訪問,以此來保證記憶體結構的完整性不受到損壞。在多個會話同時修改或者檢視(inspect)sga中同一個記憶體結構時,必須序列化訪問以保證sga中資料結構的完整性。
程式獲取latch有兩種模式:willing-to-wait和No_wait。no-wait模式只在少數latch中使用。透過no-wait模式 獲取latch的統計資訊記錄在immediate_gets immediate_misses列中,這些列在v$latch,v$latch_parent,v$latch_children檢視中都存在。一般來 說,no-wait模式在第一次獲取一些有很多子latch的latch比如redo copy時使用。如果一個程式第一次獲取這些子latch中的任何一個失敗,它會立即使用no-wait模式詢問下一個。只有當採用no-wait模式試圖獲取所有的子latch都失敗以後,才會轉而採用willing-to-wait模式。
透過willing-to-wait模式獲取latch的統計資訊存放在gets和misses列中。每當一個程式用willing-to-wait模式去獲取一個latch時,gets都會增加。
如果程式在第一次請求latch時,latch可用,就會直接獲得該latch。在修改任何受到保護的資料結構之前,程式會將一些恢復資訊寫入到latch恢復區,這樣當獲得latch的程式發生異常時,pmon程式才能夠清理該程式持有的latch。
如果請求latch時,該latch不可用,程式就會在cpu中等待一小段時間(spin)然後重新請求latch。如果latch一直不可用,該過程(spin一段時間然後重新請求)會一直重複。重複的次數由隱含引數_spin_count決定,預設值2000。如果在請_spin_count次之內 獲得了latch,就對spin_gets和misses列各加一,否則,程式v$session_wait中記錄latch free等待事件,然後釋放cpu,轉入睡眠狀態。睡眠一定時間後,程式被喚醒並重覆上面的過程,一直到獲得latch。在成功獲得latch後,才會更行sleep列得統計資訊。
由於程式只有在獲得latch後才會停止對latch得請求,如果某個持有latch的程式發生異常,其他請求該latch的程式該怎麼辦?豈不是要一直等待下去?不會的。當一個程式請求latch失敗一定次數後,它會請求pmon程式檢視該latch的持有者,如果持有程式異常,pmon就會清理該程式,釋放latch。
每個latch都有一個從0到13的優先順序編號。父latch和獨立latch的優先順序編號是在oracle核心程式碼中固定的。子latch是在例項啟動時建立,其優先順序編號從其父latch繼承。使用優先順序可以避免死鎖。
當一個程式請求no-wait模式的latch時,該latch的優先順序編號必須和它當前已經持有的latch的優先順序編號相同。
當一個程式請求willing-to-wait模式的latch時,該latch的優先順序編號必須比它當前已經持有的latch的優先順序編號要大。
程式獲取Latch的過程:
任何時候,只有一個程式可以訪問記憶體中的某一個資料塊,如果程式因為別的程式正佔用塊而無法獲得Latch時,他會對CPU進行一次spin(旋轉),時間非常的短暫,spin過後繼續獲取,不成功仍然spin,直到 spin次數到達閥值限制(這個由隱含引數_spin_count指定),此時程式會停止spin,進行短期的休眠,休眠過後會繼續剛才的動作,直到獲取塊上的Latch為止。程式休眠的時間也是存在演算法的,他會隨著spin次數而遞增,以釐秒為單位,休眠的閥值限制由隱含引數 _max_exponential_sleep控制,預設是2秒,如果當前程式已經佔用了別的Latch,則他的休眠時間不會太長(過長會引起別的程式的 Latch等待),此時的休眠最大時間有隱含引數_max_sleep_holding_latch決定,預設是4釐秒。這種時間限制的休眠又稱為短期等待。另外一種情況是長期等待鎖存器(Latch Wait Posting),此時等待程式請求Latch不成功,進入休眠,他會向鎖存器等待連結串列(Latch Wait List)壓入一條訊號,表示獲取Latch的請求,當佔用程式釋放Latch時會檢查Latch Wait List,向請求的程式傳遞一個訊號,啟用休眠的程式。Latch Wait List是在SGA區維護的一個程式列表,他也需要Latch來保證其正常執行,預設情況下share pool latch和library cache latch是採用這個機制。
如果將隱含引數_latch_wait_posting設定為2,則所有Latch都採用這種等待方式,使用這種方式能夠比較精確的喚醒某個等待的程式, 但維護Latch Wait List需要系統資源,並且對Latch Wait List上Latch的競爭也可能出現瓶頸。
資料緩衝池Latch爭用
訪問頻率非常高的資料塊被稱為熱快(Hot Block),當很多使用者一起去訪問某幾個資料塊時,就會導致一些Latch爭用,最常見的latch爭用有:
(1) buffer busy waits
(2) cache buffer chain
Cache buffer chian產生原因:
當一個會話需要去訪問一個記憶體塊時,它首先要去一個像連結串列一樣的結構中去搜尋這個資料塊是否在記憶體中,當會話訪問這個連結串列的時候需要獲得一個Latch,如果獲取失敗,將會產生Latch cache buffer chain 等待,導致這個等待的原因是訪問相同的資料塊的會話太多或者這個列表太長(如果讀到記憶體中的資料太多,需要管理資料塊的hash列表就會很長,這樣會話掃描列表的時間就會增加,持有chache buffer chain latch的時間就會變長,其他會話獲得這個Latch的機會就會降低,等待就會增加)。
Buffer busy waits 產生原因:
當一個會話需要訪問一個資料塊,而這個資料塊正在被另一個使用者從磁碟讀取到記憶體中或者這個資料塊正在被另一個會話修改時,當前的會話就需要等待,就會產生一個buffer busy waits等待。
產生這些Latch爭用的直接原因是太多的會話去訪問相同的資料塊導致熱塊問題,造成熱塊的原因可能是資料庫設定導致或者重複執行的SQL頻繁訪問一些相同的資料塊導致。
latch有40餘種,但作為DBA關心的主要應有以下幾種:
Cache buffers chains latch: 當使用者程式搜尋SGA尋找database cache buffers時需要使用此latch。
Cache buffers LRU chain latch: 當使用者程式要搜尋buffer cache中包括所有 dirty blocks的LRU (least recently used) 鏈時使用該種latch。
Redo log buffer latch: 這種latch控制redo log buffer中每條redo entries的空間分配。
Row cache objects latch: 當使用者程式訪問快取的資料字典數值時,將使用Row cache objects latch。
下 面我們將著重介紹一下如何檢測和減少redo log buffer latch的衝突。對redo log buffer的訪問是由redo log buffer latch來控制的,這種latch有兩種型別, redo allocation latch和redo copy latch。
Redo allocation latch控制redo entries在redo log buffer中的空間分配。Oracle的一個使用者程式只有得到redo allocation latch後才能為redo entries在redo log buffer中分配空間,又由於一個instance只有一個redo allocation latch,所以一次只有一個使用者程式在buffer中分配空間。當使用者程式獲得latch後,首先為redo entry分配空間,然後程式繼續持有latch並複製entry到buffer中,這種複製稱為“在redo allocation latch上的複製”(copying on the redo allocation latch),複製完畢後,使用者程式釋放該latch。
一個“在redo allocation latch上的複製”的redo entry的最大值是由初始化引數LOG_SMALL_ENTRY_MAX_SIZE定義的,根據作業系統的不同而不同。
Redo Copy Latch只應用於多CPU的系統。在多CPU的instance中,如果一個redo entry太大,超過了LOG_SMALL_ENTRY_MAX_SIZE定義值,則不能進行“在redo allocation latch上的複製”, 此時使用者程式必須獲取redo copy latch。一個instance中可以有多個redo copy latch,其數目由初始引數LOG_SIMULTANEOUS_COPIES決定,預設值為CPU數目。
在單CPU情況下,不存在redo copy latch,所有的redo entry無論大小, 都進行“在redo allocation latch上的複製”。
對redo log buffer的過多訪問將導致redo log buffer latch的衝突,latch衝突將降低系統效能,我們可透過如下查詢來檢測這種latch衝突:
col name for a40
SELECT ln.name,gets,misses,immediate_gets,immediate_misses
FROM v$latch l,v$latchname ln
WHERE ln.name IN('redo allocation','redo copy') AND ln.latch#=l.latch#
/
若misses與gets的比例超過1%或immediate_misses與(immediate_gets+immediate_misses)比例超過1%時,應考慮採取措施減少latch的衝突。
大 多數的redo log buffer latch衝突是在多個CPU情況下,兩個或多個Oracle程式試圖同時得到相同的latch發生的。由於一個instance只有一個redo allocation latch,為減少redo allocation latch的衝突,應減少單個程式持有latch的時間,這可以透過減小初始引數LOG_SMALL_ENTRY_MAX_SIZE以減小redo entry的數目和大小來實現。如果觀察到有redo copy latch衝突,可以透過增大LOG_SIMULTANEOUS_COPIES 初始引數來加大latch數目,其預設值為CPU數目,最大可增大到CPU數目的兩倍。
8.請寫出rownum與rowid的區別
rownum只是你查詢出來結果集的一個臨時排列序號,必須從1開始,可以看作是隨便可以變化的!
rowid是對於每一條資料的地址,你可以把它看作是固定的(頻繁更新,刪除操作除外)
當你從某個表中查詢資料的時候,返回的結果集中都會帶有rownum這個欄位,而且有時候也可以使用rownum進行一些條件查詢。
rownum是在得到結果集的時候產生的,用於標記結果集中結果順序的一個欄位,這個欄位被稱為“偽數列”,也就是事實上不存在的一個數列。它的特點是按順序標記,而且是逐次遞加的,換句話說就是隻有有rownum=1的記錄,才可能有rownum=2的記錄。
和rownum相似,oracle還提供了另外一個偽數列:rowid。不過rowid和rownum不同,一般說來每一行資料對應的rowid是固定而且唯一的,在這一行資料存入資料庫的時候就確定了。可以利用rowid來查詢記錄,而且透過rowid查詢記錄是查詢速度最快的查詢方法。(這個我沒有試過,另外要記住一個長度在18位,而且沒有太明顯規律的字串是一個很困難的事情,所以我個人認為利用rowid查詢記錄的實用性不是很大)rowid只有在表發生移動(比如表空間變化,資料匯入/匯出以後),才會發生變化。
1、ROWNUM
定義: ROWNUM是一個偽列,標識了select從一個表或一組連線(JOIN)的表中查詢資料時,返回記錄的順序。
Oracle在執行select查詢時,會按照返回的row的順序,依次為row分配一個序號:
返回的第一條row的序號為1,第二條row的序號為2,以此類推。
這個序號即為每條row的rownum。
注意1:同一個查詢語句中,如果ROWNUM後,含有ORDER BY子句時:
Oracle先返回未應用ORDER BY處理的結果,分配ROWNUM後,再根據ORDER BY子句的要求排序。
因此,返回的結果中,ROWNUM順序是混亂的。如:
SQL> SELECT ROWNUM,DEPT.* FROM SCOTT.DEPT ORDER BY DNAME;
ROWNUM DEPTNO DNAME LOC
-------------- ------------- -------------------- -------------
1 10 ACCOUNTING NEW YORK
4 40 OPERATIONS BOSTON
2 20 RESEARCH DALLAS
3 30 SALES CHICAGO
未應用ORDER BY的結果為:
SQL> SELECT ROWNUM,DEPT.* FROM SCOTT.DEPT;
ROWNUM DEPTNO DNAME LOC
-------------- ------------- ---------------------- -------------
1 10 ACCOUNTING NEW YORK
2 20 RESEARCH DALLAS
3 30 SALES CHICAGO
4 40 OPERATIONS BOSTON
欲使ORDER BY後的ROWNUM連續,可將ORDER BY放入子查詢,如:
SQL> SELECT ROWNUM,T.* FROM (SELECT DEPT.* FROM SCOTT.DEPT ORDER BY LOC) T;
ROWNUM DEPTNO DNAME LOC
-------------- ------------- --------------------- -------------
1 40 OPERATIONS BOSTON
2 30 SALES CHICAGO
3 20 RESEARCH DALLAS
4 10 ACCOUNTING NEW YORK
注意2:對ROWNUM應用>,>=,=,between...and條件,返回結果都為空:
因為,當返回第一條記錄,作為結果的第1條,分配rownum=1,
應用>,>=,=,between...and條件判斷時,不滿足條件,記錄刪除;
返回下一條記錄時,仍作為結果的第1條,分配rownum=1,仍不滿足條件,依次類推,結果為空。
select rownum from test where rownum=1; //返回1條記錄(結果集中的第一條)
select rownum from test where rownum=2;
//返回0條。根據ROWNUM定義,不難看出,返回第1條記錄時,因ROWNUM=1,因此過濾掉。
select rownum from test where rownum>10;
select rownum from test where rownum between 2 and 4;
應用:
1)可透過ROWNUM限制返回結果的記錄數(行數)
SQL> select rownum from test where rownum<10;
2)透過ROWNUM為表中某列產生一個唯一(UNIQUE)值
SQL> UPDATE table_name SET column_name = ROWNUM;
//將rownum指定為該行某列的值。
二、ROWID
(一)、概念:行的ROWID標識了該行資料的地址,ROWID包含如下資訊:
資料物件編號、
該行資料,在資料檔案中的塊編號
該行在資料塊中的位置(第一行為0)
儲存該行資料的資料檔案的編號(第一個資料檔案為1)
ROWID在插入資料時建立,在刪除資料時,刪除。
不能手動設定或刪除ROWID,ORACLE內部透過ROWID組建索引;
(二)、型別
1、物理ROWID:儲存普通表(不含索引組織的表IOT)、聚合表(clustered table)、分割槽和子分割槽表、索引、分割槽和子分割槽索引中行的地址;
2、邏輯ROWID:儲存索引組織表(IOT)的地址;
(三)、物理ROWID
1、型別:物理ROWID包含擴充套件ROWID與受限ROWID兩類
1)、擴充套件ROWID(extended rowid)
支援表空間關聯的資料塊地址,有效標識分割槽表、分割槽索引以及普通表和索引中的行。
Oracle 8i及更高版本支援extended rowid。
2)、受限ROWID(restricted rowid)
為了向後相容,如oracle 7及更低版本。
2、擴充套件ROWID(extended rowid)
a.擴充套件ROWID使用base64為每一行資料的實體地址進行編碼,包含A-Z,a-z,0-9,+以及/。如下查詢:
SQL> select rowid,dept.* from dept;
ROWID DEPTNO DNAME LOC
-------------------------------- ------------ -------------------- ----------------
AAAMfKAAEAAAAAQAAA 10 ACCOUNTING NEW YORK
AAAMfKAAEAAAAAQAAB 20 RESEARCH DALLAS
AAAMfKAAEAAAAAQAAC 30 SALES CHICAGO
AAAMfKAAEAAAAAQAAD 40 OPERATIONS BOSTON
b.擴充套件ROWID格式
擴充套件ROWID共18位,包含4部分,OOOOOOFFFBBBBBBRRR
a)000000:資料物件編號,標識了資料庫中的段;
b)FFF:表空間相關的資料檔案編號;
c)BBBBBB:資料檔案中的資料塊編號;
d)RRR:在資料塊中的行編號;
c.DBMS_ROWID包
a)dbms_rowid.rowid_object透過ROWID,獲取該資料的物件編號
SQL> select dbms_rowid.rowid_object('AAAMfKAAEAAAAAQAAC') as object_id from dual;
OBJECT_ID
----------------
51146
b)dbms_rowid.rowid_relative_fno透過ROWID獲取資料檔案編號
SQL> select dbms_rowid.rowid_relative_fno('AAAMfKAAEAAAAAQAAC') as file_no from dual;
FILE_NO
-------------
4
c)dbms_rowid.rowid_block_number透過ROWID,獲取該資料的資料塊編號
SQL> select dbms_rowid.rowid_block_number('AAAMfKAAEAAAAAQAAC') as block_number from dual;
BLOCK_NUMBER
------------------------
16
d)dbms_rowid.rowid_row_number透過ROWID,獲取資料塊中的行編號
SQL> select dbms_rowid.rowid_row_number('AAAMfKAAEAAAAAQAAC') as row_no from dual;
ROW_NO
----------
2
3、受限ROWID(resticted rowid)
a.受限rowid用二進位制表示每行資料的實體地址,當使用SQL Plus查詢時,二進位制表示法被轉換為varchar2或16進製表示。
SQL> select dbms_rowid.rowid_to_restricted(rowid,1) as restricted_rowid,dept.* from scott.dept;
RESTRICTED_ROWID DEPTNO DNAME LOC
------------------------------- ------------- --------------------- ------------------
00000010.0000.0004 10 ACCOUNTING NEW YORK
00000010.0001.0004 20 RESEARCH DALLAS
00000010.0002.0004 30 SALES CHICAGO
00000010.0003.0004 40 OPERATIONS BOSTON
b.受限rowid格式:
共16位,包含3部分:AAAAAAAA.BBBB.CCCC
a)AAAAAAAA:儲存該行資料的資料塊編號
b)BBBB:該行資料在資料塊中的行編號
c)CCCC:包含該行資料的資料檔案編號
(四)、邏輯ROWID(logical rowid)
1、概述:索引組織的表(IOT)中,row儲存在索引的葉子節點,可以在塊內或塊間移動。
因此,這些rows沒有固定的實體地址,無法根據實體地址來唯一標識。
Oracle提供了邏輯ROWID,來標識IOT中的行,邏輯ROWID是基於表的主鍵;
Oracle可根據這些邏輯ROWID為IOT建立第二索引。
每個第二索引使用的邏輯ROWID都包含一個physical guess;physical guess標識了當建立第二索引時,IOT中每個row的塊位置;
9.請寫出丟失非當前重做日誌時應如何處理
Oracle的重做日誌檔案(Online redo logfile)迴圈記錄了資料庫所有的事務。它的大小、個數和儲存位置對資料庫效能和恢復有重要影響。它一般由大小相同的幾組檔案構成。我們可以檢視資料庫檢視v$logfile知道redo logfile的個數和儲存位置。對每一個Oracle資料庫都要求至少具有兩個聯機重做日誌。
每一次新的事務提交時,Oracle將該事務寫入日誌檔案,但並非此時也將修改的資料塊寫回原資料檔案。由於記憶體讀寫和磁碟I/O存在幾個數量級的效率差別,Oracle透過減少資料檔案的物理I/O讀寫來大大提高資料庫的效能;同時,又透過優先寫日誌檔案來保證資料的正確性和一致性。基於這種機制,重做日誌檔案在資料庫的例項恢復和介質恢復時至關重要,是oracle資料庫最重要的物理檔案之一。
如果資料庫在啟動時檢測到重做日誌丟失,資料庫將無法啟動。如果資料庫在執行時切換日誌檔案組,檢測到下一組或者全部的重做日誌丟失,資料庫將會崩潰。由於磁碟介質損壞或者人為的誤刪除檔案,造成嚴重後果的事件近期時有發生。本文列舉了重做日誌丟失的資料庫恢復,但如果按照冗餘原則合理分佈日誌檔案組的成員,如果工程師瞭解日誌檔案的基本原理和使用原則,就完全可以避免出現下列問題。
恢復方法
故障現象
SQL> startup mount
Oracle Instance Started
Database mounted
ORA-00313: open failed for members of log group 1 of thread 1
ORA-00312: online log 1 thread 1: '/ORACLE/ORADATA/H817/REDO01.LOG'
ORA-27041: unable to open file
OSD-04002: unable to open file
O/S-Error: (OS 2) The system cannot find the file specified.
恢復注意事項
以下所列舉的恢復方法,都屬於不完全恢復或者強制恢復,會丟失當前重做日誌中的事務資料。一旦操作不當,將帶來資料丟失等嚴重後果,請遵循以下幾個恢復原則:
1.請勿在生產系統上試用。
2.如果生產系統出現重做日誌檔案丟失的故障,請勿自行操作破壞現場,應該立刻聯絡Oracle工程師。
3.恢復成功之後,需要馬上做一次資料庫的全備份。
4.建議重做日誌檔案一定要實現鏡象在不同的磁碟上,避免這種情況的發生。
恢復方法
1.首先檢查重做日誌檔案狀態,看看報錯的日誌檔案的狀態是否為Current
SQL> select * from v$log;
SQL> select * from v$logfile;
2.如果重做日誌檔案狀態為Inactive,我們可以直接清除該日誌檔案的內容:
SQL> alter database clear logfile '/ORACLE/ORADATA/H817/REDO01.LOG';
3.如果重做日誌檔案狀態為Current,恢復工作較為複雜,有以下四種情況:
1)透過下面步驟,資料庫順利開啟
SQL> recover database until cancel;
Type Cancel when prompted
SQL>alter database open resetlogs;
2)第一種情況的'recover database until cancel' 操作遇到ORA-01547,ORA-01194,ORA-01110錯誤,需要整個資料庫的物理備份,並根據歸檔日誌恢復到錯誤時間點,前提是資料庫是歸檔模式。
restore old backup
SQL> startup mount
SQL> recover database until cancel using backup controlfile;
SQL> alter database open resetlogs;
3)如果資料庫是非歸檔模式,只能恢復整個物理備份,然後直接開啟資料庫。這種情況將丟失物理備份至故障發生前的全部資料。
4)如果資料庫是非歸檔模式,且沒有物理備份,只能透過特殊的隱含引數,允許資料庫不一致的狀況下開啟資料庫。這種恢復方法是沒有辦法之後的恢復方法,將導致資料庫不一致,一般情況下不要採用。如確有需要,請在Oracle的技術人員指導下使用該方法。
l 關閉資料庫
SQL>shutdown immediate
l 在init
_allow_resetlogs_corruption=TRUE
l 重新啟動資料庫,利用until cancel恢復
SQL>recover database until cancel;
Cancel
l 開啟資料庫
SQL>alter database open resetlogs;
l 資料庫被開啟後,馬上執行一個全庫匯出。
關閉資料庫,在init
10.請寫出引數檔案的作用
下面是是我對引數檔案的一點總結
分為二類:
1.初始引數檔案:pfile(initialization parameter file)
2.伺服器引數檔案:spfile(server-side parameter file)
主要的區別是:
1.pfile是文字檔案,spfile是二進位制檔案
2.pfile可以透過文字編輯器修改,spfile主要是透過alter system set parameter=value [scope=memory|spfile|both]修改
oracle啟動時,讀取引數檔案的順序是:
1.spfile$ORACLE_SID.ORA(建立資料庫時建立的spfile)
2.spfile.ora(oracle預設spfile檔案)
3.init$ORACLE_SID.ora(建立資料庫時建立的pfile)
4.init.ora(oracle預設pfile檔案)
oracle會按順序讀出這些引數檔案,如果在1沒有找到就去找2,直到找到。
和引數檔案相關常用SQL如下:
1.檢視當前使用的spfile和pfile的位置:
show parameter spfile/show parameter pfile
2.檢視引數檔案的具體設定
show parameters
3.從spfile獲取pfile
create pfile='pfilesid.ora' from spfile或者
create pfile='pfilesid.ora' from spfile='/$ORACLE_HOME/dbs/spfile.ora'
4.修改引數
alter system set parameter=value [scope=memory|spfile|both]
1.修改後當前就起作用,重啟資料庫不起作用
scope=memory
2.修改後當前不起作用,下次重啟資料庫才起作用
scope=spfile
3.修改後當前起作用,下次重啟資料庫也起作用
scope=both
Notice:命令alter system set parameter=value在沒有加scope選項時,預設值是什麼呢?多數朋友可能不加思索就會回答both這答案,實際的情況是,當oracle在以spfile引數啟動時,預設值是both,而以pfile啟動時,預設值是memory,也就是隻修改當前值。所以如果不能確定啟動的引數檔案,可以用show parameter spfile檢視。
5.指定初始引數檔案啟動資料庫
startup pfile='/$ORACLE_HOME/dbs/init$ORACLE_SID.ora'
不能以指定伺服器引數檔案spfile來啟動資料庫
可以先將spfile轉換成pfile,再用這個命令來達到目的
6.檢視系統是以pfile還是spfile啟動
show parameter spfile
如果是null值,就是pfile啟動的
11.請寫出event 10053的作用是什麼
藉助Oracle的10053事件event,我們可以監控到CBO對SQL進行成本計算和路徑選擇的過程和方法。
10053事件有兩個級別:
Level 2:2級是1級的一個子集,它包含以下內容:
Column statistics
Single Access Paths
Join Costs
Table Joins Considered
Join Methods Considered (NL/MS/HA)
Level 1: 1級比2級更詳細,它包含2級的所有內容,在加如下內容:
Parameters used by the optimizer
Index statistics
啟用10053事件
ALTER SESSION SET EVENTS '10053 trace name context forever, level 1';
ALTER SESSION SET EVENTS '10053 trace name context forever, level 2';
關閉10053事件:
ALTER SESSION SET EVENTS '10053 trace name context off';
說明:
1、sqlplus中開啟autotrace看到的執行計劃實際上是用explain plan 命令得到的,explain plan 命令不會進行bind peeking。
應該透過v$sql_plan檢視SQL的真實的執行計劃。
2、10053只對CBO有效,而且如果一個sql語句已經解析過,就不會產生新的trace資訊。
3、10053事件產生的trace檔案不能用tkprof格式化。
12.請寫出hash join 與nest loop的實現原理
nest loop:多用於聯機業務 OLTP (exists)
巢狀迴圈連線的工作方式是這樣的:
1、 Oracle首先選擇一張表作為連線的驅動表,這張表也稱為外部表(Outer Table)。由驅動表進行驅動連線的表或資料來源稱為內部表(Inner Table)。
2、 提取驅動表中符合條件的記錄,與被驅動表的連線列進行關聯查詢符合條件的記錄。在這個過程中,Oracle首先提取驅動表中符合條件的第一條記錄,再與內部表的連線列進行關聯查詢相應的記錄行。在關聯查詢的過程中,Oracle會持續提取驅動表中其他符合條件的記錄與內部表關聯查詢。這兩個過程是並行進行的,因此巢狀迴圈連線返回前幾條記錄的速度是非常快的。在這裡需要說明的是,由於Oracle最小的IO單位為單個資料塊,因此在這個過程中Oracle會首先提取驅動表中符合條件的單個資料塊中的所有行,再與內部表進行關聯連線查詢的,然後提取下一個資料塊中的記錄持續地迴圈連線下去。當然,如果單行記錄跨越多個資料塊的話,就是一次單條記錄進行關聯查詢的。
Hash join:多用於批處理業務 (in)
一般用於一張小表和一張大表進行join時。Hash join的過程大致如下(下面所說的記憶體就指sort area,關於過程,後面會作詳細討論):
1.一張小表被hash在記憶體中。因為資料量小,所以這張小表的大多數資料已經駐入在記憶體中,剩下的少量資料被放置在臨時表空間中;
2.每讀取大表的一條記錄,就和小表中記憶體中的資料進行比較,如果符合,則立即輸出資料(也就是說沒有讀取臨時表空間中的小表的資料)。而如果大表的資料與小表中臨時表空間的資料相符合,則不直接輸出,而是也被儲存臨時表空間中。
3.當大表的所有資料都讀取完畢,將臨時表空間中的資料以其輸出。
如果小表的資料量足夠小(小於hash area size),那所有資料就都在記憶體中了,可以避免對臨時表空間的讀寫。
如果是並行環境下,前面中的第2步就變成如下了:
2.每讀取一條大表的記錄,和記憶體中小表的資料比較,如果符合先做join,而不直接輸出,直到整張大表資料讀取完畢。如果記憶體足夠,Join好的資料就儲存在記憶體中。否則,就儲存在臨時表空間中。
NESTED LOOP
對於被連線的資料子集較小的情況,nested loop連線是個較好的選擇。nested loop就是掃描一個表,每讀到一條記錄,就根據索引去另一個表裡面查詢,沒有索引一般就不會是 nested loops。
一般在nested loop中, 驅動表滿足條件結果集不大,被驅動表的連線欄位要有索引,這樣就走nestedloop。如果驅動表返回記錄太多,就不適合nested loops了。如果連線欄位沒有索引,則適合走hash join,因為不需要索引。
可用ordered提示來改變CBO預設的驅動表,可用USE_NL(table_name1 table_name2)提示來強制使用nested loop。
HASH JOIN
hash join是CBO 做大資料集連線時的常用方式。最佳化器掃描小表(或資料來源),利用連線鍵(也就是根據連線欄位計算hash 值)在記憶體中建立hash表,然後掃描大表,每讀到一條記錄就來探測hash表一次,找出與hash表匹配的行。
當小表可以全部放入記憶體中,其成本接近全表掃描兩個表的成本之和。如果表很大不能完全放入記憶體,這時最佳化器會將它分割成若干不同的分割槽,不能放入記憶體的部分就把該分割槽寫入磁碟的臨時段,此時要有較大的臨時段從而儘量提高I/O 的效能。臨時段中的分割槽都需要換進記憶體做hash join。這時候成本接近於全表掃描小表+分割槽數*全表掃描大表的代價和。
至於兩個表都進行分割槽,其好處是可以使用parallel query,就是多個程式同時對不同的分割槽進行join,然後再合併。但是複雜。
使用hash join時,HASH_AREA_SIZE初始化引數必須足夠的大,如果是9i,Oracle建議使用SQL工作區自動管理,設定WORKAREA_SIZE_POLICY 為AUTO,然後調整PGA_AGGREGATE_TARGET即可。
以下條件下hash join可能有優勢:
兩個巨大的表之間的連線。
在一個巨大的表和一個小表之間的連線。
可用ordered提示來改變CBO預設的驅動表,可用USE_HASH(table_name1 table_name2)提示來強制使用hash join。
SORT MERGE JOIN
sort merge join的操作通常分三步:對連線的每個表做table access full;對table access full的結果進行排序;進行merge join對排序結果進行合併。sort merge join效能開銷幾乎都在前兩步。一般是在沒有索引的情況下,9i開始已經很少出現了,因為其排序成本高,大多為hash join替代了。
通常情況下hash join的效果都比sort merge join要好,然而如果行源已經被排過序,在執行sort merge join時不需要再排序了,這時sort merge join的效能會優於hash join。
在全表掃描比索引範圍掃描再透過rowid進行表訪問更可取的情況下,sort merge join會比nested loops效能更佳。
可用USE_MERGE(table_name1 table_name2)提示強制使用sort merge join。
13.請描述行連線與行遷移的原理
有兩種情況會導致表中某行資料過大,一個資料塊(data block)無法容納。
行連結:當一行資料被插入時一個資料塊就無法容納。在這種情況下Oracle將這行資料儲存在段內的一個資料塊鏈(chain)中。在插入資料量大的行時常會發生行連結(row chaining),例如一個包含資料型別為 LONG 或 LONG RAW 列的資料行。此時行連結不可避免。
行遷移:原本儲存在一個資料塊(data block)內的資料行,因為更新操作導致長度增長,而所在資料塊的可用空間也不能容納增長後的資料行。在這種情況下,Oracle將此行資料遷移(migrate)到新的資料塊中。Oracle在被遷移資料行原來所在位置儲存一個指向新資料塊的指標。被遷移資料行的 rowid 保持不變。
當資料行發生連結(chain)或遷移(migrate)時,對其訪問將會造成 I/O 效能降低,因為Oracle為獲取這些資料行的資料時,必須訪問更多的資料塊(data block)。
14.請寫出pctfree及pctused的作用
PCTFREE 引數用來設定一個資料塊(data block)中至少需要保留(reserve)多少可用空間(百分比值),為資料塊中已有資料更新時可能發生的資料量增長做準備。例如,當使用者用 CREATE TABLE 語句建立表時指定了以下引數:PCTFREE 20
這個引數設定了此表對應的資料段(data segment)中的每個資料塊(data block)至少保留20%的可用空間,以備塊中已有資料更新時使用。只要資料塊中行資料區與資料塊頭的容量之和不超過資料塊總容量的80%,使用者就可以向其中插入新資料,資料行被放入行資料區(row data area),相關資訊被寫入資料塊頭(overhead area)。
PCTUSED 引數用於決定一個資料塊(data block)是否可被用於插入新資料,她的依據是資料區(row data)與資料塊頭(overhead)的容量之和佔資料塊全部容量的最大百分比。當一個資料塊中的可用空間比例小於 PCTFREE 引數的規定時,Oracle就認為此資料塊無法被用於插入新資料,直到資料塊中的佔用容量比例小於 PCTUSED 引數的限定。在佔用容量比例大於 PCTUSED 引數的限定之前,Oracle只在更新資料塊內已有資料時才會使用此資料塊的可用空間。例如,當使用者用 CREATE TABLE 語句建立表時指定了以下引數:PCTUSED 40
在例子中,當此表的某資料塊佔用容量比例高於40%時,Oracle不會將此資料塊用於插入新資料行(假設此資料塊的可用空間曾經低於 PCTFREE 的限定)。
15.請寫出分割槽表的作用
分割槽表的作用:提高查詢速度(查詢資料的時候不會再對錶進行全部掃描,而掃描相應的分割槽表),在表進行分割槽之後,邏輯上還是一張表,實際上已經把插入的資料分到了各個分割槽表中,資料物理的分到不同的分割槽表中。當一個分割槽損壞後,不影響其他分割槽中的資料。
分割槽表的型別:1)按範圍進行分割槽2)列表分割槽3)雜湊分割槽4)範圍列表組合5)範圍散弄組合。
分割槽技術能夠帶來以下好處:
1)利用分割槽技術,使用者可以在分割槽級(partition level)進行資料載入(data load),索引建立及重建,或備份恢復等資料管理操作,而非針對整個表執行。這大大減少了此類操作所需時間。
2)分割槽技術能夠提高查詢效能。在很多情況下,查詢的結果集可能來自幾個分割槽,而非整個表。 對於某些查詢,這種技術(稱為分割槽剪除(partition pruning))能夠帶來幾個資料量級的效能提升。
3)分割槽技術能夠顯著縮短維護操作導致的停機時間。
4)由於對各分割槽的維護操作可以相互獨立地進行,使用者可以同時對錶或索引的不同分割槽進行維護操作。使用者還能在維護的同時對未受維護操作影響的分割槽執行 SELECT 及 DML 操作。
5)利用分割槽技術儲存資料庫中的關鍵表及索引,能夠縮短此類物件的維護視窗(maintenance window),及恢復時間,並減少此類物件發生故障時對系統的影響,從而提高資料庫的可用性。
6)採用分割槽技術時,使用者無需對原有應用程式進行任何修改。例如,當使用者將一個非分割槽錶轉化為分割槽表後,無需修改訪問此表的 SELECT 語句及 DML 語句。使用者無需重寫應用程式程式碼就可以發揮分割槽技術的優勢。
16.請寫出引數session_cached_cursors 的作用
open_cursors:該引數含義是同一個session同時開啟最多在使用的遊標數。在Oracle10.2.0.1.0版本中預設為300。
session_cached_cursors:SESSION_CACHED_CURSORS, 就是說的是一個session可以快取多少個cursor,讓後續相同的SQL語句不再開啟遊標,從而避免軟解析的過程來提高效能。(繫結變數是解決硬解析的問題),軟解析同硬解析一樣,比較消耗資源.所以這個引數非常重要。在Oracle10.2.0.1.0版本中預設為20。
show parameter open_cursors ----每個session(會話)最多能同時開啟多少個cursor(遊標)
show parameter session_cached_cursors ----每個session(會話)最多可以快取多少個關閉掉的cursor
select count(*) from v$open_cursor; ----是指當前例項的某個時刻的開啟的cursor數目 COUNT(*)
a、兩個引數之間沒有任何關係,相互也不會有任何影響。
b、兩個引數有著相同的作用:讓後續相同的sql語句不在開啟遊標,從而避免軟解析過程來提供應用程式的效率。
cursor的作用 open ->close. 頻繁的開關會產生開銷。SESSION_CACHED_CURSORS適當的增加提高了快取open cursor的數量,減少了頻繁開關的開銷。
使用下面的sql判斷session_cached_cursors的使用情況。如果使用率為100%則增大這個引數值。
Select 'session_cached_cursors' Parameter,
Lpad(Value, 5) Value,
Decode(Value, 0, ' n/a', To_Char(100 * Used / Value, '990') || '%') Usage
From (Select Max(s.Value) Used
From V$statname n, V$sesstat s
Where n.Name = 'session cursor cache count'
And s.Statistic# = n.Statistic#),
(Select Value From V$parameter Where Name = 'session_cached_cursors')
Union All
Select 'open_cursors',
Lpad(Value, 5),
To_Char(100 * Used / Value, '990') || '%'
From (Select Max(Sum(s.Value)) Used
From V$statname n, V$sesstat s
Where n.Name In
('opened cursors current', 'session cursor cache count')
And s.Statistic# = n.Statistic#
Group By s.Sid),
(Select Value From V$parameter Where Name = 'open_cursors');
17.請寫出臨時表空間的作用
1、臨時表空間的作用:
臨時表空間主要用途是在資料庫進行排序運算、管理索引、訪問檢視等操作時提供臨時的運算空間,當運算完成之後系統會自動清理。
當臨時表空間不足時,表現為運算速度異常的慢,並且臨時表空間迅速增長到最大空間(擴充套件的極限),並且一般不會自動清理了。
2、迅速增長的原因:
一般原因是sql演算法不正確,可能導致出現了迪卡爾積。
另外一個原因是檢視的建立問題(本人遇到的正是該問題!)。Oracle資料庫中多張表聯合查詢時,極限的表單數量為4張,一般將以為3張!有時需要大於4張表聯合查詢時,怎麼辦呢?可以建立子檢視:
如view0(聯合table0,table1,table2),view1(聯合table0,table3,table4),view2(聯合table0,table5,table6)
然後將view0、view1、view2聯合成view。
這樣可以解決臨時表空間迅速增長的問題!
臨時表空間使用注意:
1.臨時表空間 是用於在進行排序操作(如大型查詢,建立索引和聯合查詢期間儲存臨時資料)
每個使用者都有一個臨時表空間
2.對於大型操作頻繁,(大型查詢,大型分類查詢,大型統計分析等),應指定單獨的臨時表空間,以方便管理
3.分配使用者單獨臨時表空間,一般是針對 大型產品資料庫,OLTP資料庫,資料庫倉庫
對於小型產品不需要單獨制定臨時表空間,使用預設臨時表空間
當然解決方法也很簡單:1、設定臨時資料檔案自動擴充套件,或者2、增大臨時表空間。
擴充套件臨時表空間:
方法一、增大臨時檔案大小:
SQL> alter database tempfile ‘/u01/app/oracle/oradata/orcl/temp01.dbf’ resize 100m;
Database altered.
方法二、將臨時資料檔案設為自動擴充套件:
SQL> alter database tempfile ‘/u01/app/oracle/oradata/orcl/temp01.dbf’ autoextend on next 5m maxsize unlimited;
Database altered.
方法三、向臨時表空間中新增資料檔案:
SQL> alter tablespace temp add tempfile ‘/u01/app/oracle/oradata/orcl/temp02.dbf’ size 100m;
18.請寫出全域性索引及本地索引的區別
區域性索引local index
1. 區域性索引一定是分割槽索引,分割槽鍵等同於表的分割槽鍵,分割槽數等同於表的分割槽數,一句話,區域性索引的分割槽機制和表的分割槽機制一樣。
2. 如果區域性索引的索引列以分割槽鍵開頭,則稱為字首區域性索引。
3. 如果區域性索引的列不是以分割槽鍵開頭,或者不包含分割槽鍵列,則稱為非字首索引。
4. 字首和非字首索引都可以支援索引分割槽消除,前提是查詢的條件中包含索引分割槽鍵。
5. 區域性索引只支援分割槽內的唯一性,無法支援表上的唯一性,因此如果要用區域性索引去給表做唯一性約束,則約束中必須要包括分割槽鍵列。
6. 區域性分割槽索引是對單個分割槽的,每個分割槽索引只指向一個表分割槽,全域性索引則不然,一個分割槽索引能指向n個表分割槽,同時,一個表分割槽,也可能指向n個索引分割槽, 對分割槽表中的某個分割槽做truncate或者move,shrink等,可能會影響到n個全域性索引分割槽,正因為這點,區域性分割槽索引具有更高的可用性。
7. 點陣圖索引只能為區域性分割槽索引。
8. 區域性索引多應用於資料倉儲環境中。
全域性索引global index
1. 全域性索引的分割槽鍵和分割槽數和表的分割槽鍵和分割槽數可能都不相同,表和全域性索引的分割槽機制不一樣。
2. 全域性索引可以分割槽,也可以是不分割槽索引,全域性有分割槽索引必須是字首索引,即全域性索引的索引列必須是以索引分割槽鍵作為其前幾列。
3. 全域性分割槽索引的索引條目可能指向若干個分割槽,因此,對於全域性分割槽索引,即使只動,截斷一個分割槽中的資料,都需要rebulid若干個分割槽甚至是整個索引。
4. 全域性索引多應用於oltp系統中。
5. 全域性分割槽索引只按範圍或者雜湊hash分割槽,hash分割槽是10g以後才支援。
6. oracle9i以後對分割槽表做move或者truncate的時可以用update global indexes語句來同步更新全域性分割槽索引,用消耗一定資源來換取高度的可用性。
7. 表用a列作分割槽,索引用b做區域性分割槽索引,若where條件中用b來查詢,那麼oracle會掃描所有的表和索引的分割槽,成本會比分割槽更高,此時可以考慮用b做全域性分割槽索引。
19.請寫出如何定位消耗資源多的SQL
statspack-- 在你庫上業務最忙得時候抓15分鐘的report,看裡面的top sql///////awr/ash
1 top找到消耗資源多的pid
2 確定是oracle的應用程式還是後臺程式
3 根據v$session,v$process,v$sqlarea定位
用oem帶的top session
SELECT hash_value, executions, buffer_gets, disk_reads, parse_calls FROM V$SQLAREA
WHERE buffer_gets > 10000000 OR disk_reads > 1000000
ORDER BY buffer_gets + 100 * disk_reads DESC
1. 值得懷疑的SQL
select substr(to_char(s.pct, '99.00'), 2) || '%' load, s.executions executes, p.sql_text from (select address,disk_reads,executions,pct,rank() over(order by disk_reads desc) ranking from (select address,disk_reads,executions,100 * ratio_to_report(disk_reads) over() pct from sys.v_$sql where command_type != 47) where disk_reads > 50 * executions) s, sys.v_$sqltext p where s.ranking <= 5 and p.address = s.address order by 1, s.address, p.piece;
2、檢視消耗記憶體多的sql
select b.username,a. buffer_gets,a.executions,a.disk_reads / decode(a.executions, 0, 1, a.executions),a.sql_text SQL from v$sqlarea a, dba_users b where a.parsing_user_id = b.user_id and a.disk_reads > 10000 order by disk_reads desc;
3.邏輯讀多的SQL
select * from (select buffer_gets, sql_text from v$sqlarea where buffer_gets > 500000 order by buffer_gets desc) where rownum <= 30;
4.執行次數多的SQL
select sql_text, executions from (select sql_text, executions from v$sqlarea order by executions desc) where rownum < 81;
5. 讀硬碟多的SQL
select sql_text, disk_reads from (select sql_text, disk_reads from v$sqlarea order by disk_reads desc) where rownum < 21;
6. 排序多的SQL
select sql_text, sorts from (select sql_text, sorts from v$sqlarea order by sorts desc) where rownum < 21;
7.分析的次數太多,執行的次數太少,要用綁變數的方法來寫sql
set pagesize 600;
set linesize 120;
select substr(sql_text, 1, 80) "sql", count(*), sum(executions) "totexecs" from v$sqlarea where executions < 5 group by substr(sql_text, 1, 80) having count(*) > 30 order by 2;
8.遊標的觀察
set pages 300;
select sum(a.value), b.name from v$sesstat a, v$statname b where a.statistic# = b.statistic# and b.name = 'opened cursors current'group by b.name;
select count(0) from v$open_cursor;
select user_name, sql_text, count(0) from v$open_cursor group by user_name, sql_text having count(0) > 30;
9.檢視當前使用者&username執行的SQL
select sql_text from v$sqltext_with_newlines where (hash_value, address) in (select sql_hash_value, sql_address from v$session where username = '&username') order by address, piece;
20.請寫出oracle主要後臺程式的作用
Oracle中的程式共分為三類:使用者程式、服務程式、後臺程式。其中後臺程式伴隨例項的啟動而啟動,他們主要是維護資料庫的穩定,相當於一個企業中的管理者及內部服務人員。他們並不會直接給使用者提過服務。
一:database write:DBWn資料寫入
作用:把SGA中被修改的資料同步到磁碟檔案中。保證Buffer Cache中有足夠的空閒資料塊數量。
觸發條件:1,檢查點
2,一個服務程式在設定的時間內沒有找到空閒塊。
3,每3秒自動喚醒一次。
設定:DB_WRITER_PROCESSES用來定義DBWn程式數量。(commit命令只是把記錄修改寫入日誌檔案,不是把修改後的資料寫入資料檔案,下面還會提到。)
二:log write LGWR:日誌檔案寫入
作用:把log buffer中的日誌內容寫入聯機的日誌檔案中,釋放log使用者buffer空間呢。
觸發條件:1,使用者發出commit指令。(在oracle中稱為快速提交機制(fast commit):把redo log buffer中的記錄寫入日誌檔案,寫入一條已提交的記錄)。
2,三秒鐘定時喚醒。
3,log buffer超過1/3,或日誌數量超過1M。
4,DBWR程式觸發:DBWn試圖將髒資料塊寫入磁碟先檢查他的相關redo記錄是否寫入聯機日誌檔案,如果沒有就通知LGWR程式。
在oracle中稱為提前寫機制(write ahead):redo記錄先於資料記錄被寫入磁碟。
三:checkpoint CKPT:檢查點事件
作用:維護資料庫一致性狀態。檢查點時刻資料檔案與SGA中的內容一致。這不是一個單獨的程式,要和前兩個程式一起工作。DBWR寫入髒資料,同時觸發LGWR程式。
CKPT更新控制檔案中的檢查點記錄。
觸發條件:日誌切換(log switch)會觸發檢查點。
四:process monitor PMON :維護使用者程式
作用:1,發現使用者程式異常終止,並進行清理。釋放佔用資源。(清理異常終止使用者使用的鎖)。
2,向監聽程式動態的註冊例項。
觸發條件:定時被喚醒,其他程式也會主動喚醒他。
五:system monitor SMON:例項維護
作用:1,負責例項恢復,前滾(Roll Forward)恢復到例項關閉時刻的狀態,使用最後一次檢查點後的日誌進行重做。這時包括提交和未提交的事務。開啟資料庫,進行回滾(Roll Back):回滾未提交的事務。
(Oracle承諾commit之後的資料不會丟失,現在我們可以大致的瞭解Oracle是如何實現這個承諾的,以及在資料的安全性和資料庫效能之間的平衡選擇。)
2,負責清理臨時段,以釋放空間;
觸發條件:定期被喚醒或者被其他事務主動喚醒。
六:archive ARCn:歸檔操作
作用:發生日誌切換時把寫滿的聯機日誌檔案複製到歸檔目錄中。
觸發條件:日誌切換時被LGWR喚醒。
設定:LOG_ARCHIVE_MAX_PROCESSES可以設定oracle啟動的時候ARCn的個數。
七:manageability monitor MMON:AWR主要的程式。
作用:1收集AWR必須的統計資料,把統計資料寫入磁碟。10g中儲存在SYSAUX表空間中。
2,生成server-generated報警。
每一個小時把shard pool中的統計資訊寫入磁碟,或shard pool佔用超過5%。
八:manageability monitor light MMNL:輕量級的MMON;
九:memory manager MMAN:自動記憶體管理
作用:每分鐘都檢查AWR效能資訊,並根據這些資訊來決定SGA元件最佳分佈。
設定:STATISTICS_LEVEL:統計級別
SGA_TARGET:SGA總大小
十:job queue coordinator CJQO:資料庫定時任務
十一:recover writer RVWR:為flashback database提供日誌記錄。把資料塊的前映象寫入日誌。
十二:change tracking writer CTWR:跟蹤資料塊的變化,把資料塊地址記錄到change_tracking file檔案中。RMAN的增量備份將使用這個檔案來確定那些資料塊發生了變化,並進行備份。
以上是oracle中比較常見的後臺程式,不是所有的程式。其中DBWn,ARCn可以設定資料庫啟動時的數量。這些程式在系統中可以不止一個。
Oracle實戰類:
1.表tab1,由5列組成,存在1000萬條記錄,現查詢該表非常慢,請問如何解決該問題
首先先用查詢條件(order by等)查詢一下 如果還慢,檢視是否有索引,沒有建立索引,有索引重新建立索引。
索引結構
如何再不行,重新將表分割槽。
2.資料庫突然變得非常緩慢,請寫出診斷思路
看是否有哪些sql語句發生死鎖,堵塞
看看alert檔案有什麼錯誤或警告沒有,此外在慢的時候查查v$session_wait有什麼等待事件
看回滾空間佔用率是多少,temp空間佔用率是多少。
如果回滾空間佔用率太多,就看是什麼程式在其中佔用了大量的回滾空間,而且沒有自我釋放,一直在執行,從中,可以判斷出是什麼問題。
然後在殺資料庫的程式,將死迴圈或者其他死程式給殺了。
還有可能是臨時表空間滿了
awr
3.資料庫alert日誌中報錯ORA-01555,請寫出診斷思路
Linux下執行:oerr ora 1555檢視錯誤解釋
先看報錯,是否因為undo表空間太小,如果是,擴大undo表空間;如果不是,增加引數undo_retention;
undo基本資訊:
select inst_id,name,value from gv$parameter where upper(name) like '%UNDO%';
select distinct status,count(*) extent_num , sum(bytes/1024/1024) undosize from dba_undo_extents group by status;
4.資料庫在備份時報錯塊損壞,請寫出處理思路
如果是物理損壞,換盤,如果是邏輯損壞,先定位到塊損壞的位置。////如何定位資料塊的位置。
停止資料庫備份:用bbed來修復壞塊
recover datafile'/u01/oracle/oracle10g/oradata/TEST/test.dbf';恢復資料檔案。
5.資料庫突然異常關閉,請寫出處理思路
先重新啟動如果不行檢視alert
總結:
當發生1102錯誤時,可以按照以下流程檢查、排錯:
如果是HA系統,檢查其他節點是否已經啟動例項;
檢查Oracle程式是否存在,如果存在則殺掉程式;
檢查訊號量是否存在,如果存在,則清除訊號量;
檢查共享記憶體段是否存在,如果存在,則清除共享記憶體段;
檢查鎖記憶體檔案lk
伺服器異常斷電,導致oracle 資料庫無法開啟:
SQL> alter database open;
alter database open
*
ERROR at line 1:
ORA-16038: log 1 sequence# 8 cannot be archived
ORA-19504: failed to create file ""
ORA-00312: online log 1 thread 1: '/oracle/oradate/orcl/redo1.log'
處理過程是:
SQL> select group#, sequence# from v$log;
GROUP# SEQUENCE#
------- ----------
1 10
2 11
3 12
SQL> alter database clear unarchived logfile group 1;
Database altered.
SQL> alter database open;
Database altered.
當時沒能建立歸檔日誌的原因是對歸檔資料夾的操作許可權不夠。賦予足夠許可權以後
SQL> alter system archive log start;
System altered.
某系統突然掉電,系統啟動後發現Oracle無法啟動。啟動時報如下錯誤:
ORA-01102 cannot mount database in EXCLUSIVE mode
出現1102錯誤可能有以下幾種可能:
一、在HA系統中,已經有其他節點啟動了例項,將雙機共享的資源(如磁碟陣列上的裸裝置)佔用了;
二、說明Oracle被異常關閉時,有資源沒有被釋放,一般有以下幾種可能,
1、 Oracle的共享記憶體段或訊號量沒有被釋放;
2、 Oracle的後臺程式(如SMON、PMON、DBWn等)沒有被關閉;
3、 用於鎖記憶體的檔案lk
首先,雖然我們的系統是HA系統,但是備節點的例項始終處在關閉狀態,這點透過在備節點上查資料庫狀態可以證實。
其次、是因系統掉電引起資料庫當機的,系統在接電後被重啟,因此我們排除了第二種可能種的1、2點。最可疑的就是第3點了。
查$ORACLE_HOME/dbs目錄:
$ cd $ORACLE_HOME/dbs$ ls sgadef*sgadef* not found$ ls lk*lkORA92
果然,lk
$ rm lk*
再啟動資料庫,成功。
如果懷疑是共享記憶體沒有被釋放,可以用以下命令檢視:
$ipcs -mopIPC status from /dev/kmem
as of Thu Jul 6 14:41:43 2006T ID KEY MODE OWNER GROUP NATTCH CPID LPIDShared Memory:m 0 0x411c29d6
--rw-rw-rw- root root 0 899 899m 1 0x4e0c0002
--rw-rw-rw- root root 2 899 901m 2 0x4120007a
--rw-rw-rw- root root 2 899 901m 458755 0x0c6629c9
--rw-r----- root sys 2 9113 17065m 4 0x06347849
--rw-rw-rw- root root 1 1661 9150m 65541 0xffffffff
--rw-r--r-- root root 0 1659 1659m 524294 0x5e100011
--rw------- root root 1 1811 1811m 851975 0x5fe48aa4
--rw-r----- oracle oinstall 66 2017 25076
然後它ID號清除共享記憶體段:
$ipcrm –m 851975
對於訊號量,可以用以下命令檢視:
$ ipcs -sopIPC status from /dev/kmem
as of Thu Jul 6 14:44:16 2006T ID KEY MODE OWNER GROUPSemaphores:s 0 0x4f1c0139
--ra------- root root... ...s 14 0x6c200ad8
--ra-ra-ra- root roots 15 0x6d200ad8
--ra-ra-ra- root roots 16 0x6f200ad8
--ra-ra-ra- root roots 17 0xffffffff
--ra-r--r-- root roots 18 0x410c05c7
--ra-ra-ra- root roots 19 0x00446f6e
--ra-r--r-- root roots 20 0x00446f6d
--ra-r--r-- root roots 21 0x00000001
--ra-ra-ra- root roots 45078 0x67e72b58
--ra-r----- oracle oinstall
根據訊號量ID,用以下命令清除訊號量:
$ipcrm -s 45078
如果是Oracle程式沒有關閉,用以下命令查出存在的oracle程式:
$ ps -ef|grep ora oracle 29976 1 0 Jun 22 ? 0:52 ora_dbw0_ora92 oracle 29978 1 0 Jun 22 ? 0:51 ora_dbw1_ora92 oracle 5128 1 0 Jul 5 ? 0:00 oracleora92 (LOCAL=NO)... ...
然後用kill -9命令殺掉程式
$kill -9
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26845409/viewspace-1695753/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- JVM問題及解答JVM
- Oracle常用傻瓜問題1000問Oracle
- 域名解析常見問題盤點及解答
- 【FAQ】統一掃碼服務常見問題及解答
- 前端入門-day2(常見css問題及解答)前端CSS
- APatch常見問題解答
- Python list,dict問題解答Python
- linux處理oracle問題常用命令LinuxOracle
- RapidWeaver 8常見問題解答API
- Ubuntu 常見問題和解答Ubuntu
- 軟體新人問題解答(一)
- Docker面試問題與解答Docker面試
- 【FAQ】申請Health Kit許可權的常見問題及解答
- NSIS 之 NsDialogs 常見問題解答
- ViewModel和LiveData問題思考與解答ViewLiveData
- [譯] HTTP/2 常見問題解答HTTP
- 阿里雲centos7伺服器nginx配置及常見問題解答阿里CentOS伺服器Nginx
- 【ORACLE】Oracle常用SQL及重點功能說明OracleSQL
- Oracle 錯誤總結及問題解決 ORAOracle
- C# 面試問題與解答1C#面試
- 小遊戲引擎常見問題解答遊戲引擎
- Rhinoceros 6 for Mac的常見問題解答ROSMac
- Screaming Frog SEO Spider常見問題解答IDE
- 關於CleanMyMac常見問題與解答Mac
- Java程式設計師面試題及解答Java程式設計師面試題
- 【AUDIT]Oracle審計配置及常用sqlOracleSQL
- Oracle trigger問題Oracle
- Oracle資料庫處理壞塊問題常用命令Oracle資料庫
- 【FAQ】申請運動健康服務驗證環節常見問題及解答健康服務
- 深度學習從入門到進階的12個經典問題及解答深度學習
- SOLIDWORKS認證考試常見問題解答Solid
- 業務規則的常見問題解答
- 犀牛Rhinoceros 6 for Mac的常見問題解答ROSMac
- HTTPS總結+相關面試問題解答HTTP面試
- Python程式設計常見問題與解答Python程式設計
- 聚類的基本問題及兩個常用演算法聚類演算法
- oracle ora-600[2662]問題分析及異常恢復Oracle
- 提出問題,解答問題!這才是理解程式碼設計的正確方法
- 關於“等保保護”最常見問題解答!