banner
hkxtor

hkxtor

With eyes filled with stories, the face shows no signs of wind or frost.

如何判斷資料庫IO是否慢

1. 引言#

一個項目的資料庫響應慢的問題,結論就是操作系統層面上的 IO 性能差的問題,怎麼樣才能更有說服力。我們一般衡量 IO 性能主要用兩種指標來衡量。響應時間:用微秒來測量完成一項操作所需的時間,這個一般由 oracle 來採集統計。吞吐量:以每個單位時間內完成的操作數量來測量。這個一般通過操作系統下的工具來統計,例如 iostat。本文主要是闡述如何從 oracle 的角度來確定 IO 是否慢,不再詳細說明吞吐量及其測量方法。

2. 怎麼才算 IO “慢”#

IO 慢是一個很主觀的術語,它更多的取決於用戶對系統和硬體的預期和實際的差異,這個差異是一個比較主觀的感覺,量化到具體性能指標來看,在企業級平台下,當 IO 請求的響應時間大於 10ms 時,用戶會開始敏感。不過響應時間是會不斷變化的,有可能是數據從檔案系統遷移到共享存儲上,也可能是存儲設備出現異常,又或者是業務增長導致的 IO 性能達到峰值。這就需要通過對響應時間這個指標作出作出多維度的測量。

3. 響應時間#

