天天看點

MYSQL常用緩存

全局共享記憶體主要是 MySQL Instance(mysqld程序)以及底層存儲引擎用來暫存各種全局運算及可共享的暫存資訊,如存儲查詢緩存的 Query Cache,緩存連接配接線程的 Thread Cache,緩存表檔案句柄資訊的 Table Cache,緩存二進制日志的 BinLog Buffer, 緩存 MyISAM 存儲引擎索引鍵的 Key Buffer以及存儲 InnoDB 資料和索引的 InnoDB Buffer Pool 等等。下面針對 MySQL 主要的共享記憶體進行一個簡單的分析。

查詢緩存(Query Cache):查詢緩存是 MySQL 比較獨特的一個緩存區域,用來緩存特定 Query 的結果集(Result Set)資訊,且共享給所有用戶端。通過對 Query 語句進行特定的 Hash 計算之後與結果集對應存放在 Query Cache 中,以提高完全相同的 Query 語句的相應速度。當我們打開 MySQL 的 Query Cache 之後,MySQL 接收到每一個 SELECT 類型的 Query 之後都會首先通過固定的 Hash 算法得到該 Query 的 Hash 值,然後到 Query Cache 中查找是否有對應的 Query Cache。如果有,則直接将 Cache 的結果集傳回給用戶端。如果沒有,再進行後續操作,得到對應的結果集之後将該結果集緩存到 Query Cache 中,再傳回給用戶端。當任何一個表的資料發生任何變化之後,與該表相關的所有 Query Cache 全部會失效,是以 Query Cache 對變更比較頻繁的表并不是非常适用,但對那些變更較少的表是非常合适的,可以極大程度的提高查詢效率,如那些靜态資源表,配置表等等。為了盡可能高效的利用 Query Cache,MySQL 針對 Query Cache 設計了多個 query_cache_type 值和兩個 Query Hint:SQL_CACHE 和 SQL_NO_CACHE。當 query_cache_type 設定為0(或者 OFF)的時候不使用 Query Cache,當設定為1(或者 ON)的時候,當且僅當 Query 中使用了 SQL_NO_CACHE 的時候 MySQL 會忽略 Query Cache,當 query_cache_type 設定為2(或者DEMAND)的時候,當且僅當Query 中使用了 SQL_CACHE 提示之後,MySQL 才會針對該 Query 使用 Query Cache。可以通過 query_cache_size 來設定可以使用的最大記憶體空間。

連接配接線程緩存(Thread Cache):連接配接線程是 MySQL 為了提高建立連接配接線程的效率,将部分空閑的連接配接線程保持在一個緩存區以備新進連接配接請求的時候使用,這尤其對那些使用短連接配接的應用程式來說可以極大的提高建立連接配接的效率。當我們通過 thread_cache_size 設定了連接配接線程緩存池可以緩存的連接配接線程的大小之後,可以通過(Connections - Threads_created) / Connections * 100% 計算出連接配接線程緩存的命中率。注意,這裡設定的是可以緩存的連接配接線程的數目,而不是記憶體空間的大小。

表緩存(Table Cache):表緩存區主要用來緩存表檔案的檔案句柄資訊,在 MySQL5.1.3之前的版本通過 table_cache 參數設定,但從MySQL5.1.3開始改為 table_open_cache 來設定其大小。當我們的用戶端程式送出 Query 給 MySQL 的時候,MySQL 需要對 Query 所涉及到的每一個表都取得一個表檔案句柄資訊,如果沒有 Table Cache,那麼 MySQL 就不得不頻繁的進行打開關閉檔案操作,無疑會對系統性能産生一定的影響,Table Cache 正是為了解決這一問題而産生的。在有了 Table Cache 之後,MySQL 每次需要擷取某個表檔案的句柄資訊的時候,首先會到 Table Cache 中查找是否存在空閑狀态的表檔案句柄。如果有,則取出直接使用,沒有的話就隻能進行打開檔案操作獲得檔案句柄資訊。在使用完之後,MySQL 會将該檔案句柄資訊再放回 Table Cache 池中,以供其他線程使用。注意,這裡設定的是可以緩存的表檔案句柄資訊的數目,而不是記憶體空間的大小。

