為什麼我的 Oracle 會從磁碟讀取?
[從ServerFault複製到看起來更合適的論壇]
我們的 Oracle 伺服器(版本 12c)在具有 128GB RAM 的 RedHat-6.7 伺服器上執行。
它上面唯一的數據庫目前大小只有60GB左右。
然而,我們看到大量的磁碟讀取——在儲存數據庫的設備上——在
iostat
輸出中(以藍色顯示)。當然,也有一些寫(以黃色顯示):雖然對永久儲存的寫入是有意義的,因為我們確實有時會對數據進行修改,但讀取卻沒有——整個數據庫可以在記憶體中容納兩次……事實上,我們應該能夠將它儲存在 USB 上-堅持並且仍然有很好的閱讀時間——例如,與 Redis 相當。
我們應該檢查和調整 Oracle 配置的哪些部分以使伺服器使用所有可用的 RAM?
我們將查看INMEMORY設置。但似乎
inmemory_*
只有當伺服器必須(由於 RAM 短缺)決定從記憶體中刪除什麼以稍後重新讀回時,參數才起作用。在我們的例子中,任何東西都不應該從記憶體中刪除,因為一切都有空間。然而,顯然,有些東西被一遍又一遍地(重新)閱讀……更新:伺服器上的輸出
free
目前為:
total used free shared buffers cached Mem: 132044132 99974992 32069140 89131408 292508 93060984 -/+ buffers/cache: 6621500 125422632 Swap: 33554428 0 33554428
-user擁有的程序
oracle
似乎都共享上述 85GB 記憶體塊。也許,我們真的只是在自己限制伺服器——30GB 未使用的記憶體似乎表明了這一點。我們如何告訴伺服器使用更多?
只是一些可能性,沒有 100% 準確的解釋。
假設您有 100+ GB SGA(帶有 100 GB 緩衝區記憶體)和 20 GB PGA。
- 執行排序(使用 ORDER BY 查詢)或散列(HASH JOIN)的操作使用 PGA 記憶體來執行此操作。單個會話通常可以為這些操作使用高達 5% 的目標 PGA,如果它需要更多記憶體,那麼它會切換到臨時表空間,繼續它的工作,但它不是記憶體,而是在磁碟上執行它。因此,如果您的查詢需要對一些更大但甚至不接近可用記憶體量的數據(1 GB + 數據)進行排序,它將在磁碟上進行排序。
- 使用full scan讀取時,不會記憶體大表(=segments)。預設情況下,大表 (=segment) 通常是大於緩衝區記憶體 2% 的表 (=segment)。此行為可以通過設置
"_small_table_threshold"
參數來控制,該參數指定數據庫塊中的門檻值,用於決定是否應記憶體段。類似的例子:如果你有一個超過 2 GB 的表,並且你的查詢使用全掃描讀取它,數據庫甚至不會嘗試記憶體它。如果您多次執行此查詢,數據庫將一遍又一遍地從磁碟讀取表。- LOB 列儲存在單獨的段中。LOB 段預設不被記憶體(如果在創建時或以後沒有明確指定),因此它們將一遍又一遍地從磁碟讀取。記憶體可以啟用為:
alter table table1 modify lob (lob_column1) (cache);
或(cache reads)
僅記憶體讀取。+1。您配置的 SGA 比您的數據庫更大。(希望您也在實例級別配置它)。您可以強製完整的數據庫記憶體為:
ALTER DATABASE FORCE FULL DATABASE CACHING;
+2。In-Memory 是需要許可的數據庫的額外成本選項。僅當您擁有相應的許可證時才使用它。
在您的 RedHat 伺服器中,將swappiness核心參數更改為較低的值或 0 以避免交換操作。如上所述,檢查您的 Oracle DB 記憶體值。
systemctl vm.swappiness = <integer value>