本文屬于個(gè)人備忘錄,主要是極客時(shí)間《MySQL實(shí)戰(zhàn)45講》學(xué)習(xí)筆記。

          MySQL架構(gòu)



          MySQL 可以分為 Server 層和存儲(chǔ)引擎層兩部分。不同的存儲(chǔ)引擎共用一個(gè)Server層。

          <>

          Server層

          <>

          概述

          Server層包括

          * 連接器
          * 查詢緩存
          * 分析器
          * 優(yōu)化器
          * 執(zhí)行器
          * ...
          Server層功能

          * MySQL大多數(shù)核心服務(wù)功能
          * 所有的內(nèi)置函數(shù),如日期、時(shí)間、數(shù)學(xué)和加密函數(shù)等
          * 跨存儲(chǔ)引擎的功能,如存儲(chǔ)過程、觸發(fā)器、視圖等
          <>

          連接器

          <>

          連接器做什么?

          * 連接器負(fù)責(zé)跟客戶端建立連接、獲取權(quán)限、維持和管理連接。
          連接命令示例
          mysql -h$ip -P$port -u$user -p
          其中,mysql是客戶端工具,用來跟服務(wù)端建立連接。在完成經(jīng)典的 TCP 握手后,連接器就要開始認(rèn)證你的身份,這個(gè)時(shí)候用的就是你輸入的用戶名和密碼。

          * 如果用戶名或密碼不對(duì),會(huì)收到"Access denied for user"錯(cuò)誤,客戶端結(jié)束執(zhí)行
          *
          如果用戶名密碼認(rèn)證通過,連接器會(huì)到權(quán)限表里面查出你擁有的權(quán)限。之后,這個(gè)連接里面的權(quán)限判斷邏輯,都將依賴于此時(shí)讀到的權(quán)限。

          * 這就意味著,一個(gè)用戶成功建立連接后,即使你用管理員賬號(hào)對(duì)這個(gè)用戶的權(quán)限做了修改,也不會(huì)影響已經(jīng)存在連接的權(quán)限。
          * 權(quán)限修改完成后,只有再新建的連接才會(huì)使用新的權(quán)限設(shè)置。
          *
          連接完成后,如果沒有后續(xù)的動(dòng)作,這個(gè)連接就處于空閑狀態(tài),可以用show processlist命令看該鏈接狀態(tài)。如下。

          * 其中Command列顯示為“Sleep”的這一行,就表示現(xiàn)在系統(tǒng)里面有一個(gè)空閑連接。 mysql> show processlist;
          +----+----------+-----------------+---------+---------+--------+-----------+------------------+
          | Id | User | Host | db | Command | Time | State | Info |
          +----+----------+-----------------+---------+---------+--------+-----------+------------------+
          | 28 | testuser | localhost:60453 | db_test | Sleep | 8 | | NULL | | 29 |
          testuser | localhost:53231 | db_test | Query | 0 | starting | show processlist
          |
          +----+----------+-----------------+---------+---------+--------+-----------+------------------+
          25 rows in set (0.00 sec)
          客戶端如果太長時(shí)間沒動(dòng)靜,連接器會(huì)自動(dòng)斷開。這個(gè)時(shí)間是由參數(shù)wait_timeout控制的,默認(rèn)值是8小時(shí)。
          mysql> show variables like 'wait_timeout'; +---------------+-------+ |
          Variable_name | Value | +---------------+-------+ | wait_timeout | 28800 |
          +---------------+-------+ 1 row in set (0.01 sec) mysql>
          如果在連接被斷開之后,客戶端再次發(fā)送請求的話,會(huì)收到一個(gè)錯(cuò)誤:Lost connection to MySQL server during
          query。這時(shí)候如果要繼續(xù),就需要重連后再執(zhí)行請求。

          <>

          什么是長連接?

          長連接:指連接成功后,如果客戶端持續(xù)有請求,則一直使用同一個(gè)連接。

          建立連接的過程通常比較復(fù)雜,建議使用中要盡量減少建立連接的動(dòng)作,即盡量使用長連接。

          <>

          什么是短連接?

          短連接:指每次執(zhí)行完很少的幾次查詢就斷開連接,下次查詢再重新建立一個(gè)。

          <>

          長連接的影響

          影響

          * 全部使用長連接后,可能會(huì)發(fā)現(xiàn),有些時(shí)候MySQL占用內(nèi)存漲得特別快。
          * 如果長連接累積下來,可能導(dǎo)致內(nèi)存占用太大,被系統(tǒng)強(qiáng)行殺掉(OOM),看起來是MySQL異常重啟。
          原因

          * 是因?yàn)镸ySQL在執(zhí)行過程中臨時(shí)使用的內(nèi)存是管理在連接對(duì)象里面的。這些資源會(huì)在連接斷開的時(shí)候才釋放。
          解決辦法

          *
          定期斷開長連接。

          * 使用一段時(shí)間,或者程序里面判斷執(zhí)行過一個(gè)占用內(nèi)存的大查詢后斷開連接,之后查詢時(shí)再重連。
          *
          執(zhí)行mysql_reset_connection重新初始化連接資源

          * MySQL >= 5.7版本
          * 在每次執(zhí)行一個(gè)比較大的操作后,重新初始化鏈接資源
          * 這個(gè)過程不需要重連和重新鑒權(quán),但是會(huì)將連接恢復(fù)到剛剛創(chuàng)建完時(shí)的狀態(tài)
          <>

          查詢緩存

          連接建立完成后,就可以進(jìn)行查詢了。MySQL接到一個(gè)查詢請求后,會(huì)先查詢緩存。

          * 如果語句在緩存中,則其對(duì)應(yīng)的結(jié)果會(huì)被直接返回給客戶端,以提高查詢效率。

          * 如果語句不在緩存中,會(huì)繼續(xù)后面的執(zhí)行階段。執(zhí)行完成后,執(zhí)行結(jié)果會(huì)被存入查詢緩存中。
          但是大多數(shù)情況下不要使用查詢緩存。因?yàn)椴樵兙彺嫱状笥诶?br>
          查詢緩存的失效非常頻繁,只要有對(duì)一個(gè)表的更新,這個(gè)表上所有的查詢緩存都會(huì)被清空。

          *
          不使用緩存

          * 對(duì)于更新壓力大的數(shù)據(jù)庫來說,查詢緩存的命中率會(huì)非常低。
          *
          可使用緩存

          * 業(yè)務(wù)是一張靜態(tài)表,很長時(shí)間才會(huì)更新一次。
          * 比如,一個(gè)系統(tǒng)配置表,那這張表上的查詢才適合使用查詢緩存。
          可通過設(shè)置參數(shù)query_cache_type來設(shè)置要不要使用查詢緩存。

          *
          DEMAND

          * 默認(rèn)都不使用查詢緩存
          *
          SQL_CACHE

          * 顯式指定使用查詢緩存,如 mysql> select SQL_CACHE * from T where ID=10;
          通常情況下,該參數(shù)設(shè)置為OFF,即關(guān)閉查詢緩存即可。
          mysql> show variables like 'query_cache_type'; +------------------+-------+ |
          Variable_name | Value | +------------------+-------+ | query_cache_type | OFF |
          +------------------+-------+ 1 row in set (0.00 sec)
          注意

          * MySQL 8.0版本直接將查詢緩存的整塊功能刪掉了,即8.0開始徹底沒有這個(gè)功能了。
          <>

          分析器

          分析器做什么?

          *
          詞法分析

          * 識(shí)別SQL語句各個(gè)字符串是什么、代表什么
          *
          語法分析

          * 根據(jù)語法規(guī)則,判斷SQL語句是否滿足MySQL語法
          * 如果語句不對(duì),會(huì)報(bào)“You have an error in your SQL syntax”錯(cuò)誤 mysql> elect * from t
          where ID=1; ERROR 1064 (42000): You have an error in your SQL syntax; check the
          manual that corresponds to your MySQL server version for the right syntax to
          use near 'elect * from t where ID=1' at line 1
          一般語法錯(cuò)誤會(huì)提示第一個(gè)出現(xiàn)錯(cuò)誤的位置,需要關(guān)注緊接“use near”的內(nèi)容。

          <>

          優(yōu)化器

          優(yōu)化器做什么?

          * 在表里面有多個(gè)索引的時(shí)候,決定使用哪個(gè)索引
          * 或者在一個(gè)語句有多表關(guān)聯(lián)(join)的時(shí)候,決定各個(gè)表的連接順序
          比如執(zhí)行下面這樣的語句,這個(gè)語句是執(zhí)行兩個(gè)表的join:

          mysql> select * from t1 join t2 using(ID) where t1.c=10 and t2.d=20;
          兩種執(zhí)行方法

          * 先從表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í)行的效率會(huì)有不同,而優(yōu)化器的作用就是決定選擇使用哪一個(gè)方案。

          <>

          執(zhí)行器

          分析器:要做什么
          優(yōu)化器:怎么做

          執(zhí)行步驟

          *
          鑒權(quán)

          * 沒有:返回?zé)o權(quán)限錯(cuò)誤
          * 有:繼續(xù)
          *
          打開表執(zhí)行

          * 打開表的時(shí)候,執(zhí)行器就會(huì)根據(jù)表的引擎定義,去使用這個(gè)引擎提供的接口。
          有索引查詢

          * 第一次調(diào)用的是“取滿足條件的第一行”這個(gè)接口
          * 之后循環(huán)調(diào)用“滿足條件的下一行”這個(gè)接口
          無索引查詢


          *
          調(diào)用InnoDB引擎接口取這個(gè)表的第一行,判斷ID值是不是10

          * 如果不是則跳過
          * 如果是則將這行存在結(jié)果集中
          * 調(diào)用引擎接口取下一行,重復(fù)相同的判斷邏輯,直到取到這個(gè)表的最后一行
          * 執(zhí)行器將上述遍歷過程中所有滿足條件的行組成的記錄集作為結(jié)果集返回給客戶端
          掃描了多少行?

          * 數(shù)據(jù)庫慢查詢?nèi)罩局杏幸粋€(gè)rows_examined字段,表示這個(gè)語句執(zhí)行過程中掃描了多少行
          * 這個(gè)值就是在執(zhí)行器每次調(diào)用引擎獲取數(shù)據(jù)行的時(shí)候累加的

          <>

          存儲(chǔ)引擎層

          * 存儲(chǔ)引擎層負(fù)責(zé)數(shù)據(jù)的存儲(chǔ)和提取
          * 架構(gòu)模式是插件式的,支持InnoDB、MyISAM、Memory 等多個(gè)存儲(chǔ)引擎
          * 目前最常用的存儲(chǔ)引擎是InnoDB,它從MySQL 5.5.5 版本開始成為了默認(rèn)存儲(chǔ)引擎
          比如,執(zhí)行create table建表時(shí),

          * 如果不指定引擎類型,默認(rèn)使用的就是 InnoDB
          * 使用engine=memory 來指定內(nèi)存引擎創(chuàng)建表

          友情鏈接
          ioDraw流程圖
          API參考文檔
          OK工具箱
          云服務(wù)器優(yōu)惠
          阿里云優(yōu)惠券
          騰訊云優(yōu)惠券
          京東云優(yōu)惠券
          站點(diǎn)信息
          問題反饋
          郵箱:[email protected]
          QQ群:637538335
          關(guān)注微信

                五月天国产激情视频在线观看 | 手机av在线| 亚洲AV成人毛片无码一二三 | 日韩特黄特色大片免费视频 | aaaaaa在线观看免费高清 |