表定義資訊緩存(Table definition Cache):表定義資訊緩存是從 MySQL5.1.3 版本才開始引入的一個新的緩存區,用來存放表定義資訊。當我們的 MySQL 中使用了較多的表的時候,此緩存無疑會提高對表定義資訊的通路效率。MySQL 提供了 table_definition_cache 參數給我們設定可以緩存的表的數量。在 MySQL5.1.25 之前的版本中,預設值為128,從 MySQL5.1.25 版本開始,則将預設值調整為 256 了,最大設定值為524288。注意,這裡設定的是可以緩存的表定義資訊的數目,而不是記憶體空間的大小。

二進制日志緩沖區(Binlog Buffer):二進制日志緩沖區主要用來緩存由于各種資料變更操做所産生的 Binary Log 資訊。為了提高系統的性能,MySQL 并不是每次都是将二進制日志直接寫入 Log File,而是先将資訊寫入 Binlog Buffer 中,當滿足某些特定的條件(如 sync_binlog參數設定)之後再一次寫入 Log File 中。我們可以通過 binlog_cache_size 來設定其可以使用的記憶體大小,同時通過 max_binlog_cache_size 限制其最大大小(當單個事務過大的時候 MySQL 會申請更多的記憶體)。當所需記憶體大于 max_binlog_cache_size 參數設定的時候,MySQL 會報錯:“Multi-statement transaction required more than ‘max_binlog_cache_size’ bytes of storage”。

MyISAM索引緩存(Key Buffer):MyISAM 索引緩存将 MyISAM 表的索引資訊緩存在記憶體中,以提高其通路性能。這個緩存可以說是影響 MyISAM 存儲引擎性能的最重要因素之一了,通過 key_buffere_size 設定可以使用的最大記憶體空間。

InnoDB 日志緩沖區(InnoDB Log Buffer):這是 InnoDB 存儲引擎的事務日志所使用的緩沖區。類似于 Binlog Buffer,InnoDB 在寫事務日志的時候,為了提高性能,也是先将資訊寫入 Innofb Log Buffer 中,當滿足 innodb_flush_log_trx_commit 參數所設定的相應條件(或者日志緩沖區寫滿)之後,才會将日志寫到檔案(或者同步到磁盤)中。可以通過 innodb_log_buffer_size 參數設定其可以使用的最大記憶體空間。

注:innodb_flush_log_trx_commit 參數對 InnoDB Log 的寫入性能有非常關鍵的影響。該參數可以設定為0,1,2,解釋如下:

0:log buffer中的資料将以每秒一次的頻率寫入到log file中,且同時會進行檔案系統到磁盤的同步操作,但是每個事務的commit并不會觸發任何log buffer 到log file的重新整理或者檔案系統到磁盤的重新整理操作。

1:在每次事務送出的時候将log buffer 中的資料都會寫入到log file,同時也會觸發檔案系統到磁盤的同步;

2:事務送出會觸發log buffer 到log file的重新整理,但并不會觸發磁盤檔案系統到磁盤的同步。此外,每秒會有一次檔案系統到磁盤同步操作。

此外,MySQL文檔中還提到,這幾種設定中的每秒同步一次的機制,可能并不會完全確定非常準确的每秒就一定會發生同步,還取決于程序排程的問題。實際上,InnoDB 能否真正滿足此參數所設定值代表的意義正常 Recovery 還是受到了不同 OS 下檔案系統以及磁盤本身的限制,可能有些時候在并沒有真正完成磁盤同步的情況下也會告訴 mysqld 已經完成了磁盤同步。

InnoDB 資料和索引緩存(InnoDB Buffer Pool):InnoDB Buffer Pool 對 InnoDB 存儲引擎的作用類似于 Key Buffer Cache 對 MyISAM 存儲引擎的影響,主要的不同在于 InnoDB Buffer Pool 不僅僅緩存索引資料,還會緩存表的資料,而且完全按照資料檔案中的資料快結構資訊來緩存,這一點和 Oracle SGA 中的 database buffer cache 非常類似。是以,InnoDB Buffer Pool 對 InnoDB 存儲引擎的性能影響之大就可想而知了。可以通過 (Innodb_buffer_pool_read_requests - Innodb_buffer_pool_reads) / Innodb_buffer_pool_read_requests * 100% 計算得到 InnoDB Buffer Pool 的命中率。

繼續閱讀