有一個(gè)表引擎叫內(nèi)存表,你在新建時(shí)可以選擇,或已有的表可以修改過去
站在用戶的角度思考問題,與客戶深入溝通,找到麗水網(wǎng)站設(shè)計(jì)與麗水網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗(yàn),讓設(shè)計(jì)與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個(gè)性化、用戶體驗(yàn)好的作品,建站類型包括:成都網(wǎng)站制作、成都網(wǎng)站建設(shè)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、域名注冊(cè)、網(wǎng)站空間、企業(yè)郵箱。業(yè)務(wù)覆蓋麗水地區(qū)。
生產(chǎn)環(huán)境中,MySQL 不經(jīng)意間吃掉全部的內(nèi)容,然后開始吃掉 SWAP,性能一降再降,怎么辦?
可以從下面三點(diǎn)查看原因:
MySQL 使用內(nèi)存,有兩個(gè)途徑。
永久占用的內(nèi)容
比如全局緩沖區(qū)(Global Buffer)類別,是在服務(wù)器啟動(dòng)期間從操作系統(tǒng)獲得的,不會(huì)釋放到任何一個(gè)別的進(jìn)程。
動(dòng)態(tài)請(qǐng)求的內(nèi)存
線程緩沖區(qū)由MySQL使用,它是在處理新查詢時(shí)從操作系統(tǒng)請(qǐng)求的內(nèi)存。在執(zhí)行查詢之后,該內(nèi)存被釋放回操作系統(tǒng)。
這意味著 MySQL 的內(nèi)存使用,是 全局緩沖區(qū) 加上 線程緩沖區(qū) 以及 允許的最大連接數(shù) 。
對(duì)于專用數(shù)據(jù)庫服務(wù)器,該值需要保持在服務(wù)器內(nèi)存的90%以下。在共享服務(wù)器的情況下,它應(yīng)該保持在服務(wù)器內(nèi)存的50%以下。
檢查一下 MySQL 設(shè)置,有助于確定內(nèi)存使用情況,從而為 MySQL 分配合適的值。
一個(gè)近似的公式:
當(dāng)網(wǎng)站受到攻擊時(shí),有可能在短時(shí)間內(nèi)建立異常高的連接數(shù)量。MySQL 中的 PROCESSLIST 可用于檢測頂級(jí)用戶并阻止對(duì)濫用連接的訪問。
找出查詢需要很長時(shí)間才能執(zhí)行的語句,因?yàn)檫@些查詢需要進(jìn)一步優(yōu)化服務(wù)器才能更好地執(zhí)行,可以通過服務(wù)器查詢?nèi)罩具M(jìn)行識(shí)別。由于查詢速度慢,導(dǎo)致磁盤讀取較多,導(dǎo)致內(nèi)存和CPU使用率較高,影響服務(wù)器性能。
最后,到了加內(nèi)存條的時(shí)候了。雖然在優(yōu)化數(shù)據(jù)庫設(shè)置之后,服務(wù)器會(huì)不斷地路由到使用交換內(nèi)存,但也必須增加內(nèi)存。俗話說:“巧婦難為無米之炊”,就是這個(gè)意思。
上面說的這些方向,大家可以在實(shí)際操作中驗(yàn)證體會(huì),希望大家在數(shù)據(jù)庫優(yōu)化的路上,麻溜順暢,砥礪前行。
我們?nèi)匀皇褂脙蓚€(gè)會(huì)話,一個(gè)會(huì)話 run,用于運(yùn)行主 SQL;另一個(gè)會(huì)話 ps,用于進(jìn)行 performance_schema 的觀察:
主會(huì)話線程號(hào)為 29,
將 performance_schema 中的統(tǒng)計(jì)量重置,
臨時(shí)表的表大小限制取決于參數(shù)? tmp_table_size 和 max_heap_table_size 中較小者,我們實(shí)驗(yàn)中以設(shè)置 max_heap_table_size 為例。
我們將會(huì)話級(jí)別的臨時(shí)表大小設(shè)置為 2M(小于上次實(shí)驗(yàn)中臨時(shí)表使用的空間),執(zhí)行使用臨時(shí)表的 SQL:
查看內(nèi)存的分配記錄:
會(huì)發(fā)現(xiàn)內(nèi)存分配略大于 2M,我們猜測臨時(shí)表會(huì)比配置略多一點(diǎn)消耗,可以忽略。
查看語句的特征值:
可以看到語句使用了一次需要落磁盤的臨時(shí)表。
那么這張臨時(shí)表用了多少的磁盤呢?
我們開啟 performance_schema 中 waits 相關(guān)的統(tǒng)計(jì)項(xiàng):
重做實(shí)驗(yàn),略過。
再查看 performance_schema 的統(tǒng)計(jì)值:
可以看到幾個(gè)現(xiàn)象:
1. 臨時(shí)表空間被寫入了 7.92MiB 的數(shù)據(jù)。
2. 這些數(shù)據(jù)是語句寫入后,慢慢逐漸寫入的。
來看看這些寫入操作的特征,該方法我們?cè)?實(shí)驗(yàn) 03?使用過:
可以看到寫入的線程是 page_clean_thread,是一個(gè)刷臟操作,這樣就能理解數(shù)據(jù)為什么是慢慢寫入的。
也可以看到每個(gè) IO 操作的大小是 16K,也就是刷數(shù)據(jù)頁的操作。
結(jié)論:
我們可以看到,
1. MySQL 會(huì)基本遵守 max_heap_table_size 的設(shè)定,在內(nèi)存不夠用時(shí),直接將表轉(zhuǎn)到磁盤上存儲(chǔ)。
2. 由于引擎不同(內(nèi)存中表引擎為 heap,磁盤中表引擎則跟隨 internal_tmp_disk_storage_engine 的配置),本次實(shí)驗(yàn)寫磁盤的數(shù)據(jù)量和?實(shí)驗(yàn) 05?中使用內(nèi)存的數(shù)據(jù)量不同。
3. 如果臨時(shí)表要使用磁盤,表引擎配置為 InnoDB,那么即使臨時(shí)表在一個(gè)時(shí)間很短的 SQL 中使用,且使用后即釋放,釋放后也會(huì)刷臟頁到磁盤中,消耗部分 IO。