硬體不必對於每個 IO 請求都有相同的反應。總會有可能出現高峰和低谷。因此使用平均值是一種測量響應時間的通用方法。
注意:為了減緩這種高峰 / 低谷的異常場景帶來的問題,樣例數據量需要比較大。樣例數據量應該至少是每小時 1000 次操作,目的就是為了提供給決測更可信和實用的依據。

  1. IO 的類型

    平均響應時間直接關聯到具體的 IO 類型:

    1. 讀或寫
    2. 單塊或多塊
      單塊IO,指一次只讀一個塊。例如,當一個session等待一個單塊IO時,典型的等待事件就是“db file sequential read”,表明正在等待需要的塊。
      多塊讀指的是一次讀多個塊,從2到128個Oracle塊不等,依賴於塊的大小與操作系統設置。通常一個多塊請求容量上有1MB的限制。例如當一個session等待一次多塊IO時,典型的等待事件就是“db file scattered read”,表明正在等待需要的塊。
      
    3. 同步或異步
      同步(阻塞)操作等待硬體完成物理IO,完成後能得到通知,合理地管理操作的成功或失敗(成功讀的情況下可以接收結果)。當需要等待系統調用結果的時候,進程的執行是被堵塞的。
      對於異步(非阻塞)操作,一旦IO請求傳遞到硬體,或放入操作系統的隊列中(典型的情況是物理IO開始之前),系統調用會立即返回。進程的執行不会被堵塞,因為它不需要等待系統調用的結果。它能繼續執行,當IO操作有結果時再接收。
      
  2. 響應時間的閾值

    一次典型的多塊同步讀 64x 8k (總計 512KB) 的平均時間應該在未出現 IO 變慢的情況下大約是 20 毫秒左右。小請求應該更快 (10-20 毫秒),大請求的消耗時間應該不多於 25 毫秒。異步操作應該至少和同步操作一樣快,甚至還要更快。單塊讀至少應該和多塊讀一樣快,甚至還要更快。“log file parallel write”,“control file write” 和 “direct path writes“等待時間應該不多於 15 毫秒。數據文件寫的測量不像讀那樣簡單。DBWR 以批量的方式 ("db file parallel write") 異步寫入塊,現在還沒有寫操作響應時間的標準。如果 DBWR (多塊或單塊,帶或不帶 IO salves) 足夠快速能夠清理髒塊,那麼其他的等待事件和統計信息就會顯露出來。作為規則,超過上述等待事件時間的等待事件都應該詳細分析,當對比之前的時間消耗,有明顯變化時更需要知曉。

    注意:當系統低於這些最大閾值的時候,並不意味著沒有其他的調優方法。#

    響應時間因系統而有所不同。例如,接下來的幾項內容可以看做是正常平均值:

    1. 多塊同步讀時間是 10 毫秒。
    2. 單塊同步讀時間是 5 毫秒。
    3. 'log file parallel write' 時間是 3 毫秒。

    以上是基於多塊 IO 比單塊 IO 需要更多的 IO 子系統資源的前提。如果接受這些建議,redo 日誌最好放在最快的磁碟,並且沒有其它並發活動的爭用。

    以下是各 IO 相關等待事件的響應時間閾值:

    Wait EventR/WSynchronous/ AsynchronousSingleblock/ MultiblockElapsed Time
    control file parallel writeWriteAsynchronousMulti< 15ms
    control file sequential readReadSynchronousSingle< 20 ms
    db file parallel readReadAsynchronousMulti< 20 ms
    db file scattered readReadSynchronousMulti< 20 ms
    db file sequential readReadSynchronousSingle< 20 ms
    direct path readReadAsynchronousMulti< 20 ms
    direct path read tempReadAsynchronousMulti< 20 ms
    direct path writeWriteAsynchronousMulti< 15 ms
    direct path write tempWriteAsynchronousMulti< 15 ms
    log file parallel writeWriteAsynchronousMulti< 15 ms
  3. 確定響應時間的途徑

    1. 10046 trace file

      當在10046 trace中使用level 8或12時,會包含相關的等待事件的信息,響應時間是ela字段,單位是微秒。
      WAIT #5: nam='cell single block physical read' ela= 672 cellhash#=2520626383 diskhash#=1377492511 bytes=16384 obj#=63 tim=1280416903276618
      >> 672微秒 = 0.672毫秒
      WAIT #5: nam='db file sequential read' ela= 1018 file#=2 block#=558091 blocks=1 obj#=0 tim=10191852599110
      >> 1018微秒 => 1.018毫秒
      
    2. System State Dump

      對於每個系統級的進程,等待信息包括在進程信息中。通常顯示一個活動的waiting for,或者等待完成,進程正在CPU中執行waited for/last wait for。
      其中waiting for表示進程處於等待狀態。11g之前可以查看seconds since wait started字段,顯示進程已經等待多久了。從11gR1開始,”total“字段顯示等待的時間。 如果waiting for顯示一個進程正在等待一IO相關的操作,seconds since wait started>0,表示可能IO丟失,session處於hang狀態。(因為之前提到過平均可接受時間是20毫秒,任何IO等待時間超過1秒都需要關注)。
      last wait for是與11g之前的版本相關的,表明進程不在等待(例如正在使用CPU)。等待時間記錄到”wait_time“字段。(11g中wait_time被not in wait替代)
      
      last wait for 'db file sequential read' blocking sess=0x0 seq=100 wait_time=2264 seconds since wait started=0 file#=45, block#=17a57, blocks=1
      >> 2264微秒 => 2.264毫秒
      
      waited for表示session不在等待。通常是11gR1以後的系統級trace中使用。total字段表示等待的總時間。
      0: waited for 'db file sequential read' file#=9, block#=46526, blocks=1
      wait_id=179 seq_num=180 snap_id=1
      wait times: snap=0.007039 sec, exc=0.007039 sec, total=0.007039 sec
      wait times: max=infinite
      wait counts: calls=0 os=0
      >> 0.007039 sec => 7.039毫秒
      
    3. Statspack 與 AWR reports

      前台進程和後台進程的等待事件,平均響應時間通過 Wait Avg (ms) 反映 (以毫秒計算的平均讀)。
      image
      image

      表空間 IO
      平均響應時間通過 Av Rd (ms) 反映 (以毫秒計算的平均讀)。
      image

      等待事件直方圖可以提供組成這些平均值的寫操作時間分佈。他會展示出所有寫操作都接近於平均值,還是會有若干波峰或波谷的情況。每列都表明每個 bucket 之間等待事件時間分佈的百分比。例如,<16ms 的等待大於 < 8ms。只要最大的百分比是從 < 1ms 到 16ms 的範圍內,那麼 IO 性能通常就可以接受。
      image

4. 總結#

本文的目標不是為了排查 IO 變慢的原因,而是為了如何尋找判定 IO 慢的證據。如果性能變差,那麼 IO 慢可能成為性能問題的一個潛在原因,需要從資料庫角度來分析如何採集支持的證據;如果潛在原因是由於操作系統級別的 IO 慢,那麼負責 IO 子系統工程師需要參與進來診斷和修復這個問題。

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。