部分 RAID 陣列的間歇性 I/O 延遲導致 MySQL 性能不佳
我正在管理執行 MySQL 數據庫以及其他一些軟體的裸機伺服器。我們看到一些 MySQL 查詢存在性能問題,但這些問題是間歇性發生的,並且幾乎完全影響 UPDATE 查詢。
例如,我有一個大約每 15 秒執行一次的特定查詢。大多數情況下它會在幾毫秒內完成,但有時查詢分析會顯示:
Status Duration starting 0.000026 checking permissions 0.000003 Opening tables 0.000011 System lock 0.000002 init 0.000007 update 0.000052 Waiting for query cache lock 0.000001 update 0.000002 end 0.000001 query end 15.198987 closing tables 0.000023 freeing items 0.000026 logging slow query 0.000014 logging slow query 0.000001 cleaning up 0.000002
我嘗試了this question中的建議,但沒有效果。然後我開始查看較低級別的項目,因為我注意到其他一些軟體也表現出間歇性緩慢響應。
這是性能良好時的最高輸出:
top - 12:09:48 up 138 days, 21:57, 2 users, load average: 2.35, 1.73, 1.55 Tasks: 392 total, 2 running, 388 sleeping, 2 stopped, 0 zombie %Cpu0 : 16.4 us, 1.3 sy, 0.0 ni, 80.3 id, 1.0 wa, 0.0 hi, 1.0 si, 0.0 st %Cpu1 : 9.3 us, 0.7 sy, 0.0 ni, 89.1 id, 0.7 wa, 0.0 hi, 0.3 si, 0.0 st %Cpu2 : 4.0 us, 0.7 sy, 0.0 ni, 95.0 id, 0.3 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu3 : 3.0 us, 0.7 sy, 0.0 ni, 96.3 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu4 : 10.0 us, 0.7 sy, 0.0 ni, 89.3 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu5 : 14.9 us, 0.7 sy, 0.0 ni, 84.4 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu6 : 2.6 us, 0.3 sy, 0.0 ni, 96.4 id, 0.7 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu7 : 1.3 us, 0.0 sy, 0.0 ni, 98.0 id, 0.7 wa, 0.0 hi, 0.0 si, 0.0 st KiB Mem: 32836768 total, 24516984 used, 8319784 free, 143868 buffers KiB Swap: 0 total, 0 used, 0 free. 15166836 cached Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 26264 root 20 0 1255040 81148 17792 S 19.3 0.2 367:38.32 node 1450 root 20 0 1249548 106060 17760 S 7.6 0.3 2612:39 node 30815 root 20 0 1245184 71652 17780 S 5.6 0.2 898:00.21 node 20700 root 20 0 1238644 63004 16812 S 2.3 0.2 635:20.34 node 281 root 20 0 193348 101184 97840 S 2.0 0.3 2832:15 systemd-journal 2974 root 20 0 48404 21688 3812 S 1.3 0.1 1329:51 openvpn 26283 postgres 20 0 235384 45408 42648 S 1.3 0.1 10:17.88 postgres 26284 postgres 20 0 235380 44780 42008 S 1.3 0.1 10:14.81 postgres 25764 root 20 0 1232976 58792 17716 S 1.0 0.2 42:51.01 node 26279 postgres 20 0 235356 45772 43028 S 1.0 0.1 10:13.60 postgres 12793 root 20 0 23956 3300 2488 R 0.7 0.0 0:00.11 top 26280 postgres 20 0 235384 44764 41992 S 0.7 0.1 10:16.64 postgres 27135 postgres 20 0 235380 44932 42156 S 0.7 0.1 10:15.24 postgres 27136 postgres 20 0 235360 44288 41532 S 0.7 0.1 10:15.45 postgres
當它不好時:
top - 12:13:19 up 138 days, 22:00, 2 users, load average: 3.34, 2.45, 1.88 Tasks: 393 total, 2 running, 389 sleeping, 2 stopped, 0 zombie %Cpu0 : 11.1 us, 0.0 sy, 0.0 ni, 0.0 id, 87.8 wa, 0.0 hi, 1.0 si, 0.0 st %Cpu1 : 1.3 us, 0.0 sy, 0.0 ni, 75.5 id, 22.8 wa, 0.0 hi, 0.3 si, 0.0 st %Cpu2 : 5.7 us, 0.3 sy, 0.0 ni, 8.4 id, 85.6 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu3 : 11.0 us, 0.3 sy, 0.0 ni, 74.3 id, 14.3 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu4 : 0.7 us, 0.0 sy, 0.0 ni, 87.3 id, 12.0 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu5 : 1.3 us, 0.0 sy, 0.0 ni, 98.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu6 : 1.0 us, 0.0 sy, 0.0 ni, 99.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu7 : 3.0 us, 0.3 sy, 0.0 ni, 93.3 id, 3.4 wa, 0.0 hi, 0.0 si, 0.0 st KiB Mem: 32836768 total, 24870588 used, 7966180 free, 143868 buffers KiB Swap: 0 total, 0 used, 0 free. 15073140 cached Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 26264 root 20 0 1252992 109712 17792 S 10.0 0.3 368:16.02 node 1450 root 20 0 1255692 112632 17760 S 4.3 0.3 2612:57 node 30815 root 20 0 1240064 81032 17780 S 4.0 0.2 898:13.71 node 20700 root 20 0 1243764 74472 16812 S 2.3 0.2 635:24.22 node 281 root 20 0 58644 22468 19124 S 1.0 0.1 2832:18 systemd-journal 25764 root 20 0 1240144 64560 17716 S 1.0 0.2 42:53.01 node 2974 root 20 0 48404 21688 3812 S 0.7 0.1 1329:53 openvpn 7 root 20 0 0 0 0 S 0.3 0.0 728:52.82 rcu_sched 770 postgres 20 0 235648 45920 42780 S 0.3 0.1 8:11.67 postgres 5476 root 20 0 0 0 0 S 0.3 0.0 0:00.15 kworker/u16:1 12329 root 20 0 0 0 0 D 0.3 0.0 0:00.18 kworker/2:1 12778 root 20 0 0 0 0 R 0.3 0.0 0:00.25 kworker/2:2 26278 postgres 20 0 232340 17764 15544 S 0.3 0.1 5:38.38 postgres 28478 mysql 20 0 7210212 3.677g 8560 S 0.3 11.7 1849:14 mysqld 30829 postgres 20 0 232340 17484 15272 S 0.3 0.1 14:01.09 postgres 1 root 20 0 28968 5188 2864 S 0.0 0.0 5:44.60 systemd 2 root 20 0 0 0 0 S 0.0 0.0 0:12.38 kthreadd 3 root 20 0 0 0 0 S 0.0 0.0 75:39.66 ksoftirqd/0 5 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kworker/0:0H 8 root 20 0 0 0 0 S 0.0 0.0 0:00.00 rcu_bh
遵循一些有關在 Linux 中解決高 I/O 等待問題的建議,我執行了
iostat -xm 5
.這是一個正常的輸出:
avg-cpu: %user %nice %system %iowait %steal %idle 6.05 0.00 0.63 0.80 0.00 92.52 Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await r_await w_await svctm %util sda 0.00 2.60 0.00 58.40 0.00 0.64 22.58 0.02 0.32 0.00 0.32 0.29 1.68 sdb 0.00 2.80 0.00 58.20 0.00 0.64 22.66 0.12 2.10 0.00 2.10 1.70 9.92 md0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 md1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 md2 0.00 0.00 0.00 24.00 0.00 0.10 8.53 0.00 0.00 0.00 0.00 0.00 0.00 md3 0.00 0.00 0.00 27.80 0.00 0.53 39.19 0.00 0.00 0.00 0.00 0.00 0.00 dm-0 0.00 0.00 0.00 24.20 0.00 0.53 45.02 0.22 9.06 0.00 9.06 2.64 6.40
和緩慢的輸出:
avg-cpu: %user %nice %system %iowait %steal %idle 3.90 0.00 0.28 51.05 0.00 44.77 Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await r_await w_await svctm %util sda 0.00 7.20 0.00 42.20 0.00 15.24 739.82 0.35 8.27 0.00 8.27 0.74 3.12 sdb 0.00 7.40 0.00 62.00 0.00 24.69 815.55 110.16 2142.10 0.00 2142.10 16.13 100.00 md0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 md1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 md2 0.00 0.00 0.00 0.40 0.00 0.00 24.00 0.00 0.00 0.00 0.00 0.00 0.00 md3 0.00 0.00 0.00 0.20 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 dm-0 0.00 0.00 0.00 0.20 0.00 0.00 8.00 219.50 3880180.00 0.00 3880180.00 5000.00 100.00
sda 和 sdb 是三星 SSD 850 EVO 1TB 驅動器。每個都有一個相同的分區表,在 RAID1 上創建四個 md 設備:
Personalities : [raid1] md3 : active raid1 sda4[0] sdb4[1] 940987072 blocks super 1.2 [2/2] [UU] bitmap: 2/8 pages [8KB], 65536KB chunk md2 : active raid1 sda3[0] sdb3[1] 19514368 blocks super 1.2 [2/2] [UU] md1 : active raid1 sda2[0] sdb2[1] 15617024 blocks super 1.2 [2/2] [UU] md0 : active raid1 sda1[0] sdb1[1] 487104 blocks super 1.2 [2/2] [UU]
md0 是 /boot,輸入 xfs。md1 用於交換,但目前未使用。md2 是 /,輸入 xfs。最後,md3 是儲存數據的加密卷 (dm-0) 的備份設備:
LUKS header information for /dev/md3 Version: 1 Cipher name: aes Cipher mode: xts-plain64 Hash spec: sha1 Payload offset: 4096
特別困擾我的是 sdb 上的 I/O 負載似乎比 sda 上高得多。由於兩個磁碟都只為 RAID1 陣列提供成員分區,這似乎不對。
我檢查了 sdb 的 SMART 數據,並執行了短期和長期自檢,沒有檢測到問題:
SMART Error Log Version: 1 No Errors Logged SMART Self-test log structure revision number 1 Num Test_Description Status Remaining LifeTime(hours) LBA_of_first_error # 1 Extended offline Completed without error 00% 8719 - # 2 Short offline Completed without error 00% 8711 -
除了每 30 分鐘 smartd 記錄溫度變化外,系統日誌沒有顯示 sdb 的條目。
核心版本:
Linux no 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt25-2+deb8u3 (2016-07-02) x86_64 GNU/Linux
我錯過了什麼?
根據您的
iostat
輸出,sdb
似乎有一個很長的 I/O 隊列,相應的等待時間也很長。為什麼這只發生在
sdb
,而不是兩個磁碟上?這是一種可能的解釋:當您第一次配置 RAID 設備時,所有sda
內容(甚至是無效/垃圾內容)都被複製到sdb
. 這會自動將所有塊標記為已使用,sdb
從而為快閃記憶體塊/頁面回收留下非常少的空間(僅少量過度配置)。這會對消費級磁碟造成嚴重破壞,控制器實際上會暫停所有 I/O 操作以垃圾收集一些快閃記憶體塊。加密分區加劇了這種情況,對於磁碟控制器來說,它基本上看起來像是一個大的二進制部落格。
現在做什麼?如果您的 LUKS 安裝(以及它下面的所有 I/O 堆棧)支持 ATA TRIM 傳遞,您可以簡單地發出
fstrim -v <mntpoint>
命令將所有可用空間標記為未使用。如果它有效,我建議您安排一個夜間 cronjob 在低負載時間自動執行它。在這裡查看更多資訊。如果您的設置不支持 TRIM passdown,那麼您就不走運了:在這種情況下,您必須安全擦除磁碟並重新分區,至少留出 25% 的空間未分配。在某些情況下甚至需要使用
hdparm
設置適當大小Host Protected Area
來手動設置更多的過度配置;但是,三星 850 EVO 不需要這樣做。