mysql 层_mysql三层体系
為什么有連接池和線程池?
每創(chuàng)建一個(gè)新的會話(或鏈接),mysql內(nèi)部創(chuàng)建一個(gè)新的用戶線程來提供服務(wù),當(dāng)連接被銷毀,線程也被銷毀.即一個(gè)連接有一個(gè)線程.這種創(chuàng)建鏈接和銷毀鏈接都會消耗cpu性能.為了降低這種消耗,有了連接池和線程池.
連接池(connection pool):
連接池:在客戶端部署。客戶端創(chuàng)建預(yù)先創(chuàng)建一定的連接,利用這些連接服務(wù)于客戶端所有的DB請求。如果某一個(gè)時(shí)刻,空閑的連接數(shù)小于DB的請求數(shù),則需要將請求排隊(duì),等待空閑連接處理。通過連接池可以復(fù)用連接,避免連接的頻繁創(chuàng)建和釋放,從而減少請求的平均響應(yīng)時(shí)間,并且在請求繁忙時(shí),通過請求排隊(duì),可以緩沖應(yīng)用對DB的沖擊。當(dāng)連接斷開,連接將回歸連接池。
線程池(thread pool):
線程池:在服務(wù)器端部署。通過創(chuàng)建一定數(shù)量的線程服務(wù)DB請求,有了線程池,當(dāng)有了新連接,可以直接從線程池里拿線程,斷開時(shí),也不銷毀線程,而是回放進(jìn)線程池。與一個(gè)線程服務(wù)一個(gè)連接的方式對比,線程池服務(wù)的最小單位是語句,即一個(gè)線程可以對應(yīng)多個(gè)活躍的連接。通過線程池,可以將server端的服務(wù)線程數(shù)控制在一定的范圍,減少了系統(tǒng)資源的競爭和線程上下切換帶來的消耗,同時(shí)也避免出現(xiàn)高連接數(shù)導(dǎo)致的高并發(fā)問題。
說明:在mysql社區(qū)版無線程池功能.?在第三方perconadb?和mysql商業(yè)版有其功能.
線程池帶來的問題1:調(diào)度死鎖(解決方法是添加優(yōu)先級隊(duì)列)
引入線程池解決了多線程高并發(fā)的問題,但也帶來一個(gè)隱患。假設(shè),A,B兩個(gè)事務(wù)被分配到不同的group中執(zhí)行,A事務(wù)已經(jīng)開始,并且持有鎖,但由于A所在的group比較繁忙,導(dǎo)致A執(zhí)行一條語句后,不能立即獲得調(diào)度執(zhí)行;而B事務(wù)依賴A事務(wù)釋放鎖資源,雖然B事務(wù)可以被調(diào)度起來,但由于無法獲得鎖資源,導(dǎo)致仍然需要等待,這就是所謂的調(diào)度死鎖。由于一個(gè)group會同時(shí)處理多個(gè)連接,但多個(gè)連接不是對等的。比如,有的連接是第一次發(fā)送請求;而有的連接對應(yīng)的事務(wù)已經(jīng)開啟,并且持有了部分鎖資源。為了減少鎖資源爭用,后者顯然應(yīng)該比前者優(yōu)先處理,以達(dá)到盡早釋放鎖資源的目的。因此在group里面,可以添加一個(gè)優(yōu)先級隊(duì)列,將已經(jīng)持有鎖的連接,或者已經(jīng)開啟的事務(wù)的連接發(fā)起的請求放入優(yōu)先隊(duì)列,工作線程首先從優(yōu)先隊(duì)列獲取任務(wù)執(zhí)行。
線程池帶來的問題2:大查詢處理(解決方法是設(shè)置thread_pool_oversubscribe)
某個(gè)group里面的連接都是大查詢,那么group里面的工作線程數(shù)很快就會達(dá)到thread_pool_oversubscribe參數(shù)設(shè)置值,對于后續(xù)的連接請求,則會響應(yīng)不及時(shí)(沒有更多的連接來處理),這時(shí)候group就發(fā)生了stall。通過前面分析知道,timer線程會定期檢查這種情況,并創(chuàng)建一個(gè)新的worker線程來處理請求。如果長查詢來源于業(yè)務(wù)請求,則此時(shí)所有g(shù)roup都面臨這種問題,此時(shí)主機(jī)可能會由于負(fù)載過大,導(dǎo)致hang住的情況。這種情況線程池本身無能為力,因?yàn)樵搭^可能是爛SQL并發(fā),或者SQL沒有走對執(zhí)行計(jì)劃導(dǎo)致,通過其他方法,比如SQL高低水位限流或者SQL過濾手段可以應(yīng)急處理。但是,還有另外一種情況,就是dump任務(wù)。很多下游依賴于數(shù)據(jù)庫的原始數(shù)據(jù),通常通過dump命令將數(shù)據(jù)拉到下游,而這種dump任務(wù)通常都是耗時(shí)比較長,所以也可以認(rèn)為是大查詢。如果dump任務(wù)集中在一個(gè)group內(nèi),并導(dǎo)致其他正常業(yè)務(wù)請求無法立即響應(yīng),這個(gè)是不能容忍的,因?yàn)榇藭r(shí)數(shù)據(jù)庫并沒有壓力,只是因?yàn)椴捎昧司€程池策略,才導(dǎo)致了請求響應(yīng)不及時(shí),為了解決這個(gè)問題,我們將group中處理dump任務(wù)的線程不計(jì)入thread_pool_oversubscribe累計(jì)值,避免上述問題。
連接池和線程池說明:
連接池主要用來管理客戶端的連接,避免重復(fù)的連接/斷開操作,是將空閑的連接緩存起來,可以復(fù)用。從而減少了連接mysql server/斷開mysql server的開銷與成本,從而提升性能。
但是mysql的連接池不能獲取mysql server的查詢處理能力以及當(dāng)前的負(fù)載情況。
線程池:線程池的操作是在mysql server端,并且設(shè)計(jì)就是用來管理當(dāng)前并發(fā)的連接和查詢。
thread pool到底能夠提升多少性能?
根據(jù)Oracle Mysql官方的性能測試:
在并發(fā)達(dá)到128個(gè)連接以后.沒有線程池的Mysql性能會迅速降低。使用線程池以后,性能不會出現(xiàn)波動(dòng),會一直保持在較好的狀態(tài)運(yùn)行。
在讀寫模式下,128個(gè)連接以后,有線程池的Mysql比沒有線程池的Mysql性能高出60倍。
在只讀模式下,512個(gè)連接以后,有線程池的Mysql比沒有線程池的Mysql性能高出18倍。
什么時(shí)候可以考慮使用thread_pool?
show global status like '%threads_running%';其值是mysql server當(dāng)前并發(fā)執(zhí)行語句的數(shù)量,如果這個(gè)值一直保持在40左右的區(qū)間,那么可以考慮使用thread pool。
如果你使用了innodb_thread_concurrency參數(shù)來控制并發(fā)的事物量,那么使用線程池將會獲得更好的效果。
如果你的工作是有很多短連接組成的,那么使用線程池是有益的。
第2層sql處理層(SQL Layer):主要有SQL Interface、Parser、Optimizer、Cache和Buffer
Sql層功能:
功能:解析器,授權(quán),優(yōu)化器,查詢執(zhí)行,查詢高速緩存,查詢?nèi)罩居涗?#xff0c;跨存儲引擎功能。
1.解析器:解析SQL語法,形成語法樹
2.授權(quán):SQL的權(quán)限驗(yàn)證 ?*.*對于指定的庫和表
3.優(yōu)化器:CBO(基于成本的優(yōu)化),根據(jù)統(tǒng)計(jì)信息--> SQL改寫?--->執(zhí)行計(jì)劃(即選哪種算法執(zhí)行)
sql層處理數(shù)據(jù)流程:
用戶傳入sql-----查詢緩存(命中緩存可直接返回結(jié)果)----解析器(生成sql解析樹)----預(yù)處理器(可能sql等價(jià)改寫)-----查詢優(yōu)化器(生成sql執(zhí)行計(jì)劃)----查詢執(zhí)行引擎----結(jié)果返回給用戶。
SQL接口:(SQL Interface)
功能:接受用戶的SQL命令,并且返回用戶需要查詢的結(jié)果。比如select from就是調(diào)用SQL Interface
解析器:(Parser)--生成sql解析樹
SQL命令傳遞到解析器的時(shí)候會被解析器驗(yàn)證和解析(進(jìn)行語義和語法的分析,分解成數(shù)據(jù)結(jié)構(gòu),如果在分解構(gòu)成中遇到錯(cuò)誤,那么就說明這個(gè)sql語句是不合理的?),生成sql解析樹。解析器是由Lex和YACC實(shí)現(xiàn)的,是一個(gè)很長的腳本。
查詢優(yōu)化器:(Optimizer) --生成執(zhí)行計(jì)劃
SQL語句在查詢之前會使用查詢優(yōu)化器對查詢進(jìn)行優(yōu)化,根據(jù)客戶端請求的?query?語句,和數(shù)據(jù)庫中的一些統(tǒng)計(jì)信息,在一系列算法的基礎(chǔ)上進(jìn)行分析,得出一個(gè)最優(yōu)的策略,告訴后面的程序如何取得這個(gè)?query?語句的結(jié)果,即執(zhí)行計(jì)劃。查詢優(yōu)化器使用選取-投影-聯(lián)接策略生成執(zhí)行計(jì)劃。
選取-投影-聯(lián)接:
用一個(gè)例子就可以理解:?select uid,name from user where gender = 1;
這個(gè)select?查詢先根據(jù)where?語句進(jìn)行選取,而不是先將表全部查詢出來以后再進(jìn)行g(shù)ender過濾。
這個(gè)select查詢先根據(jù)uid和name進(jìn)行屬性投影,而不是將屬性全部取出以后再進(jìn)行過濾。
將這兩個(gè)查詢條件聯(lián)接起來生成最終查詢結(jié)果。
查詢緩存功能(Cache和Buffer):(建議關(guān)閉)
當(dāng)執(zhí)行sql的時(shí)候,sql第一次被執(zhí)行,然后再次執(zhí)行的時(shí)候如果相同的sql,可以不進(jìn)行解析,直接返回結(jié)果,提高查詢效率.
關(guān)閉查詢緩存:query_cache_type = 0? ? query_cache_size = 0
局限性比較大,任何查詢結(jié)果有變更,都需要進(jìn)行更新,對于mysql性能影響比較嚴(yán)重,整個(gè)更新過程的鎖顆粒度的比較高,還持有全局鎖,效率很低.
建議:是否使用查詢緩存,不用.(在mysql8.0里沒了查詢緩存功能.)
問題:如何計(jì)算和提高查詢緩存命中率?
第3層儲存引擎層(StorEngine Layer):
儲存引擎層功能:
存儲引擎,也稱為表類型,真正的負(fù)責(zé)了MySQL中數(shù)據(jù)的存儲和提取,儲存引擎層由多種存儲引擎共同組成。它們負(fù)責(zé)存儲和獲取所有存儲在MySQL中的數(shù)據(jù)。就像Linux眾多的文件系統(tǒng) 一樣。每個(gè)存儲引擎都有自己的優(yōu)點(diǎn)和缺陷。服務(wù)器是通過存儲引擎API來與它們交互的。存儲引擎不能解析SQL,互相之間也不能通信。僅僅是簡單的響應(yīng)服務(wù)器 的請求。存儲引擎不會互相通信。不同的存儲引擎采用不同的技術(shù)(存儲機(jī)制、索引機(jī)制、鎖定機(jī)制)存儲數(shù)據(jù)。
MySQL的存儲引擎是插件式的,也就是說,用戶可以隨時(shí)切換MySQL的存儲引擎:針對表或針對庫都可(通過SQL語句命令)。MySQL集合了多種引擎:MyISAM、InnoDB、BDB、Merge、Memory等,默認(rèn)的是InnoDB。
儲存引擎層說明:
1、根據(jù)上層獲取數(shù)據(jù)的方法(執(zhí)行計(jì)劃),將數(shù)據(jù)提取出來。
2、重新再交給SQL層。
3、是MYSQL數(shù)據(jù)庫的核心,關(guān)系到數(shù)據(jù)庫性能。
4、存儲引擎是基于表的,而不是數(shù)據(jù)庫。
常見的MySQL的存儲引擎及特點(diǎn):
存儲引擎???????????????????特點(diǎn)
InnoDB? ? ? ? ??持事務(wù)安全。但是對比MyISAM引擎,寫的處效率會差些
MyISAM? ? ? ? ??支持事務(wù),插速度般innodb快一些
Memory? ? ? ? ??數(shù)據(jù)存儲于內(nèi)存之中
CSV? ? ? ? ? ??數(shù)據(jù)存儲為CSV件格式,不進(jìn)轉(zhuǎn)換
查看mysql儲存引擎:
mysql> show plugins;? ? ? ? ? ?---查看插件及其狀態(tài)
mysql> show engines;? ? ? ? ? ---查看目前支持的儲存引擎
InnoDB和MyISAM區(qū)別:
InnoDB? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? MyISAM
索引組織表? ? ? ? ? ? ? ? ? ? ? ? ? ? ??堆表
鎖? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??表鎖
物理結(jié)構(gòu)不同,數(shù)據(jù)索引在起(.frm)? ? ? ?物理結(jié)構(gòu)不同,數(shù)據(jù)索引分開(.MYD .MYI)
支持事務(wù)? ? ? ? ? ? ? ? ? ? ? ? ? ? ?不支持事務(wù)
支持外鍵? ? ? ? ? ? ? ? ? ? ? ? ? ? ?不支持外鍵
MVCC多版本控制
INNODB緩存索引和數(shù)據(jù)? ? ? ? ? ? ? ? ? ? ?MyISAM只緩存索引塊
說明:
通過對開關(guān)binlog先后的測試發(fā)現(xiàn),其實(shí)MySIAM的插性能要好于INNODB,這和MySIAM不支持事務(wù),鎖開銷也較有關(guān)。但是MySiam的表鎖讓該引擎不能在并發(fā)下工作,因?yàn)闀斐傻逆i沖突。在線業(yè)務(wù)OLTP業(yè)務(wù),強(qiáng)烈不建議使MySIAM的存儲引擎,并發(fā)效率很低。
創(chuàng)建表時(shí)指定儲存引擎:
create table test1
(
id int,
name varchar(11)
)engine=innodb;
create table test2
(
id int,
name varchar(11)
)engine=myisam ;
InnoDB的物理存儲結(jié)構(gòu):
test1.frm? ? ? ? #表結(jié)構(gòu)文件
test1.ibd? ?#表數(shù)據(jù)文件(存儲數(shù)據(jù)和索引)
MySIAM的物理存儲結(jié)構(gòu):
test2.frm? ? ? ? #表結(jié)構(gòu)文件
test2.MYD? ?#表數(shù)據(jù)文件
test2.MYI? ?#表索引文件
修改MyISAM表結(jié)構(gòu)到InnoDB表:
alter table test2 engine = innodb;
show create table test2\G;
Create Table: CREATE TABLE `test2` (
`id` int(11) DEFAULT NULL,
`name` varchar(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
注意:MySQL?的系統(tǒng)表,?user?等不能轉(zhuǎn)化為?InnoDB?格式,他們必須采用?MyISAM?格式!!
總結(jié)
以上是生活随笔為你收集整理的mysql 层_mysql三层体系的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 特斯拉华为问界齐降价,凭什么,为什么?
- 下一篇: mysql 严格模式查看,如何查找和禁用