從操作系統(tǒng)命令TOP到數(shù)據(jù)庫的優(yōu)化
對于一個(gè)剛開始學(xué)習(xí)數(shù)據(jù)庫優(yōu)化的新手DBA來說,當(dāng)用戶反饋系統(tǒng)比較慢時(shí),他會非常緊張,面對數(shù)據(jù)庫,他無從下手,不知道從哪里開始著手來優(yōu)化數(shù)據(jù)庫,查找系統(tǒng)
存在的問題。
今天我們通過操作系統(tǒng)命令TOP,來優(yōu)化數(shù)據(jù),我們?nèi)绾伟巡僮飨到y(tǒng)與數(shù)據(jù)庫關(guān)聯(lián)起來哪,我們主要是通過操作系統(tǒng)TOP命令找到最消耗資源OS PID進(jìn)程。
通過OS PID與V$PROCESS動態(tài)性能試圖進(jìn)行管理。我們知道V$PROCESS是被認(rèn)為從操作系統(tǒng)到數(shù)據(jù)庫的入口,而進(jìn)入數(shù)據(jù)庫內(nèi)部,進(jìn)程需要創(chuàng)建回話(SESSION)執(zhí)行數(shù)據(jù)庫操作的SQL語句,一般情況下,一個(gè)進(jìn)程只會創(chuàng)建一個(gè)回話,但是在特殊的情況下,一個(gè)進(jìn)程也可以創(chuàng)建多個(gè)數(shù)據(jù)庫回話。回話的信息是通過動態(tài)性能試圖V$SESSION來進(jìn)行管理和體現(xiàn)的。
那么我們通過一個(gè)實(shí)驗(yàn)來看一下,如何完成從操作系統(tǒng)命令到數(shù)據(jù)庫內(nèi)部的操作,我們模擬一個(gè)出現(xiàn)故障的場景,我們通過操作系統(tǒng)命令TOP,進(jìn)行觀察,找到操作系統(tǒng)進(jìn)程占CPU資源比較高的進(jìn)程。
1.首先我們建立一個(gè)測試表t1,向表中插入一些數(shù)據(jù)。
SQL>create table t1 as select * from emp;
SQL>insert into t1 as select * from t1;
SQL>/
SQL>/
SQL>/
SQL>/
使表T1大約有幾萬條記錄。
2.開3,4個(gè)會話,其中表t1有幾萬行的數(shù)據(jù),同時(shí)運(yùn)行,立刻查詢上面的語句
declare v1 emp.sal%type; begin for n in 1..100 loop for k in 1..100 loop select count(*) into v1 from t1; end loop; dbms_lock.sleep(1); end loop; end; / |
3.通過操作系統(tǒng)命令TOP找到消耗CPU資源的進(jìn)程
top - 12:57:42 up 19 min, 2 users, load average: 1.18, 0.35, 0.23 Tasks: 132 total, 2 running, 130 sleeping, 0 stopped, 0 zombie Cpu(s): 20.5%us, 5.9%sy, 0.0%ni, 73.1%id, 0.5%wa, 0.0%hi, 0.0%si, 0.0%st Mem: 1034664k total, 883716k used, 150948k free, 125584k buffers Swap: 4120664k total, 0k used, 4120664k free, 609440k cached PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 5182 oracle 19 0 368m 50m 48m S 37.9 5.0 0:03.57 oracle 1 root 15 0 2160 652 564 S 0.0 0.1 0:02.30 init 2 root RT -5 0 0 0 S 0.0 0.0 0:00.05 migration/0 3 root 34 19 0 0 0 S 0.0 0.0 0:00.00 ksoftirqd/0 4 root RT -5 0 0 0 S 0.0 0.0 0:00.04 migration/1 5 root 34 19 0 0 0 S 0.0 0.0 0:00.00 ksoftirqd/1 6 root 10 -5 0 0 0 S 0.0 0.0 0:00.04 events/0 7 root 10 -5 0 0 0 S 0.0 0.0 0:00.00 events/1 8 root 11 -5 0 0 0 S 0.0 0.0 0:00.01 khelper 9 root 10 -5 0 0 0 S 0.0 0.0 0:00.00 kthread 13 root 10 -5 0 0 0 S 0.0 0.0 0:00.10 kblockd/0 14 root 10 -5 0 0 0 S 0.0 0.0 0:00.02 kblockd/1 15 root 16 -5 0 0 0 S 0.0 0.0 0:00.00 kacpid 179 root 12 -5 0 0 0 S 0.0 0.0 0:00.00 cqueue/0 180 root 12 -5 0 0 0 S 0.0 0.0 0:00.00 cqueue/1 183 root 11 -5 0 0 0 S 0.0 0.0 0:00.00 khubd 185 root 10 -5 0 0 0 S 0.0 0.0 0:00.00 kseriod 252 root 18 0 0 0 0 S 0.0 0.0 0:00.00 khungtaskd 253 root 17 0 0 0 0 S 0.0 0.0 0:00.00 pdflush 254 root 15 0 0 0 0 S 0.0 0.0 0:00.03 pdflush |
4.我們看到進(jìn)程PID等于5182,我們下面的一個(gè)腳本,關(guān)聯(lián)V$PROCESS試圖和V$SESSION試圖、V$SQLTEST試圖,可以找出這個(gè)進(jìn)程正在執(zhí)行的SQL語句,這里只需要一個(gè)“發(fā)動”條件,就是進(jìn)程(PID):
SQL>SELECT /*+ ORDERED */ sql_text FROM v$sqltext a WHERE (a.hash_value, a.address) IN (SELECT DECODE(sql_hash_value, 0, prev_hash_value, sql_hash_value), DECODE(sql_hash_value, 0, prev_sql_addr, sql_address) FROM v$session b WHERE b.paddr = (SELECT addr FROM v$process c WHERE c.spid = '&pid')) ORDER BY piece ASC; / |
提示輸入變量值。
Enter value for pid: 5182 old 9: (SELECT addr FROM v$process c WHERE c.spid = '&pid')) new 9: (SELECT addr FROM v$process c WHERE c.spid = '5182')) SQL_TEXT ---------------------------------------------------------------- declare v1 number; begin for n in 1..100 loop for k in 1..100 l oop select count(*) into v1 from t1; end loop; dbms_lock.sleep(1 ); end loop; end; |
注:這里我們使用了3個(gè)動態(tài)性能試圖,獲取到了執(zhí)行的SQL語句。我們的邏輯是:
1)首先輸入一個(gè)PID,這個(gè)PID即是process id,也就是在TOP命令中看到的PID.
2)通過PID和v$process.spid相關(guān),我們可以獲得process的詳細(xì)信息。
3)通過v$process.addr和v$session.paddr相關(guān)聯(lián),可以獲取session的相關(guān)詳細(xì)信息。
4)再結(jié)合v$sqltest,即可獲得當(dāng)前session正在執(zhí)行的SQL語句。
總結(jié):
1.首先我們通過操作系統(tǒng)命令TOP找到了PID.
2.我們結(jié)合3個(gè)試圖,就找打了當(dāng)前正在瘋狂消耗CPU的罪魁禍?zhǔn)祝敲聪旅娴墓ぷ骶褪侨绾蝺?yōu)化這個(gè)SQL,我們可以進(jìn)一步通過
dbms_system包跟蹤改進(jìn)程,或者通過AWR獲取該SQL的執(zhí)行計(jì)劃。來改變SQL的執(zhí)行計(jì)劃,達(dá)到優(yōu)化的目的。
posted on 2014-08-20 09:52 順其自然EVO 閱讀(168) 評論(0) 編輯 收藏 所屬分類: 測試學(xué)習(xí)專欄