qileilove

          blog已經轉移至github,大家請訪問 http://qaseven.github.io/

          從操作系統命令TOP到數據庫的優化

           對于一個剛開始學習數據庫優化的新手DBA來說,當用戶反饋系統比較慢時,他會非常緊張,面對數據庫,他無從下手,不知道從哪里開始著手來優化數據庫,查找系統
            存在的問題。
            今天我們通過操作系統命令TOP,來優化數據,我們如何把操作系統與數據庫關聯起來哪,我們主要是通過操作系統TOP命令找到最消耗資源OS PID進程。
            通過OS PID與V$PROCESS動態性能試圖進行管理。我們知道V$PROCESS是被認為從操作系統到數據庫的入口,而進入數據庫內部,進程需要創建回話(SESSION)執行數據庫操作的SQL語句,一般情況下,一個進程只會創建一個回話,但是在特殊的情況下,一個進程也可以創建多個數據庫回話。回話的信息是通過動態性能試圖V$SESSION來進行管理和體現的。
            那么我們通過一個實驗來看一下,如何完成從操作系統命令到數據庫內部的操作,我們模擬一個出現故障的場景,我們通過操作系統命令TOP,進行觀察,找到操作系統進程占CPU資源比較高的進程。
            1.首先我們建立一個測試表t1,向表中插入一些數據。
            SQL>create table t1 as select * from emp;
            SQL>insert into t1 as select * from t1;
            SQL>/
            SQL>/
            SQL>/
            SQL>/
            使表T1大約有幾萬條記錄。
            2.開3,4個會話,其中表t1有幾萬行的數據,同時運行,立刻查詢上面的語句
          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.通過操作系統命令TOP找到消耗CPU資源的進程
          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.我們看到進程PID等于5182,我們下面的一個腳本,關聯V$PROCESS試圖和V$SESSION試圖、V$SQLTEST試圖,可以找出這個進程正在執行的SQL語句,這里只需要一個“發動”條件,就是進程(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個動態性能試圖,獲取到了執行的SQL語句。我們的邏輯是:
            1)首先輸入一個PID,這個PID即是process id,也就是在TOP命令中看到的PID.
            2)通過PID和v$process.spid相關,我們可以獲得process的詳細信息。
            3)通過v$process.addr和v$session.paddr相關聯,可以獲取session的相關詳細信息。
            4)再結合v$sqltest,即可獲得當前session正在執行的SQL語句。
            總結:
            1.首先我們通過操作系統命令TOP找到了PID.
            2.我們結合3個試圖,就找打了當前正在瘋狂消耗CPU的罪魁禍首,那么下面的工作就是如何優化這個SQL,我們可以進一步通過
            dbms_system包跟蹤改進程,或者通過AWR獲取該SQL的執行計劃。來改變SQL的執行計劃,達到優化的目的。
           

          posted on 2014-08-20 09:52 順其自然EVO 閱讀(166) 評論(0)  編輯  收藏 所屬分類: 測試學習專欄

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

          導航

          統計

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 醴陵市| 本溪市| 汨罗市| 呼图壁县| 天祝| 辉县市| 都江堰市| 西峡县| 安龙县| 两当县| 双城市| 九台市| 定兴县| 天台县| 祁阳县| 彭州市| 九龙城区| 清原| 吉安县| 报价| 凤城市| 鄂托克旗| 九龙坡区| 澄城县| 鄂托克前旗| 资中县| 浦县| 郁南县| 兰溪市| 鸡西市| 桑日县| 电白县| 郎溪县| 闵行区| 呈贡县| 满城县| 樟树市| 南部县| 澳门| 赤壁市| 龙川县|