這篇 找到MySQL服務器發生SWAP罪魁禍首 ,雖然它是在講 MySQL

引用內文

SWAP是乾嘛的,了解下它的背景知識。

在Linux下,SWAP的作用類似Windows系統下的“虛擬內存”。當物理內存不足時,

拿出部分硬盤空間當SWAP分區(虛擬成內存)使用,從而解決內存容量不足的情況。

SWAP意思是交換,顧名思義,當某進程向OS請求內存發現不足時,OS會把內存中暫時不用的數據交換出去,

放在SWAP分區中,這個過程稱為SWAP OUT。當某進程又需要這些數據且OS發現還有空閒物理內存時,

又會把SWAP分區中的數據交換回物理內存中,這個過程稱為SWAP IN。在vmstat的輸出結果中,

分別表現為si\so兩列,如下圖.1

圖1

看到這裡我們就知道了,發生SWAP的最直接可能的原因是進程向OS申請內存時,

發現物理內存不足,當沒有SWAP可用的話,這時可能會一直等待,也可能會觸發OOM-killer機制,

OS把消耗內存最多的那個進程kill掉以釋放內存,這個選擇取決於內核參數vm.swappiness。

該參數可選範圍從0 - 100,設為0就是希望最大限度使用物理內存,

盡量不使用swap,設為100則是希望積極使用swap。

在運行數據庫進程的服務器上,我們通常強烈建議這個值小於等於10,最好是設置為0。原因很簡單,

對數據庫這種需要集中CPU資源、大內存、高I/O的程序而言,如果用SWAP分區代替內存,

那數據庫服務性能將是不可接受的,

還不如直接被OOM kill(數據庫進程通常佔用最多內存,最容易被OOM kill)來的痛快

(早死晚死都是死,還不如痛快的死,反正很快就能重生,嗯)。

MySQL 秏盡記憶體

引用

由於服務器硬件、系統設置不當,沒有關閉NUMA,導致發生SWAP。建議方案有:

在BIOS設置層面關閉NUMA,缺點是需要重啟OS;

或修改GRUB配置文件,缺點也是要重啟OS;

升級MySQL版本到5.6.27及以後,新增了一個選項innodb_numa_interleave,只需要重啟mysqld實例,無需重啟OS,推薦此方案。

引用 比较全面的MySQL优化参考(上篇)

2.2、其他內核參數優化
針對關鍵內核參數設定合適的值,目的是為了減少swap的傾向,並且讓內存和磁盤I/O不會出現大幅波動,導致瞬間波峰負載:
1、將vm.swappiness設置為5-10左右即可,甚至設置為0(RHEL 7以上則慎重設置為0,除非你允許OOM kill發生),以降低使用SWAP的機會;

2、將vm.dirty_background_ratio設置為5-10,將vm.dirty_ratio設置為它的兩倍左右,以確保能持續將臟數據刷新到磁盤,避免瞬間I/O寫,產生嚴重等待(和MySQL中的innodb_max_dirty_pages_pct類似);

3、將net.ipv4.tcp_tw_recycle、net.ipv4.tcp_tw_reuse都設置為1,減少TIME_WAIT,提高TCP效率;

4、至於網傳的read_ahead_kb、nr_requests這兩個參數,我經過測試後,發現對讀寫混合為主的OLTP環境影響並不大(應該是對讀敏感的場景更有效果),不過沒準是我測試方法有問題,可自行斟酌是否調整;

引用 FAQ系列| 是什麼導致MySQL數據庫服務器磁盤I/O高?

3、解決

既然知道原因,問題解決起來也就快了,我們主要做了下面幾個調整:
調大innodb-buffer-pool-size,原則上不超過物理內存的70%,所以設置為40G;
調大innodb-purge-thread,原來是1,調整成4;
調大innodb_io_capacity和innodb_io_capacity_max,值分別為2萬和2.5萬;
調整完後,重啟實例(5.7版本前調整innodb-buffer-pool-size和innodb-purge-thread需要重啟才生效)。再經觀察,發現IOPS下降的很快,不再告警,同時Innodb_buffer_pool_wait_free也一直為0,unpurge列表降到了數千級別

 

Related posts 相關文章
使用連線控制插件提高 MySQL 安全性
More...
使用驗證插件提高 MySQL 密碼安全性
More...
用 pv 查看 mysql restore 還原資料進度
More...
使用 sysbench 壓力測試 mysql
More...

作者

留言

撰寫回覆或留言

發佈留言必須填寫的電子郵件地址不會公開。