1. 程式人生 > 資料庫 >MySQL8.0記憶體相關引數總結

MySQL8.0記憶體相關引數總結

MySQL理論上使用的記憶體 = 全域性共享記憶體 + max_connections×執行緒獨享記憶體。

也就是:innodb_buffer_pool_size + innodb_log_buffer_size + thread_cache_size +table_open_cache + table_definition_cache +key_buffer_size + max_connections *( thread_stack+ sort_buffer_size+join_buffer_size + read_buffer_size+read_rnd_buffer_size+ binlog_cache_size+tmp_table_size)

下面我們按照全域性記憶體引數與執行緒獨享引數分類,簡單介紹下相關引數的作用。

全域性共享記憶體

innodb_buffer_pool_size

innodb_buffer_pool_size這個引數是對Mysql資料庫最重要的引數之一,它對 InnoDB 儲存引擎的作用類似於 Key Buffer Cache 對 MyISAM 儲存引擎的影響,主要區別是 InnoDB Buffer Pool 不僅僅快取索引資料,會快取表的資料,而且完全按照資料檔案中的資料快結構資訊來快取,這一點和 Oracle SGA 中的 database buffer cache 類似,因此在SHOW ENGINE innodb status中查到的Buffer pool size要乘以16K。

可以通過 (Innodb_buffer_pool_read_requests - Innodb_buffer_pool_reads) / Innodb_buffer_pool_read_requests * 100% 計算得到 InnoDB Buffer Pool 的命中率。

innodb_change_buffering

change buffering是MySQL5.5加入的新特性,change buffering是insert buffer的加強,insert buffer只針對insert有效,change buffering對insert、delete、update(delete+insert)、purge都有效。當修改一個索引塊(secondary index)時的資料時,索引塊在buffter pool中不存在,修改資訊就會被cache在change buffer中,當通過索引掃描把需要的索引塊讀取到buffer pool時,會和change buffer中修改資訊合併,再擇機寫回disk。

目的還是為了減少隨機IO帶來效能損耗,說明白了:把隨機IO儘量變成順序IO。現在SSD盛行,在SSD上隨機訪問和順序訪問效能幾乎差不多的情況下,change buffering特性不會帶來多大的效能提升,但對於廉價的機械硬碟,這個引數還是能幫助提高效能的。

change buffering由引數innodb_change_buffering控制:

  • all: buffer inserts,delete-marking operations,and purges.
  • none: Do not buffer any operations.
  • inserts: Buffer insert operations.
  • deletes: Buffer delete-marking operations.
  • changes: Buffer both inserts and delete-marking.
  • purges: Buffer the physical deletion operations that happen in the background.

注意這個記憶體是在Innodb的buffer pool中分配的,計算總記憶體的時候不用算它。

innodb_change_buffer_max_size

表示change buffer在buffer pool中的最大佔比,預設25%,最大50%。如果系統中有嚴重的insert、update並且還有活躍的delete時,就增大max_size;針對不更改資料的純報表系統,可以減小該引數值。

innodb_log_buffer_size

這是 InnoDB 儲存引擎的事務日誌所使用的緩衝區。為了提高效能,也是先將資訊寫入 Innofb Log Buffer 中,當滿足 innodb_flush_log_trx_commit 引數所設定的相應條件(或者日誌緩衝區寫滿)之後,才會將日誌寫到檔案(或者同步到磁碟)中。innodb_flush_log_trx_commit 引數可以設定為0,1,2,解釋如下:

  • 0:log buffer中的資料將以每秒一次的頻率寫入到logfile中,且同時會進行檔案系統到磁碟的同步操作,但是每個事務的commit並不會觸發任何log buffer 到log file的重新整理或者檔案系統到磁碟的重新整理操作,該模式速度最快,但不太安全,mysqld程序的崩潰會導致上一秒鐘所有事務資料的丟失;
  • 1:在每次事務提交的時候將log buffer 中的資料都會寫入到logfile,同時也會觸發檔案系統到磁碟的同步,該模式是最安全的,但也是最慢的一種方式;
  • 2:事務提交會觸發log buffer 到logfile的重新整理,但並不會觸發磁碟檔案系統到磁碟的同步,該模式速度較快,也比0安全,只有在作業系統崩潰或者系統斷電的情況下,上一秒鐘所有事務資料才可能丟失。

thread_cache_size

執行緒池快取大小,當客戶端斷開連線後將當前執行緒快取起來,當在接到新的連線請求時快速響應無需建立新的執行緒 。這尤其對那些使用短連線的應用程式來說可以極大的提高建立連線的效率。可以通過(Connections - Threads_created) / Connections * 100% 計算出連線執行緒快取的命中率。也可以通過如下幾個MySQL狀態值來適當調整執行緒池的大小:

mysql> show global status like 'Thread%';
+-------------------+-------+
| Variable_name   | Value |
+-------------------+-------+
| Threads_cached  | 2   |
| Threads_connected | 1   |
| Threads_created  | 3   |
| Threads_running  | 2   |
+-------------------+-------+
4 rows in set (0.01 sec)

當 Threads_cached 越來越少 但 Threads_connected 始終不降,且 Threads_created 持續升高,可適當增加 thread_cache_size 的大小。

table_open_cache

