【FLUSH】將Buffer Cache內容強制寫出到資料檔案

secooler發表於2009-12-22
在某些情況下需要手工將Data Buffer Cache寫出到資料檔案,例如為防止Buffer Cache中的資料對SQL執行效能的影響,為公平起見需要先對緩衝區中的資料清理。
在Oracle的不同版本里清理Buffer Cache的方法也略有不同,總體方向是向著簡單快捷方向發展的。

1.Oracle 9i方法(10g中依然可用)
1)可以使用“immediate trace name flush_cache”事件強制將Buffer Cache中的資料全部寫出到資料檔案。
sec@ora10g> alter session set events='immediate trace name flush_cache';

Session altered.

2)當執行完上述重新整理操作之後,Oracle會在alert日誌留下它的“腳印”。
Tue Dec 22 21:15:10 2009
ALTER SYSTEM: Flushing buffer cache

3)使用“alter system”語句同樣可以完成這個任務
sec@ora10g> alter system set events = 'immediate trace name flush_cache';

System altered.

4)看一下alert中的“腳印”,注意與“alter session”的區別,這裡記錄的資訊更加詳細,包含了“OS Pid”資訊。
Tue Dec 22 21:25:29 2009
ALTER SYSTEM: Flushing buffer cache
OS Pid: 17538 executed alter system set events 'immediate trace name flush_cache'

2.Oracle 10g中為簡化這個過程,提供了一個“flush buffer_cache”方法
1)具體方法
sec@ora10g> alter system flush buffer_cache;

System altered.

2)在alert中與之對應的資訊如下
Tue Dec 22 21:27:03 2009
ALTER SYSTEM: Flushing buffer cache

3.演示一下在Buffer Cache寫出前後對同一SQL的影響
1)全新SQL語句執行後的統計資訊如下
sec@ora10g> set timing on
sec@ora10g> set autot trace statistic;
sec@ora10g> select count(*) from t;

Elapsed: 00:00:00.08

Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
       2102  consistent gets
       2093  physical reads
          0  redo size
        515  bytes sent via SQL*Net to client
        492  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

可見“physical reads”是2093,說明Oracle將所需的資料檔案從外存讀入到了Buffer Cache。

2)同樣的SQL語句再次執行,此時Buffer Cache並未刷出到外存。
sec@ora10g> select count(*) from t;

Elapsed: 00:00:00.06

Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
       2102  consistent gets
          0  physical reads
          0  redo size
        515  bytes sent via SQL*Net to client
        492  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

此時“physical reads”物理讀已為零,無需重新從外存讀入資料,隨之執行時間也減少了。

3)將Buffer Cache刷出後再次嘗試同樣的SQL
sec@ora10g> alter system flush buffer_cache;

System altered.

Elapsed: 00:00:00.15
sec@ora10g> select count(*) from t;

Elapsed: 00:00:00.08

Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
       2102  consistent gets
       2093  physical reads
          0  redo size
        515  bytes sent via SQL*Net to client
        492  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

因為Buffer Cache中資料已經被刷出到外存,同樣的SQL的物理讀情況恢復到了第一次執行時的值2093。

4.小結
當Buffer Cache包含大量資料時,重新整理時間將會很長,沒有“特殊需求”請不要使用這個方法。
該方法在進行SQL效能測試時教為常用,為排除Buffer Cache對於測試結果影響時可以考慮使用該方法強制Oracle重新執行物理讀。

Good luck.

secooler
09.12.22

-- The End --

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/519536/viewspace-623381/,如需轉載,請註明出處,否則將追究法律責任。

相關文章