jbd2/dm-0-8佔用CPU的問題分析與解決

jbd2/dm-0-8佔用CPU的問題分析與解決

jbd2/dm-0-8佔用CPU

0x00 問題的發現

有一臺流媒體服務器,運行的是VOD服務,在併發上升時服務器的CPU load average 持續上升。在查找原因的過程中發現,top 裏的 wa 也比較高,問題的原因可能是IO效率降低;

0x01 iotop 查找佔用IO的進程

 [root@ubuntu ~]# iotop

Total DISK READ :       0.00 B/s | Total DISK WRITE :     7.74 M/s
Actual DISK READ:       0.00 B/s | Actual DISK WRITE:     6.97 M/s
TID  PRIO  USER     DISK READ  DISK WRITE  SWAPIN     IO>    COMMAND
535 be/3 root        0.00 B/s    0.00 B/s  0.00 % 95.80 % [jbd2/dm-0-8]
1826 be/4 mysql       0.00 B/s   22.19 K/s  0.00 %  1.18 % mysqld
1630 be/4 mysql       0.00 B/s  162.72 K/s  0.00 %  0.07 % mysqld
1632 be/4 mysql       0.00 B/s  177.51 K/s  0.00 %  0.07 % mysqld
1631 be/4 mysql       0.00 B/s  147.93 K/s  0.00 %  0.03 % mysqld
1629 be/4 mysql       0.00 B/s   88.76 K/s  0.00 %  0.03 % mysqld
1633 be/4 mysql       0.00 B/s  147.93 K/s  0.00 %  0.03 % mysqld

發現 [jbd2/dm-0-8] 這個進程佔用IO 95%。

0x02 atop -dl 進一步確認IO 使用進程

PID       RDDSK         WRDSK         WCANCL          DSK             CMD
1437      0K              8004K         0K             99%             mysqld
535       0K              56K           0K              1%             jbd2/dm-0-8

確認是 Mysql 在佔用IO。

0x03 解決問題

登錄mysql ,查看sync_binlog變量的值:

[root@ubuntu ~]# mysql -uroot -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2118462
Server version: 5.7.22 MySQL Community Server (GPL)

Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show variables like '%sync_binlog%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| sync_binlog   | 1     |
+---------------+-------+
1 row in set (0.00 sec)

mysql>
  • sync_binlog 值爲1,表示每次提交事務後,將binlog_cache中的數據強制寫入磁盤。這是最安全但是性能損耗最大的設置,系統Crash的時候最多丟失binlog_cache中未完成的一個事務;
  • sync_binlog 值爲 0 時,表示當事務提交之後,MySQL不做fsync之類的磁盤同步指令刷新binlog_cache中的信息到磁盤,而讓Filesystem自行決定什麼時候來做同步,或者cache滿了之後才同步到磁盤。默認設置爲 0,這時性能是最好的,但風險也是最大的,一旦系統Crash,cache中的所有binlog信息都會丟失;
  • sync_binlog 值爲 n 時,當每進行n次事務提交之後,MySQL將進行一次fsync之類的磁盤同步指令來將binlog_cache中的數據強制寫入磁盤。

所以sync_binlog=1,導致事務寫入太頻繁,從而出現 [jbd2/dm-0-8] 這個進程佔用 IO 95%。

因此將sync_log設置爲一個比較大的數,如 200。

mysql> set global sync_binlog=500;
Query OK, 0 rows affected (0.00 sec)

mysql> show variables like '%sync_binlog%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| sync_binlog   | 500   |
+---------------+-------+
1 row in set (0.00 sec)

mysql>

0x04 設置 innodb_flush_log_at_trx_commit 變量.

innodb_flush_log_at_trx_commit 是配置MySql日誌何時寫入硬盤的參數:

  • 0:log buffer 將每秒一次地寫入log file中,並且log file的flush(刷到磁盤)操作同時進行。該模式下在事務提交的時候,不會主動觸發寫入磁盤的操作。
  • 1:每次事務提交時MySQL都會把log buffer的數據寫入log file,並且flush(刷到磁盤)中去,該模式爲系統默認。
  • 2:每次事務提交時mysql都會把log buffer的數據寫入log file,但是flush(刷到磁盤)操作並不會同時進行。該模式下,MySQL會每秒執行一次 flush(刷到磁盤)操作。

一般設置爲2

mysql> show variables like '%innodb_flush_log_at_trx_commit%';
+--------------------------------+-------+
| Variable_name                  | Value |
+--------------------------------+-------+
| innodb_flush_log_at_trx_commit | 1     |
+--------------------------------+-------+
1 row in set (0.01 sec)

mysql> set global innodb_flush_log_at_trx_commit=2;
Query OK, 0 rows affected (0.00 sec)

mysql> show variables like '%innodb_flush_log_at_trx_commit%';
+--------------------------------+-------+
| Variable_name                  | Value |
+--------------------------------+-------+
| innodb_flush_log_at_trx_commit | 2     |
+--------------------------------+-------+
1 row in set (0.01 sec)

再次查看 iotop ,[jbd2/dm-2-8]已明顯降低。

>>> 我的博客

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章