MySQL是典型的C/S架構(gòu)
(客戶(hù)端/服務(wù)器架構(gòu)),客戶(hù)端進(jìn)程向服務(wù)端進(jìn)程發(fā)送一段文本(MySQL指令),服務(wù)器進(jìn)程進(jìn)行語(yǔ)句處理然后返回執(zhí)行結(jié)果。
問(wèn)題來(lái)了。服務(wù)器進(jìn)程對(duì)客戶(hù)端發(fā)送的請(qǐng)求究竟做了什么處理呢?本文以查詢(xún)請(qǐng)求為例,講解MySQL服務(wù)器進(jìn)程的處理流程。
如下圖所示,服務(wù)器進(jìn)程在處理客戶(hù)端請(qǐng)求的時(shí)候,大致需要進(jìn)行3個(gè)步驟:
- 處理連接
- 解析與優(yōu)化
- 存儲(chǔ)引擎
接下來(lái)我們來(lái)詳細(xì)了解一下這3步具體都做了什么。
1. 處理連接
客戶(hù)端向服務(wù)器發(fā)送請(qǐng)求并最終收到響應(yīng),本質(zhì)上是一個(gè)進(jìn)程間通信的過(guò)程。
MySQL有專(zhuān)門(mén)用于處理連接的模塊——連接器。
1.1 客戶(hù)端和服務(wù)端的通信方式
1.1.1 TCP/IP協(xié)議
TCP/IP
協(xié)議是MySQL客戶(hù)端和服務(wù)器最常用的通信方式。
我們平時(shí)所說(shuō)的MySQL服務(wù)器默認(rèn)監(jiān)聽(tīng)的端口是3306
,這句話(huà)的前提是客戶(hù)端進(jìn)程和服務(wù)器進(jìn)程使用的是TCP/IP
協(xié)議進(jìn)行通信。
我們?cè)谑褂?code>mysql命令啟動(dòng)客戶(hù)端程序時(shí),只要在-h
參數(shù)后跟隨IP地址作為服務(wù)器進(jìn)程所在的主機(jī)地址,那么通訊方式便是TCP/IP
協(xié)議。
如果客戶(hù)端進(jìn)程和服務(wù)器進(jìn)程位于同一臺(tái)主機(jī),且要使用
TCP/IP
協(xié)議進(jìn)行通信,則IP地址需要指定為127.0.0.1,而不能使用localhost
1.1.2 UNIX域套接字
如果客戶(hù)端進(jìn)程和服務(wù)器進(jìn)程都位于類(lèi)UNIX操作系統(tǒng)(MacOS、Centos、Ubuntu等)的主機(jī)之上,并且在啟動(dòng)客戶(hù)端程序時(shí)沒(méi)有指定主機(jī)名,或者指定的主機(jī)名為localhost
,又或者指定了--protocol=socket
的啟動(dòng)參數(shù),那么客戶(hù)端進(jìn)程和服務(wù)器進(jìn)程就會(huì)使用UNIX域套接字
進(jìn)行進(jìn)程間通信。
MySQL服務(wù)器進(jìn)程默認(rèn)監(jiān)聽(tīng)的UNIX域套接字
文件為/temp/mysql.sock
,客戶(hù)端進(jìn)程啟動(dòng)時(shí)也默認(rèn)會(huì)連接到這個(gè)UNIX域套接字文件之上。
如果不明白
UNIX域套接字
到底是什么也沒(méi)關(guān)系,只要知道這是進(jìn)程之間的一種通訊方式就可以了,這里提及的主要目的是希望讀者知曉MySQL客戶(hù)端和進(jìn)程通訊方式不止于TCP/IP
協(xié)議
1.1.3 命名管道和共享內(nèi)存
如果你的MySQL是安裝在Windows主機(jī)之上,客戶(hù)端和服務(wù)器進(jìn)程可以使用命名管道和共享內(nèi)存的方式進(jìn)行通信。
不過(guò)使用這些通信方式需要在服務(wù)端和客戶(hù)端啟動(dòng)時(shí)添加一些啟動(dòng)參數(shù)。
- 使用命名管道進(jìn)行通信。需要在啟動(dòng)服務(wù)器時(shí)添加
--enable-named-pipe
參數(shù),同時(shí)在啟動(dòng)客戶(hù)端進(jìn)程時(shí)添加--pipe
或者--protocol=pipe
參數(shù) - 使用共享內(nèi)存進(jìn)行通信。需要在啟動(dòng)服務(wù)器時(shí)添加
--shared-memory
參數(shù),啟動(dòng)成功后,共享內(nèi)存便成為本地客戶(hù)端程序的默認(rèn)連接方式;也可以在啟動(dòng)客戶(hù)端進(jìn)程的命令中加上--protocol=memory
參數(shù)明確指定使用共享內(nèi)存進(jìn)行通信
如果不明白命名管道和共享內(nèi)存到底是什么沒(méi)關(guān)系,只要知道這是進(jìn)程之間的一種通訊方式就可以了,這里提及的主要目的是希望讀者知曉MySQL客戶(hù)端和進(jìn)程通訊方式不止于
TCP/IP
協(xié)議
1.2 權(quán)限驗(yàn)證
確認(rèn)通信方式并且成功建立連接之后,連接器就要開(kāi)始驗(yàn)證你的身份了,使用的信息就是你的用戶(hù)名和密碼。
- 如果用戶(hù)名或者密碼錯(cuò)誤,客戶(hù)端連接會(huì)立即斷開(kāi)
- 如果用戶(hù)名密碼認(rèn)證通過(guò),連接器會(huì)到權(quán)限表里面查出當(dāng)前登陸用戶(hù)擁有的權(quán)限。之后這個(gè)連接里面的權(quán)限判斷邏輯,都將依賴(lài)于此時(shí)讀到的權(quán)限。
1.3 查看MySQL連接
每當(dāng)一個(gè)客戶(hù)端連接到服務(wù)端時(shí),服務(wù)端進(jìn)程都會(huì)創(chuàng)建一個(gè)單獨(dú)的線(xiàn)程來(lái)處理當(dāng)前客戶(hù)端的交互操作。
那么如何查看MySQL當(dāng)前所有的連接?
mysql> show global status like 'Thread%';
+-------------------+-------+
| Variable_name | Value |
+-------------------+-------+
| Threads_cached | 0 |
| Threads_connected | 1 |
| Threads_created | 1 |
| Threads_running | 1 |
+-------------------+-------+
各字段含義如下表
字段 | 含義 |
---|---|
Threads_cached | 緩存中的線(xiàn)程連接數(shù) |
Threads_connected | 當(dāng)前打開(kāi)的連接數(shù) |
Threads_created | 為處理連接創(chuàng)建的線(xiàn)程數(shù) |
Threads_running | 非睡眠狀態(tài)的連接數(shù),通常指并發(fā)連接數(shù) |
建立連接之后,除非客戶(hù)端主動(dòng)斷開(kāi)連接,否則服務(wù)器會(huì)等待客戶(hù)端發(fā)送請(qǐng)求。但是線(xiàn)程的創(chuàng)建和保持是需要消耗服務(wù)器資源的,因此服務(wù)器會(huì)把長(zhǎng)時(shí)間不活動(dòng)的客戶(hù)端連接斷開(kāi)。
有2個(gè)參數(shù)控制這個(gè)自動(dòng)斷開(kāi)連接的行為,每個(gè)參數(shù)都默認(rèn)為28800秒,8小時(shí)。
-- 非交互式超時(shí)時(shí)間,如JDBC連接
mysql> show global variables like 'wait_timeout';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| wait_timeout | 28800 |
+---------------+-------+
-- 交互式超時(shí)時(shí)間,如數(shù)據(jù)庫(kù)查看工具Navicat等
mysql> show global variables like 'interactive_timeout';
+---------------------+-------+
| Variable_name | Value |
+---------------------+-------+
| interactive_timeout | 28800 |
+---------------------+-------+
既然連接消耗資源,那是不是MySQL的最大連接數(shù)也有默認(rèn)限制呢?沒(méi)錯(cuò)!默認(rèn)最大連接數(shù)為151。
mysql> show variables like 'max_connections';
+-----------------+-------+
| Variable_name | Value |
+-----------------+-------+
| max_connections | 151 |
+-----------------+-------+
題外話(huà):細(xì)心的讀者可能會(huì)發(fā)現(xiàn)MySQL某些查詢(xún)語(yǔ)句帶有
global
關(guān)鍵字,這個(gè)關(guān)鍵字有什么含義呢?
MySQL的系統(tǒng)變量有兩個(gè)作用范圍(不區(qū)分大小寫(xiě)),分別是
GLOBAL
(全局范圍):變量的設(shè)置影響服務(wù)器和所有客戶(hù)端SESSION
(會(huì)話(huà)范圍):變量的設(shè)置僅影響當(dāng)前連接(會(huì)話(huà))
但是并非每個(gè)參數(shù)都具有兩個(gè)作用范圍,比如允許同時(shí)連接到服務(wù)器的客戶(hù)端的數(shù)量max_connections
就只有全局級(jí)別。
當(dāng)沒(méi)有帶作用范圍關(guān)鍵字時(shí),默認(rèn)是SESSION
級(jí)別,包括查詢(xún)和修改操作。
比如修改一個(gè)參數(shù)之后,在當(dāng)前窗口生效了,但是在其他窗口卻沒(méi)有生效
show VARIABLES like 'autocommit';
set autocommit = on;
因此,如果只是臨時(shí)修改,請(qǐng)使用SESSION
級(jí)別,如果需要當(dāng)前設(shè)置在其他會(huì)話(huà)中生效,需要使用GLOBAL
關(guān)鍵字。
到此為止,服務(wù)器進(jìn)程已經(jīng)和客戶(hù)端進(jìn)程建立了連接,下一步將處理客戶(hù)端傳來(lái)的請(qǐng)求了。
-
服務(wù)器
+關(guān)注
關(guān)注
12文章
9295瀏覽量
85876 -
TCP
+關(guān)注
關(guān)注
8文章
1378瀏覽量
79199 -
MySQL
+關(guān)注
關(guān)注
1文章
829瀏覽量
26677 -
服務(wù)端
+關(guān)注
關(guān)注
0文章
66瀏覽量
7033
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論