MySQL OOM問題處理一則
一個遊戲業務的mysql資料庫,多臺伺服器上mysql服務被OOM,但OOM的原因是什麼呢?
其實導致OOM的直接原因並不複雜,就是因為伺服器記憶體不足,核心需要回收記憶體,回收記憶體就是kill掉伺服器上使用記憶體最多的程式,而mysql服務是使用記憶體最多,所以就OOM了。
首先我們檢查是什麼原因導致記憶體不足,這臺伺服器實體記憶體為64G
# free -m
total used free shared buffers cached
Mem: 64375 57821 6553 0 554 16369
-/+ buffers/cache: 40897 23478
Swap: 16383 5 16378
被oom第一個懷疑的原因就是innodb_buffer_pool_size大小設定是否合理
141205 18:47:57 [Note] Plugin 'FEDERATED' is disabled.
141205 18:47:57 InnoDB: The InnoDB memory heap is disabled
141205 18:47:57 InnoDB: Mutexes and rw_locks use GCC atomic builtins
141205 18:47:57 InnoDB: Compressed tables use zlib 1.2.3
141205 18:47:57 InnoDB: Using Linux native AIO
141205 18:47:57 InnoDB: Initializing buffer pool, size = 58.0G
141205 18:48:04 InnoDB: Completed initialization of buffer pool
141205 18:48:04 InnoDB: highest supported file format is Barracuda.
從上面mysql啟動的日誌中,可以看到在14年mysql啟動的時候,innodb_buffer_pool_size設定成了58G,一直到OOM,innodb_buffer_pool_size一直是58G
一臺實體記憶體為64G的伺服器,innodb_buffer_pool_size的這個設定確實有點大
另一個檢查是vm.swappiness的設定
現在伺服器上vm.swappiness設定為0,而RHEL/CentOS 6.4的核心從2.6.32-358這個版本以後,swappiness的行為就已經修改了,
最新的核心,建議把vm.swappiness設定1
# uname -r
2.6.32-431.el6.x86_64
這裡我們系統是最新的核心
但是透過下面的分析,發現innodb_buffer_pool_size,vm.swappiness兩個引數設定的不合理只是OOM中的潛在問題,並不是觸發OOM的直接原因
可以透過show engine innodb status,檢視一下mysql記憶體的使用情況
.....
----------------------
BUFFER POOL AND MEMORY
----------------------
Total memory allocated 63979913216; in additional pool allocated 0
Internal hash tables (constant factor + variable factor)
Adaptive hash index 7893457408 (7887918656 + 5538752)
Page hash 61625224 (buffer pool 0 only)
Dictionary cache 247241428 (246498992 + 742436)
File system 111712 (82672 + 29040)
Lock system 154077792 (154061624 + 16168)
Recovery system 0 (0 + 0)
Dictionary memory allocated 742436
Buffer pool size 3801087
Buffer pool size, bytes 62277009408 --Buffer Pool大小
Free buffers 3686413 --Buffer Pool中有多少個空白頁
Database pages 112368 --Buffer Pool中使用了多少頁
Old database pages 22365
........
這裡可以發現Buffer pool中大部分頁都是Free的,其實mysql服務並未直接分配到58G的記憶體。
透過sar -B,發現了大量的與SWAP記憶體的交換,而這個頻繁交換的時間是每半小時發生一次
10:00:01 AM pgpgin/s pgpgout/s fault/s majflt/s pgfree/s pgscank/s pgscand/s pgsteal/s %vmeff
10:10:01 AM 24472.34 13779.62 10542.81 0.88 8986.53 1547.25 42.00 1556.45 97.94
10:20:01 AM 24.55 11989.73 10669.42 0.14 4369.46 138.54 0.11 138.64 100.00
10:30:01 AM 1.29 8991.32 9832.53 0.01 3596.49 20.53 0.55 21.08 100.00
10:40:01 AM 24522.56 17124.60 11295.04 0.75 9649.33 1710.20 51.21 1666.83 94.63
10:50:01 AM 4.68 8691.01 10355.18 0.08 3934.04 21.22 0.11 21.33 100.00
11:00:01 AM 3.71 10738.47 10384.87 0.09 4017.96 94.24 0.28 94.47 99.96
11:10:02 AM 24924.74 14603.99 11129.07 0.86 9504.08 1751.06 40.43 1642.30 91.67
11:20:01 AM 11.95 8548.50 10206.84 0.11 3819.67 48.74 0.11 48.85 100.00
Average: 8944.00 11658.11 10479.06 0.40 5958.60 687.73 18.04 668.62 94.74
每半個小時的SWAP記憶體交換是什麼引起的呢?
[root@tlbb3d_yd_mxy_120-132-43-203_sx ~]# crontab -l
00 05 * * * /bin/bash /home/databak/scripts/xtrabackup.sh FULL_BACKUP
*/30 * * * * /bin/bash /home/databak/scripts/xtrabackup.sh INCRE_BACKUP
00 03 * * * /bin/bash /home/databak/dbbbak.sh xxx
透過crontab 發現,這臺伺服器每半個小時使用xtrabackup對mysql做一次增備,
這個增備的起點是基於每天凌晨5點的全備進行的,也就意味著隨著時間增備的資料量會越來越大,
備份時長也會越來越長,也就意味著系統資源會越來越緊張,以下也可以看到資料的增長情況
# du -sh *
2.4G 201602261030
2.5G 201602261100
很顯然透過以上的分析我們需要做以下三件事情來解決mysql的OOM
1.將innodb_buffer_pool_size設定為48G
2.將vm.swappiness設定為1
3.調整增量備份時間(需要和業務平衡),拉長增量備份的間隔,降低系統的資源消耗
vm.swappiness參考:https://www.percona.com/blog/2014/04/28/oom-relation-vm-swappiness0-new-kernel/
其實導致OOM的直接原因並不複雜,就是因為伺服器記憶體不足,核心需要回收記憶體,回收記憶體就是kill掉伺服器上使用記憶體最多的程式,而mysql服務是使用記憶體最多,所以就OOM了。
首先我們檢查是什麼原因導致記憶體不足,這臺伺服器實體記憶體為64G
# free -m
total used free shared buffers cached
Mem: 64375 57821 6553 0 554 16369
-/+ buffers/cache: 40897 23478
Swap: 16383 5 16378
被oom第一個懷疑的原因就是innodb_buffer_pool_size大小設定是否合理
141205 18:47:57 [Note] Plugin 'FEDERATED' is disabled.
141205 18:47:57 InnoDB: The InnoDB memory heap is disabled
141205 18:47:57 InnoDB: Mutexes and rw_locks use GCC atomic builtins
141205 18:47:57 InnoDB: Compressed tables use zlib 1.2.3
141205 18:47:57 InnoDB: Using Linux native AIO
141205 18:47:57 InnoDB: Initializing buffer pool, size = 58.0G
141205 18:48:04 InnoDB: Completed initialization of buffer pool
141205 18:48:04 InnoDB: highest supported file format is Barracuda.
從上面mysql啟動的日誌中,可以看到在14年mysql啟動的時候,innodb_buffer_pool_size設定成了58G,一直到OOM,innodb_buffer_pool_size一直是58G
一臺實體記憶體為64G的伺服器,innodb_buffer_pool_size的這個設定確實有點大
另一個檢查是vm.swappiness的設定
現在伺服器上vm.swappiness設定為0,而RHEL/CentOS 6.4的核心從2.6.32-358這個版本以後,swappiness的行為就已經修改了,
最新的核心,建議把vm.swappiness設定1
# uname -r
2.6.32-431.el6.x86_64
這裡我們系統是最新的核心
但是透過下面的分析,發現innodb_buffer_pool_size,vm.swappiness兩個引數設定的不合理只是OOM中的潛在問題,並不是觸發OOM的直接原因
可以透過show engine innodb status,檢視一下mysql記憶體的使用情況
.....
----------------------
BUFFER POOL AND MEMORY
----------------------
Total memory allocated 63979913216; in additional pool allocated 0
Internal hash tables (constant factor + variable factor)
Adaptive hash index 7893457408 (7887918656 + 5538752)
Page hash 61625224 (buffer pool 0 only)
Dictionary cache 247241428 (246498992 + 742436)
File system 111712 (82672 + 29040)
Lock system 154077792 (154061624 + 16168)
Recovery system 0 (0 + 0)
Dictionary memory allocated 742436
Buffer pool size 3801087
Buffer pool size, bytes 62277009408 --Buffer Pool大小
Free buffers 3686413 --Buffer Pool中有多少個空白頁
Database pages 112368 --Buffer Pool中使用了多少頁
Old database pages 22365
........
這裡可以發現Buffer pool中大部分頁都是Free的,其實mysql服務並未直接分配到58G的記憶體。
透過sar -B,發現了大量的與SWAP記憶體的交換,而這個頻繁交換的時間是每半小時發生一次
10:00:01 AM pgpgin/s pgpgout/s fault/s majflt/s pgfree/s pgscank/s pgscand/s pgsteal/s %vmeff
10:10:01 AM 24472.34 13779.62 10542.81 0.88 8986.53 1547.25 42.00 1556.45 97.94
10:20:01 AM 24.55 11989.73 10669.42 0.14 4369.46 138.54 0.11 138.64 100.00
10:30:01 AM 1.29 8991.32 9832.53 0.01 3596.49 20.53 0.55 21.08 100.00
10:40:01 AM 24522.56 17124.60 11295.04 0.75 9649.33 1710.20 51.21 1666.83 94.63
10:50:01 AM 4.68 8691.01 10355.18 0.08 3934.04 21.22 0.11 21.33 100.00
11:00:01 AM 3.71 10738.47 10384.87 0.09 4017.96 94.24 0.28 94.47 99.96
11:10:02 AM 24924.74 14603.99 11129.07 0.86 9504.08 1751.06 40.43 1642.30 91.67
11:20:01 AM 11.95 8548.50 10206.84 0.11 3819.67 48.74 0.11 48.85 100.00
Average: 8944.00 11658.11 10479.06 0.40 5958.60 687.73 18.04 668.62 94.74
每半個小時的SWAP記憶體交換是什麼引起的呢?
[root@tlbb3d_yd_mxy_120-132-43-203_sx ~]# crontab -l
00 05 * * * /bin/bash /home/databak/scripts/xtrabackup.sh FULL_BACKUP
*/30 * * * * /bin/bash /home/databak/scripts/xtrabackup.sh INCRE_BACKUP
00 03 * * * /bin/bash /home/databak/dbbbak.sh xxx
透過crontab 發現,這臺伺服器每半個小時使用xtrabackup對mysql做一次增備,
這個增備的起點是基於每天凌晨5點的全備進行的,也就意味著隨著時間增備的資料量會越來越大,
備份時長也會越來越長,也就意味著系統資源會越來越緊張,以下也可以看到資料的增長情況
# du -sh *
2.4G 201602261030
2.5G 201602261100
很顯然透過以上的分析我們需要做以下三件事情來解決mysql的OOM
1.將innodb_buffer_pool_size設定為48G
2.將vm.swappiness設定為1
3.調整增量備份時間(需要和業務平衡),拉長增量備份的間隔,降低系統的資源消耗
vm.swappiness參考:https://www.percona.com/blog/2014/04/28/oom-relation-vm-swappiness0-new-kernel/
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26845409/viewspace-2042220/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- mysql問題處理兩則MySql
- mysql 問題處理二則MySql
- ASMCMD處理問題一則ASM
- 處理客戶小機問題[一則]
- 資料庫升級問題處理一則資料庫
- SQL最佳化 | MySQL問題處理案例分享三則MySql
- mysql的處理能力問題MySql
- OOM分析之問題一)OOM
- Java處理正則匹配卡死(正則回溯問題)Java
- Mysql故障處理2則MySql
- MySQL:亂碼問題處理流程MySql
- mysql的處理能力問題(2)MySql
- 一次詭異的MySQL問題處理故事MySql
- js 處理四則運算失去精度問題JS
- mysql常用語句及問題處理MySql
- AIX OOM問題AIOOM
- 記一次oom問題排查OOM
- 一次線上OOM問題分析OOM
- 【MySQL】Incorrect string value 問題一則MySql
- 【問題處理】MySQL忘記root密碼的處理辦法MySql密碼
- mysql5.7安裝及問題處理MySql
- 一個NBU問題的處理
- windows的一個問題處理Windows
- dataguard故障處理一則
- hive job oom問題HiveOOM
- MongoDB觸發oom-killer的簡單處理(一)MongoDBOOM
- 【問題處理】使用者無法順利刪除問題處理一則-ORA-00604和ORA-00942錯誤
- mysql中文字元的問題全面處理MySql字元
- MySQL自定義變數處理行號問題MySql變數
- 一次efi的問題處理
- 記一次OOM問題排查過程OOM
- 一次徹底講清如何處理mysql 的死鎖問題MySql
- mysql自動斷開連線的問題處理MySql
- 一次線上OOM問題的個人覆盤OOM
- 處理問題的方法
- perl中文處理問題
- 漢字處理問題?
- xml處理的問題XML