- 1、Linux系統下mysql運行慢,請給出分析方案!!
- 2、linux 服務器mysql的CPU占的高是怎麼回事啊
- 3、Linux上MySQL優化提升性能 哪些可以優化的關閉NUMA特性
Linux 進程通過 C 標準庫中的內存分配函數 malloc 向系統申請內存,但是到真正與內核交互之間,其實還隔了一層,即內存分配管理器(memory allocator)。常見的內存分配器包括:ptmalloc(Glibc)、tcmalloc(Google)、jemalloc(FreeBSD)。MySQL 默認使用的是 glibc 的 ptmalloc 作為內存分配器。
內存分配器採用的是內存池的管理方式,處在用戶程序層和內核層之間,它響應用戶的分配請求,向操作系統申請內存,然後將其返回給用戶程序。
為了保持高效的分配,分配器通常會預先向操作系統申請一塊內存,當用戶程序申請和釋放內存的時候,分配器會將這些內存管理起來,並通過一些算法策略來判斷是否將其返回給操作系統。這樣做的最大好處就是可以避免用戶程序頻繁的調用系統來進行內存分配,使用戶程序在內存使用上更加高效快捷。
關於 ptmalloc 的內存分配原理,個人也不是非常了解,這裡就不班門弄斧了,有興趣的同學可以去看下華庭的《glibc 內存管理 ptmalloc 源代碼分析》。
關於如何選擇這三種內存分配器,網上資料大多都是推薦摒棄 glibc 原生的 ptmalloc,而改用 jemalloc 或者 tcmalloc 作為默認分配器。因為 ptmalloc 的主要問題其實是內存浪費、內存碎片、以及加鎖導致的性能問題,而 jemalloc 與 tcmalloc 對於內存碎片、多線程處理優化的更好。
目前 jemalloc 應用於 Firefox、FaceBook 等,並且是 MariaDB、Redis、Tengine 默認推薦的內存分配器,而 tcmalloc 則應用於 WebKit、Chrome 等。
先 找到 CPU 高的線程,如果 CPU 高的線程號一直在變,那可能不是單個 SQL 引起的 CPU 消耗,需要用其他方法來輔助分析。找到線程任務processlist 。
可以看到很多有用的信息:
1. 可以看到 processlist 中對應這根線程的信息
2. 可以找到其在 processlist 中的 ID,這樣我們就可以下 kill 命令來結束 SQL
小貼士:
使用 performance_schema 時,需要大家注意 MySQL 使用了多個線程編號,源自於不同視角:
1. PROCESSLIST_ID:在 processlist 中的編號,是使用者視角的編號,使用者可以直接用 kill 命令。
2. THREAD_ID:是 MySQL 內部使用的線程編號,是 MySQL 內部視角的編號。
3. THREAD_OS_ID:是在操作系統上,對應的線程編號,是操作系統視角的編號。
大家使用時需要區分好,不要 kill 錯了 SQL。
其他有用的信息,可以看到 SQL 執行的開始時間,正在使用了一張臨時磁盤表。
如果開啟了 performance_schema 的其他監控項,通過 Thread_ID 關聯,可以找到更多信息。
當然,眼下這麼明顯的坑 SQL,我們 kill 掉就是了。
Linux上MySQL優化提升性能,可以優化關閉NUMA特性如下:
這些其實都源於CPU最新的技術:節能模式。操作系統和CPU硬件配合,系統不繁忙的時候,為了節約電能和降低溫度,它會將CPU降頻。
為了保證MySQL能夠充分利用CPU的資源,建議設置CPU為最大性能模式。這個設置可以在BIOS和操作系統中設置,當然,在BIOS中設置該選項更好,更徹底。
然後我們看看內存方面,我們有哪些可以優化的。
i)
我們先看看numa
非一致存儲訪問結構
(NUMA
:
Non-Uniform
Memory
Access)
也是最新的內存管理技術。它和對稱多處理器結構
(SMP
:
Symmetric
Multi-Processor)
是對應的。
我們可以直觀的看到:SMP訪問內存的都是代價都是一樣的;但是在NUMA架構下,本地內存的訪問和非
本地內存的訪問代價是不一樣的。對應的根據這個特性,操作系統上,我們可以設置進程的內存分配方式。目前支持的方式包括:
–interleave=nodes
–membind=nodes
–cpunodebind=nodes
–physcpubind=cpus
–localalloc
–preferred=node
簡而言之,就是說,你可以指定內存在本地分配,在某幾個CPU節點分配或者輪詢分配。除非
是設置為–interleave=nodes輪詢分配方式,即內存可以在任意NUMA節點上分配這種方式以外。其他的方式就算其他NUMA節點上還有內
存剩餘,Linux也不會把剩餘的內存分配給這個進程,而是採用SWAP的方式來獲得內存。
所以最簡單的方法,還是關閉掉這個特性。
關閉特性的方法,分別有:可以從BIOS,操作系統,啟動進程時臨時關閉這個特性。
a)
由於各種BIOS類型的區別,如何關閉NUMA千差萬別,我們這裡就不具體展示怎麼設置了。
b)
在操作系統中關閉,可以直接在/etc/grub.conf的kernel行最後添加numa=off,如下所示:
kernel
/vmlinuz-2.6.32-220.el6.x86_64
ro
root=/dev/mapper/VolGroup-root
rd_NO_LUKS.UTF-8
rd_LVM_LV=VolGroup/root
rd_NO_MD
quiet
SYSFONT=latarcyrheb-sun16
rhgb
crashkernel=auto
rd_LVM_LV=VolGroup/swap
rhgb
crashkernel=auto
quiet
KEYBOARDTYPE=pc
KEYTABLE=us
rd_NO_DM
numa=off
另外可以設置
vm.zone_reclaim_mode=0盡量回收內存。
c)
啟動MySQL的時候,關閉NUMA特性:
numactl
–interleave=all
mysqld
當然,最好的方式是在BIOS中關閉。
ii)
我們再看看vm.swappiness。
vm.swappiness是操作系統控制物理內存交換出去的策略。它允許的值是一個百分比的值,最小為0,最大運行100,該值默認為60。vm.swappiness設置為0表示盡量少swap,100表示盡量將inactive的內存頁交換出去。
具體的說:當內存基本用滿的時候,系統會根據這個參數來判斷是把內存中很少用到的inactive
內存交換出去,還是釋放數據的cache。
原創文章,作者:VIMU6,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/127305.html