qileilove

          blog已經(jīng)轉(zhuǎn)移至github,大家請?jiān)L問 http://qaseven.github.io/

          從操作系統(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í)專欄

          <2014年8月>
          272829303112
          3456789
          10111213141516
          17181920212223
          24252627282930
          31123456

          導(dǎo)航

          統(tǒng)計(jì)

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 商洛市| 六枝特区| 鹿泉市| 金昌市| 安乡县| 台东市| 双桥区| 大安市| 郸城县| 哈尔滨市| 德惠市| 安西县| 安吉县| 二手房| 洛宁县| 策勒县| 龙海市| 保靖县| 辰溪县| 阳春市| 旬邑县| 甘泉县| 彝良县| 绥阳县| 楚雄市| 衡阳市| 中牟县| 鄂州市| 象山县| 富裕县| 满洲里市| 江孜县| 麻城市| 尼玛县| 甘南县| 天门市| 若尔盖县| 顺义区| 休宁县| 定边县| 平安县|