1.MYSQL(一)---基礎(chǔ)架構(gòu)(查詢)
2.MYSQL(二)---日志系統(tǒng)(更新)
3.MYSQL(三)---事務(wù)隔離
??學(xué)習(xí)MYSQL,不應(yīng)該只是從簡單的操作上去使用,學(xué)任何東西都需要從整體的架構(gòu)去理解它的整體運行得原理挂洛。鳥瞰全貌恋腕,高緯度的去理解問題。
??拿簡單的sql來說:
????????select *from table_name where id=1
??我們看到和使用的只是一條查詢語句伙单,然后返回得一個結(jié)果哈肖,就像程序運行得單線程一樣,請求->響應(yīng)布疼,但是這條語句在MYSQL內(nèi)部是如何執(zhí)行的呢,就需要我們對MYSQL正義去解析了游两。
??我們現(xiàn)在要做得就是把MYSQL進行拆解分析贱案,通過對它的整體架構(gòu),進行塊級分析宝踪,由這個拆解的過程中瘩燥,對MYSQL進行更深層次的理解。
MYSQL分為Server層和存儲引擎兩部分
Server層包括連接器溶耘、查詢緩存服鹅、分析器、優(yōu)化器留荔、等涵蓋了Mysql大多的核心服務(wù)功能澜倦,以及所有得內(nèi)置函數(shù)(日期、數(shù)據(jù)等)碘勉,所有跨存儲引擎的功能在這里進行實現(xiàn)桩卵,比如存儲過程、觸發(fā)器胜嗓、視圖等钩乍。
存儲引擎層負責(zé)數(shù)據(jù)的存儲和提取。它的架構(gòu)模式是插件形式的变过,支持InnoDB\MyISAM、Memory等多種存儲引擎〉荷保現(xiàn)在常用的是InnoDB(從5.5.5版本開始成為Mysql的默認(rèn)儲存引擎)崭孤。
????在使用mysql得過程中,創(chuàng)建表creat table建表的時候,如果不指定引擎類型罪针。默認(rèn)使用后的就是InnoDB泪酱。在創(chuàng)建得過程中是可以指定引擎類型,不同的引擎支持的存取方式是不同的墓阀,支持的功能也是不同的斯撮。從上圖中來看,不同的存儲引擎使用的server層是共用的勿锅。這就需要我們對server層的功能流程進行理解溢十。
連接器
在進行數(shù)據(jù)庫的使用的過程中,首先進行就是連接數(shù)據(jù)庫荒典,連接器就是實現(xiàn)這個功能的吞鸭。負責(zé)跟客戶端建立連接、獲取權(quán)限螃征、維持和管理連接透敌。連接命令:mysql -h$ip -P$port -u$user -p
,連接命令中的mysql是客戶端工具踢械,是用來和服務(wù)器建立連接魄藕。在完成TCP握手之后,連接器就開始認(rèn)證身份话瞧,開始輸入賬號和密碼寝姿。
- 如果用戶名或者密碼不對饵筑,就會收到報錯,然后客戶端程序執(zhí)行結(jié)束
- 如果用戶名架专、密碼正確玄帕,連接器會在權(quán)限表里面查看用戶的權(quán)限,之后的判斷邏輯裤纹,都會依賴這個權(quán)限鹰椒。
在用戶進行連接之后,權(quán)限已經(jīng)生成罩抗,如果此時用管理員賬戶對用戶的權(quán)限進行了修改灿椅,也不會影響已經(jīng)建立的鏈接的權(quán)限,只有重新進行連接后的權(quán)限改變操刀。
客戶端進行連接后婴洼,長時間沒有進行操作,連接器會自動將它斷開欢唾,這個時間是由參數(shù)wait_tiomeout控制的,默認(rèn)得時間是8小時斑芜。如果斷開之后祟霍,再次發(fā)送請求沸呐,就會收到錯誤:Lost connection to MySQL server during query。這時候需要繼續(xù)的話崭添,就要進行重連滥朱,然后再執(zhí)行請求力试。
數(shù)據(jù)庫長連接是指連接成功后,如果客戶端有持續(xù)的請求缰犁,則使用同一連接怖糊。短鏈接是使用幾次之后就斷開伍伤,下次查詢再重新建立一個。建立連接是一個復(fù)雜的過程扰魂,所以建議一般盡量減少建立連接的動作劝评,盡量使用長連接。
但是使用長連接后声畏,你就會發(fā)現(xiàn)姻成,有時候mysql占用的內(nèi)存就會漲的特別快愿棋,這是因為在長連接的過程中臨時使用的內(nèi)存是管理在連接對象里面的初斑。這些對象會在連接斷開的時候進行釋放膨处。所以長連接會累積下來,導(dǎo)致內(nèi)存過大鹃答,被系統(tǒng)進行殺掉突硝。這也是MySQL異常重啟的原因之一。
??長連接空閑斷開解決辦法:
????1.定期斷開連接锋八。使用一段時間后或者程序里執(zhí)行一個占用內(nèi)存大的查詢后护盈,進行斷開重連
????2.如果使用的是5.7以后的版本腐宋,可以在每次執(zhí)行一個比較大的操作后,通過執(zhí)行mysql_reset_connection來重新初始化連接資源欺嗤,這個過程不需要進行重新連接和權(quán)限認(rèn)證卫枝,但是連接狀態(tài)會恢復(fù)到剛剛創(chuàng)建得狀態(tài)。
查詢緩存
建立過連接之后腺占,就可以執(zhí)行select語句進行查詢了衰伯,執(zhí)行就會來到第二步邏輯积蔚,查詢緩存。
MySQL拿到一個查詢后,會先到查詢緩存看看怎顾,是不是之前執(zhí)行過這條語句读慎。之前執(zhí)行過的語句及其結(jié)果可能會以key-value形式換存在內(nèi)存中,如果查詢語句能夠在key中找到槐雾,那么就會將value直接返回給客戶端夭委。
如果不在,將會進行后續(xù)的查詢結(jié)果募强,執(zhí)行后株灸,執(zhí)行結(jié)果會放到緩存中,這樣如果直接命中緩存的話擎值,查詢的效率的確會很高慌烧。但是大多數(shù)情況下緩存的存在是弊大于利。
因為緩存的時效是經(jīng)常存在的鸠儿,只要對表有一個更新屹蚊,這個表的緩存就會清空进每,同時緩存時效汹粤。廢了很大勁存起來的緩存,還沒有用就失效了田晚,這不就很難受了嗎嘱兼。所以對于業(yè)務(wù)邏輯更新頻繁的表,緩存是累贅肉瓦。除非有一些靜態(tài)表遭京,比如系統(tǒng)配置什么的胃惜。
同時MySQL支持不使用緩存的配置泞莉,將query_cache_type設(shè)置成DEMAND,這樣在執(zhí)行sql得過程中船殉,默認(rèn)不使用緩存鲫趁,如果需要使用的話,SQL_CACHE配置 :select SQL_CACHE * from table_name where ID=1;
(8.0之后的MySQL查詢緩存的功能已經(jīng)刪除)
分析器
以上利虫,如果沒有命中緩存的話挨厚,現(xiàn)在就是要進行正規(guī)的查詢操作了。
首先MySQL需要知道你需要進行什么操作糠惫,就是這里對語句進行分析疫剃。分析器的'詞法分析',輸入的sql一堆字符串和空格硼讽,需要識別這里面的意思巢价。
??????select SQL_CACHE * from table_name where ID=1
首先執(zhí)行select是一個查詢語句,
"table_name "是表名,
"ID"是列ID
之后,就需要判斷輸入的語法是否正確壤躲,如果輸入的不對就會收到錯誤提示城菊,比如select輸入錯誤,selext得話就會報錯。
優(yōu)化器
經(jīng)過了上邊的分析器進行語句分析之后碉克,就需要讓它去選擇怎樣去執(zhí)行這條語句凌唬,決定使用哪個索引,使用多表關(guān)聯(lián)的是偶漏麦,決定各表的連接順序:select * from t1 join t2 using(ID) where t1.c=10 and t2.d=20;
- 既可以先從表t1里面取出c=10的記錄的ID值客税,再根據(jù)ID值關(guān)聯(lián)到表t2,再判斷t2里面d的值是否等于20唁奢。
- 也可以先從表t2里面取出d=20的記錄的ID值霎挟,再根據(jù)ID值關(guān)聯(lián)到t1,再判斷t1里面c的值是否等于10麻掸。
這兩種執(zhí)行方法的邏輯結(jié)果是一樣的酥夭,但是執(zhí)行的效率會有不同,而優(yōu)化器的作用就是決定選擇使用哪一個方案脊奋。
執(zhí)行器
MySQL通過分析器知道了你要做什么熬北,通過優(yōu)化器知道了該怎么做,于是就進入了執(zhí)行器階段诚隙,開始執(zhí)行語句讶隐。
開始執(zhí)行的時候,要先判斷一下你對這個表T有沒有執(zhí)行查詢的權(quán)限久又,如果沒有巫延,就會返回沒有權(quán)限的錯誤。
如果有權(quán)限地消,就打開表繼續(xù)執(zhí)行炉峰。打開表的時候,執(zhí)行器就會根據(jù)表的引擎定義脉执,去使用這個引擎提供的接口疼阔。
比如我們這個例子中的表T中,ID字段沒有索引半夷,那么執(zhí)行器的執(zhí)行流程是這樣的:
1.調(diào)用InnoDB引擎接口取這個表的第一行婆廊,判斷ID值是不是10,如果不是則跳過巫橄,如果是則將這行存在結(jié)果集中淘邻;
2.調(diào)用引擎接口取“下一行”,重復(fù)相同的判斷邏輯湘换,直到取到這個表的最后一行宾舅。
3.執(zhí)行器將上述遍歷過程中所有滿足條件的行組成的記錄集作為結(jié)果集返回給客戶端敬尺。
至此,這個語句就執(zhí)行完成了贴浙。
對于有索引的表砂吞,執(zhí)行的邏輯也差不多。第一次調(diào)用的是“取滿足條件的第一行”這個接口崎溃,之后循環(huán)取“滿足條件的下一行”這個接口蜻直,這些接口都是引擎中已經(jīng)定義好的。
你會在數(shù)據(jù)庫的慢查詢?nèi)罩局锌吹揭粋€rows_examined的字段袁串,表示這個語句執(zhí)行過程中掃描了多少行概而。這個值就是在執(zhí)行器每次調(diào)用引擎獲取數(shù)據(jù)行的時候累加的。