table_open_cache指定表快取記憶體的大小,用來快取表文件的檔案控制代碼資訊。當我們的客戶端程式提交Query給MySQL的時候,MySQL需要對Query所涉及到的每一個表都取得一個表文件控制代碼資訊,如果沒有Table Cache,那麼MySQL就不得不頻繁的進行開啟關閉檔案操作,無疑會對系統性能產生一定的影響,每當MySQL訪問一個表時,如果在表緩衝區中還有空間,該表就被開啟並放入其中,這樣可以更快地訪問表內容。注意,這裡設定的是可以快取的表文件控制代碼資訊的數目,而不是記憶體空間的大小。

通過檢查峰值時間的狀態值Open_tables和Opened_tables,可以決定是否需要增加table_open_cache的值。其中Open_tables是當前正在開啟表的數量,Opened_tables是所有已經開啟表的數量。注意,不能盲目地把table_open_cache設定成很大的值,設定太大超過了shell的檔案描述符(通過ulimit -n檢視),造成檔案描述符不足,從而造成效能不穩定或者連線失敗。如果發現open_tables等於table_open_cache,並且opened_tables在不斷增長,那麼你就需要增加table_open_cache的值了(上述狀態值可通過SHOW GLOBAL STATUS LIKE 'Open%tables'獲得)。如果Open_tables的值已經接近table_cache的值,且Opened_tables還在不斷變大,則說明mysql正在將快取的表釋放以容納新的表,此時可能需要加大table_cache的值。對於大多數情況,比較適合的值:

  • Open_tables / Opened_tables >= 0.85
  • Open_tables / table_cache <= 0.95

建議把MySQL資料庫放在生產環境中試執行一段時間,然後把引數的值調整得比Opened_tables的數值大一些,並且保證在比較高負載的極端條件下依然比Opened_tables略大。

table_definition_cache

table_definition_cache和table_open_cache類似,前者快取frm檔案,關於後者,文件中並沒有說明,應該是ibd/MYI/MYD;

狀態值:

Open_table_definitions:表定義檔案.frm被快取的數量

Opened_table_definitions:歷史上總共被快取過的,frm檔案數量

key_buffer_size

key_buffer_size指定索引緩衝區的大小,它決定索引處理的速度,尤其是索引讀的速度。通過檢查狀態值Key_read_requests和Key_reads,可以知道key_buffer_size設定是否合理。比例key_reads /key_read_requests應該儘可能的低,至少是1:100,1:1000更好(上述狀態值可以使用SHOW STATUS LIKE ‘key_read%'獲得)。key_buffer_size只對MyISAM表起作用。即使你不使用MyISAM表,但是內部的臨時磁碟表是MyISAM表,也要使用該值。可以使用檢查狀態值created_tmp_disk_tables得知詳情。

max_connections

MySQL的最大連線數,增加該值增加mysqld 要求的檔案描述符的數量。如果伺服器的併發連線請求量比較大,建議調高此值,以增加並行連線數量,當然這建立在機器能支撐的情況下,因為如果連線數越多,介於MySQL會為每個連線提供連線緩衝區,就會開銷越多的記憶體,所以要適當調整該值,不能盲目提高設值。數值過小會經常出現ERROR 1040: Too many connections錯誤,可以過'conn%'萬用字元檢視當前狀態的連線數量,以定奪該值的大小。max_used_connections / max_connections * 100% (理想值≈ 85%) 如果max_used_connections跟max_connections相同 那麼就是max_connections設定過低或者超過伺服器負載上限了,低於10%則設定過大。

執行緒/會話/連線獨享記憶體

binlog_cache_size

為每個session 分配的記憶體,在事務過程中用來儲存二進位制日誌的快取,可以提高記錄bin-log的效率,預設32K,沒有大事務,dml也不是很頻繁的情況下可以設定小一點,如果事務大而且多,dml操作也頻繁,則可以適當的調大一點。

資料庫binlog_cache_size的使用情況,可以檢視:Binlog_cache_disk_use表示因為我們binlog_cache_size設計的記憶體不足導致快取二進位制日誌用到了臨時檔案的次數,Binlog_cache_use 表示 用binlog_cache_size快取的次數

tmp_table_size和max_heap_table_size

tmp_table_size規定了內部記憶體臨時表的最大值,每個執行緒都要分配。(實際起限制作用的是tmp_table_size和max_heap_table_size的最小值。)如果記憶體臨時表超出了限制,MySQL就會自動地把它轉化為基於磁碟的MyISAM表,儲存在指定的tmpdir目錄下,預設:

mysql> show variables like "tmpdir";
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| tmpdir    | /tmp/ |
+---------------+-------+

優化查詢語句的時候,要避免使用臨時表,如果實在避免不了的話,要保證這些臨時表是存在記憶體中的。如果需要的話並且你有很多group by語句,並且你有很多記憶體,增大tmp_table_size(和max_heap_table_size)的值。這個變數不適用與使用者建立的記憶體表(memory table)。

可以比較內部基於磁碟的臨時表的總數和建立在記憶體中的臨時表的總數(Created_tmp_disk_tables和Created_tmp_tables),一般的比例關係是:

Created_tmp_disk_tables/Created_tmp_tables<5%

max_heap_table_size定義了使用者可以建立的記憶體表(memory table)的大小.這個值用來計算記憶體表的最大行數值。這個變數支援動態改變,即set @max_heap_table_size = xxx。

以上就是MySQL8.0記憶體相關引數總結的詳細內容,更多關於mysql8.0 記憶體引數的資料請關注我們其它相關文章!