表對象緩存: 是將某個表對象的字典信息(定義內(nèi)容)緩存到內(nèi)存中,用來提高對表的訪問效率。某個表被訪問過一次后,只要服務(wù)器沒有關(guān)閉且表定義沒有被修改的條件下,訪問該表,只需要從內(nèi)存中找到這個已經(jīng)緩存起來的對象做相應(yīng)操作即可。
創(chuàng)新互聯(lián)堅持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:網(wǎng)站設(shè)計制作、成都網(wǎng)站設(shè)計、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時代的澤庫網(wǎng)站設(shè)計、移動媒體設(shè)計的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!
用戶訪問表時,表對象在緩存時: 通過HASH算法找到TABLE_SHARE,然后每個線程構(gòu)造各自的實例化TABLE即可。
用戶訪問表時,當(dāng)表沒有被緩存的情況下: 第一需要打開表,首先需要從系統(tǒng)表中將這個表的所有信息都讀入內(nèi)存中,這些信息包括表名、庫名、所有列信息、列的默認(rèn)值、表的字符集、對應(yīng)的frm文件路徑、所屬存儲引擎、主鍵等,將這些信息構(gòu)造一個TABLE_SHARE結(jié)構(gòu)體,這個結(jié)構(gòu)體是表對象緩存的第一層,所有用戶共享訪問且為靜態(tài)不允許修改,它是緩存在table_def_cache(由參數(shù)table_definition_cache控制)中的。
而真正與用戶打交道的是TABLE_SHARE的衍生品,它對應(yīng)結(jié)構(gòu)體為TABLE,在被使用前需要將TABLE_SHARE結(jié)構(gòu)體實例化TABLE才能被使用,由每個線程構(gòu)造各自的實例化TABLE即可。(實例化的TABLE由table_open_cache及table_open_cache_instance控制)
注意1: DDL操作時會將所有instance鎖住,而DML操作時instance之間互不干擾。
(DDL statements still require a lock on the entire cache, but such statements are much less frequent than DML statements.)
注意2: 一個線程中如果打開表過多,超過一個instance限制的大小時,是不能跨instance緩存的
(instance大小:table_open_cache / table_open_cache_instances)
表緩存涉及其他參數(shù): 通過下面參數(shù)判斷table_open_cache參數(shù)設(shè)置是否合理
table_open_cache_hit:能夠從table open cache的free list中找到table則為命中,+1
table_open_cache_misses:與table_open_cache_hit相反,如果找不到則需要重新實例化則+1,通常發(fā)生在初始化第一次加載表或超過table_open_cache的設(shè)置被淘汰后需要重新實例化。
table_open_cache_overflow:table cache淘汰的數(shù)量,每次淘汰+1
opened_tables:已經(jīng)打開的表數(shù)。如果Opened_tables很大,那么table_open_cache的值可能太小了。
open_tables:總的instance (table cache)的總數(shù)
增加線程緩存大小
連接管理器線程處理服務(wù)器監(jiān)聽的網(wǎng)絡(luò)接口上的客戶端連接請求。連接管理器線程將每個客戶端連接與專用于它的線程關(guān)聯(lián),該線程負(fù)責(zé)處理該連接的身份驗證和所有請求處理。因此,線程和當(dāng)前連接的客戶端之間是一對一的比例。確保線程緩存足夠大以容納所有傳入請求是非常重要的。
MySQL提供了許多與連接線程相關(guān)的服務(wù)器變量:
線程緩存大小由thread_cache_size系統(tǒng)變量決定。默認(rèn)值為0(無緩存),這將導(dǎo)致為每個新連接設(shè)置一個線程,并在連接終止時需要處理該線程。如果希望服務(wù)器每秒接收數(shù)百個連接請求,那么應(yīng)該將thread_cache_size設(shè)置的足夠高,以便大多數(shù)新連接可以使用緩存線程??梢栽诜?wù)器啟動或運(yùn)行時設(shè)置max_connections的值。
還應(yīng)該監(jiān)視緩存中的線程數(shù)(Threads_cached)以及創(chuàng)建了多少個線程,因為無法從緩存中獲取線程(Threads_created)。關(guān)于后者,如果Threads_created繼續(xù)以每分鐘多于幾個線程的增加,請考慮增加thread_cache_size的值。
使用MySQL show status命令顯示MySQL的變量和狀態(tài)信息。這里有幾個例子:
Monyog線程緩存監(jiān)測
Monyog提供了一個監(jiān)控線程緩存的屏幕,名為“線程”。與MySQL線程相關(guān)的服務(wù)器變量映射到以下Monyog指標(biāo):
Monyog線程屏幕還包括“線程緩存命中率”指標(biāo)。這是一個提示線程緩存命中率的指標(biāo)。如果值較低,則應(yīng)該考慮增加線程緩存。在狀態(tài)欄以百分比形式顯示該值;它的值越接近100%越好。
如果這些指標(biāo)的值等于或超過指定值,則可以將每一個指標(biāo)配置為發(fā)出警告和/或嚴(yán)重警報
我們都知道 MySQL 的 Table Cache 是表定義的緩存,江湖上流傳著各種對這個參數(shù)的調(diào)優(yōu)方法。
table cache 的作用,就是節(jié)約讀取表結(jié)構(gòu)文件的開銷。對于table cache 是否命中,其實table cache 是針對于線程的,每個線程有自己的緩存,只緩存本線程的表結(jié)構(gòu)定義。不過我們發(fā)現(xiàn),strace 中沒有關(guān)于表結(jié)構(gòu)文件的 open 操作(只有 stat 操作,定位表結(jié)構(gòu)文件是否存在),也就是說 table cache 不命中,不一定需要讀取表結(jié)構(gòu)文件。這種感覺好像是:在不命中 table cache 時,命中了另外一個表結(jié)構(gòu)緩存。
運(yùn)維建議:
我們讀一下 MySQL 的文檔,關(guān)于 table_open_cache 的建議值公式:建議值 = 最大并發(fā)數(shù) * join 語句涉及的表的最大個數(shù)。
通過實驗我們?nèi)菀桌斫猓簍able_cache 是針對于線程的,所以需要最大并發(fā)數(shù)個緩存。另外,一個語句 join 涉及的表,需要同時在緩存中存在。所以最小的緩存大小,等于語句 join 涉及的表的最大個數(shù)。將這兩個數(shù)相乘,就得到了 MySQL 的建議值公式。