Linux 進程通過 C 標準庫中的內(nèi)存分配函數(shù) malloc 向系統(tǒng)申請內(nèi)存,但是到真正與內(nèi)核交互之間,其實還隔了一層,即內(nèi)存分配管理器(memory allocator)。常見的內(nèi)存分配器包括:ptmalloc(Glibc)、tcmalloc(Google)、jemalloc(FreeBSD)。MySQL 默認使用的是 glibc 的 ptmalloc 作為內(nèi)存分配器。

成都創(chuàng)新互聯(lián)-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設、高性價比盈江網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式盈江網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設找我們,業(yè)務覆蓋盈江地區(qū)。費用合理售后完善,10多年實體公司更值得信賴。
內(nèi)存分配器采用的是內(nèi)存池的管理方式,處在用戶程序?qū)雍蛢?nèi)核層之間,它響應用戶的分配請求,向操作系統(tǒng)申請內(nèi)存,然后將其返回給用戶程序。
為了保持高效的分配,分配器通常會預先向操作系統(tǒng)申請一塊內(nèi)存,當用戶程序申請和釋放內(nèi)存的時候,分配器會將這些內(nèi)存管理起來,并通過一些算法策略來判斷是否將其返回給操作系統(tǒng)。這樣做的最大好處就是可以避免用戶程序頻繁的調(diào)用系統(tǒng)來進行內(nèi)存分配,使用戶程序在內(nèi)存使用上更加高效快捷。
關于 ptmalloc 的內(nèi)存分配原理,個人也不是非常了解,這里就不班門弄斧了,有興趣的同學可以去看下華庭的《glibc 內(nèi)存管理 ptmalloc 源代碼分析》【文末鏈接】。
關于如何選擇這三種內(nèi)存分配器,網(wǎng)上資料大多都是推薦摒棄 glibc 原生的 ptmalloc,而改用 jemalloc 或者 tcmalloc 作為默認分配器。因為 ptmalloc 的主要問題其實是內(nèi)存浪費、內(nèi)存碎片、以及加鎖導致的性能問題,而 jemalloc 與 tcmalloc 對于內(nèi)存碎片、多線程處理優(yōu)化的更好。
目前 jemalloc 應用于 Firefox、FaceBook 等,并且是 MariaDB、Redis、Tengine 默認推薦的內(nèi)存分配器,而 tcmalloc 則應用于 WebKit、Chrome 等。
MySQL CPU占用過高原因主要有以下幾種
CPU過時(比較舊的CPU)
RAM資源不足(RAM記憶體)
解決辦法如下:
①臨時解決方案
首先是ctrl+alt+delete快捷鍵打開工作管理員
然后找到下方圖一中的mysqld.exe
右擊移至詳細資料
再來右擊設定優(yōu)先順序
按照下方圖二的步驟
根據(jù)占用情況調(diào)整成低于標準或者低
這個方法只能臨時解決
②實際解決方法是更換CPU
總結(jié):根據(jù)正常的mysql使用,即使大量數(shù)據(jù)往來也不會造成CPU占用過高,目前推論應該是CPU比較過時的原因,治標不治本的臨時解決方案。
備注:如采取方案②你需要備份你的資料,因為更換CPU會有很大的機會需要重新安裝你的作業(yè)系統(tǒng)。
一臺服務器解決了 Mysql cpu 占用 100% 的問題。稍整理了一下,將經(jīng)驗記錄在這篇文章里。
朋友主機(Windows 2003 + IIS + PHP + MYSQL )近來 MySQL 服務進程 (mysqld-nt.exe) CPU 占用率總為 100% 高居不下。此主機有10個左右的 database, 分別給十個網(wǎng)站調(diào)用。據(jù)朋友測試,導致 mysqld-nt.exe cpu 占用奇高的是網(wǎng)站A,一旦在 IIS 中將此網(wǎng)站停止服務,CPU 占用就降下來了。一啟用,則馬上上升。
MYSQL CPU 占用 100% 的解決過程
今天早上仔細檢查了一下。目前此網(wǎng)站的七日平均日 IP 為2000,PageView 為 3萬左右。網(wǎng)站A 用的 database 目前有39個表,記錄數(shù) 60.1萬條,占空間 45MB。按這個數(shù)據(jù),MySQL 不可能占用這么高的資源。于是在服務器上運行命令,將 mysql 當前的環(huán)境變量輸出到文件 output.txt:
d:\web\mysql mysqld.exe --help output.txt發(fā)現(xiàn) tmp_table_size 的值是默認的 32M,于是修改 My.ini, 將 tmp_table_size 賦值到 200M:
d:\web\mysql notepad c:\windows\my.ini
[mysqld]
tmp_table_size=200M
然后重啟 MySQL 服務。CPU 占用有輕微下降,以前的CPU 占用波形圖是 100% 一根直線,現(xiàn)在則在 97%~100%之間起伏。這表明調(diào)整 tmp_table_size 參數(shù)對 MYSQL 性能提升有改善作用。但問題還沒有完全解決。
于是進入 mysql 的 shell 命令行,調(diào)用 show processlist, 查看當前 mysql 使用頻繁的 sql 語句:
mysql show processlist;
反復調(diào)用此命令,發(fā)現(xiàn)網(wǎng)站 A 的兩個 SQL 語句經(jīng)常在 process list 中出現(xiàn),其語法如下:
SELECT t1.pid, t2.userid, t3.count, t1.dateFROM _mydata AS t1
LEFT JOIN _myuser AS t3 ON t1.userid=t3.useridLEFT JOIN _mydata_body AS t2 ON t1.pid=t3.pidORDER BY t1.pid
LIMIT 0,15
調(diào)用 show columns 檢查這三個表的結(jié)構 :
mysql show columns from _myuser;
mysql show columns from _mydata;
mysql show columns from _mydata_body;
終于發(fā)現(xiàn)了問題所在:_mydata 表,只根據(jù) pid 建立了一個 primary key,但并沒有為 userid 建立索引。而在這個 SQL 語句的第一個 LEFT JOIN ON 子句中:
LEFT JOIN _myuser AS t3 ON t1.userid=t3.userid_mydata 的 userid 被參與了條件比較運算。于是我為給 _mydata 表根據(jù)字段 userid 建立了一個索引:
mysql ALTER TABLE `_mydata` ADD INDEX ( `userid` )建立此索引之后,CPU 馬上降到了 80% 左右。看到找到了問題所在,于是檢查另一個反復出現(xiàn)在 show processlist 中的 sql 語句:
SELECT COUNT(*)
FROM _mydata AS t1, _mydata_key AS t2
WHERE t1.pid=t2.pid and t2.keywords = '孔雀'
經(jīng)檢查 _mydata_key 表的結(jié)構,發(fā)現(xiàn)它只為 pid 建了了 primary key, 沒有為 keywords 建立 index。_mydata_key 目前有 33 萬條記錄,在沒有索引的情況下對33萬條記錄進行文本檢索匹配,不耗費大量的 cpu 時間才怪。看來就是針對這個表的檢索出問題了。于是同樣為 _mydata_key 表根據(jù)字段 keywords 加上索引:
mysql ALTER TABLE `_mydata_key` ADD INDEX ( `keywords` )建立此索引之后,CPU立刻降了下來,在 50%~70%之間震蕩。
再次調(diào)用 show prosslist,網(wǎng)站A 的sql 調(diào)用就很少出現(xiàn)在結(jié)果列表中了。但發(fā)現(xiàn)此主機運行了幾個 Discuz 的論壇程序, Discuz 論壇的好幾個表也存在著這個問題。于是順手一并解決,cpu占用再次降下來了。(2007.07.09 附注:關于 discuz 論壇的具體優(yōu)化過程,我后來另寫了一篇文章,詳見:千萬級記錄的 Discuz! 論壇導致 MySQL CPU 100% 的 優(yōu)化筆記 )解決 MYSQL CPU 占用 100% 的經(jīng)驗總結(jié)
增加 tmp_table_size 值。mysql 的配置文件中,tmp_table_size 的默認大小是 32M。如果一張臨時表超出該大小,MySQL產(chǎn)生一個 The table tbl_name is full 形式的錯誤,如果你做很多高級 GROUP BY 查詢,增加 tmp_table_size 值。 這是 mysql 官方關于此選項的解釋:
tmp_table_size
This variable determines the maximum size for a temporary table in memory. If the table becomes too large, a MYISAM table is created on disk. Try to avoid temporary tables by optimizing the queries where possible, but where this is not possible, try to ensure temporary tables are always stored in memory. Watching the processlist for queries with temporary tables that take too long to resolve can give you an early warning that tmp_table_size needs to be upped. Be aware that memory is also allocated per-thread. An example where upping this worked for more was a server where I upped this from 32MB (the default) to 64MB with immediate effect. The quicker resolution of queries resulted in less threads being active at any one time, with all-round benefits for the server, and available memory.
對 WHERE, JOIN, MAX(), MIN(), ORDER BY 等子句中的條件判斷中用到的字段,應該根據(jù)其建立索引 INDEX。索引被用來快速找出在一個列上用一特定值的行。沒有索引,MySQL不得不首先以第一條記錄開始并然后讀完整個表直到它找出相關的行。表越大,花費時間越多。如果表對于查詢的列有一個索引,MySQL能快速到達一個位置去搜尋到數(shù)據(jù)文件的中間,沒有必要考慮所有數(shù)據(jù)。如果一個表有1000行,這比順序讀取至少快100倍。所有的MySQL索引(PRIMARY、UNIQUE和INDEX)在B樹中存儲。根據(jù) mysql 的開發(fā)文檔:
索引 index 用于:
快速找出匹配一個WHERE子句的行
當執(zhí)行聯(lián)結(jié)(JOIN)時,從其他表檢索行。
對特定的索引列找出MAX()或MIN()值
如果排序或分組在一個可用鍵的最左面前綴上進行(例如,ORDER BY key_part_1,key_part_2),排序或分組一個表。如果所有鍵值部分跟隨DESC,鍵以倒序被讀取。
在一些情況中,一個查詢能被優(yōu)化來檢索值,不用咨詢數(shù)據(jù)文件。如果對某些表的所有使用的列是數(shù)字型的并且構成某些鍵的最左面前綴,為了更快,值可以從索引樹被檢索出來。假定你發(fā)出下列SELECT語句:
mysql SELECT * FROM tbl_name WHERE col1=val1 AND col2=val2;如果一個多列索引存在于col1和col2上,適當?shù)男锌梢灾苯颖蝗〕觥H绻珠_的單行列索引存在于col1和col2上,優(yōu)化器試圖通過決定哪個索引將找到更少的行并來找出更具限制性的索引并且使用該索引取行。
開發(fā)人員做 SQL 數(shù)據(jù)表設計的時候,一定要通盤考慮清楚。
生產(chǎn)環(huán)境中,MySQL 不經(jīng)意間吃掉全部的內(nèi)容,然后開始吃掉 SWAP,性能一降再降,怎么辦?
可以從下面三點查看原因:
MySQL 使用內(nèi)存,有兩個途徑。
永久占用的內(nèi)容
比如全局緩沖區(qū)(Global Buffer)類別,是在服務器啟動期間從操作系統(tǒng)獲得的,不會釋放到任何一個別的進程。
動態(tài)請求的內(nèi)存
線程緩沖區(qū)由MySQL使用,它是在處理新查詢時從操作系統(tǒng)請求的內(nèi)存。在執(zhí)行查詢之后,該內(nèi)存被釋放回操作系統(tǒng)。
這意味著 MySQL 的內(nèi)存使用,是 全局緩沖區(qū) 加上 線程緩沖區(qū) 以及 允許的最大連接數(shù) 。
對于專用數(shù)據(jù)庫服務器,該值需要保持在服務器內(nèi)存的90%以下。在共享服務器的情況下,它應該保持在服務器內(nèi)存的50%以下。
檢查一下 MySQL 設置,有助于確定內(nèi)存使用情況,從而為 MySQL 分配合適的值。
一個近似的公式:
當網(wǎng)站受到攻擊時,有可能在短時間內(nèi)建立異常高的連接數(shù)量。MySQL 中的 PROCESSLIST 可用于檢測頂級用戶并阻止對濫用連接的訪問。
找出查詢需要很長時間才能執(zhí)行的語句,因為這些查詢需要進一步優(yōu)化服務器才能更好地執(zhí)行,可以通過服務器查詢?nèi)罩具M行識別。由于查詢速度慢,導致磁盤讀取較多,導致內(nèi)存和CPU使用率較高,影響服務器性能。
最后,到了加內(nèi)存條的時候了。雖然在優(yōu)化數(shù)據(jù)庫設置之后,服務器會不斷地路由到使用交換內(nèi)存,但也必須增加內(nèi)存。俗話說:“巧婦難為無米之炊”,就是這個意思。
上面說的這些方向,大家可以在實際操作中驗證體會,希望大家在數(shù)據(jù)庫優(yōu)化的路上,麻溜順暢,砥礪前行。
本文題目:mysql高了怎么辦,mysql降低高水位
瀏覽地址:http://chinadenli.net/article39/dsgogsh.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站改版、面包屑導航、做網(wǎng)站、微信公眾號、定制開發(fā)、App設計
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)