成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

MySQL客戶端代碼引發的思考

開發 開發工具
execSQL是一個非常重要的方法,所有SQL語句的最終都是交由這個代碼來實現的;這個方法被一個connectionMutex鎖(這個鎖其實就是Connection對象自己,Mysql客戶端通過使用了“反射”所以不能直接使用this)包裹著這就意味著——在同一時刻一個Mysql連接只能執行一條SQL語句。

一次偶然的機會debug代碼瞅了一眼Mysql客戶端的代碼(Java版本),最引發我興趣的是這一句:

execSQL是一個非常重要的方法,所有SQL語句的最終都是交由這個代碼來實現的;這個方法被一個connectionMutex鎖(這個鎖其實就是Connection對象自己,Mysql客戶端通過使用了“反射”所以不能直接使用this)包裹著這就意味著——在同一時刻一個Mysql連接只能執行一條SQL語句。

MySQL客戶端的“鎖”

帶著疑問我走讀了這段代碼,畫一幅圖

MysqlIO是負責網絡通訊的底層類,使用的是Java是BIO通訊屬于“標準”的TCP客戶端寫法。它內部有三個重要的成員變量

  • mysqlConnection是一個Socket類型
  • mysqlOutput是一個BufferedOutputStream類型
  • InputStream是一個InputStream類型(Mysql做了一點封裝理解成BufferedInputStream也沒什么問題)

這三個成員變量的初始化是在MySqlIO的構造函數完成的,當執行SQL語句的時相當于:

  • 鎖住Socket,此時只有當前連接可以使用這個Socket對象(實際的鎖范圍更大)
  • mysqlOutput寫入數據包,發送Command(內部稱客戶端->服務器的請求為Command)
  • mysqlInput讀取數據包,解析返回結果

如果有多條SQL語句遞交給一個連接因為Socket被“鎖”所以會變成串行執行。

這不是bug,是特性

帶著疑問我翻看了Mysql的通訊協議,客戶端->服務器的標準格式如下:

  • 3字節表示后面“payload”的長度(所以mysql單數據包***值是4M);
  • 1字節表示“sequence_id”;這個字段似乎沒有什么用途
  • ***一個是變長的“payload”(長度由***部分決定)

服務器端->客戶端(響應數據包)的標準格式是

 

  • 1字節表示“類型”
  • 根據不同的類型“payload”會有不同的變化,比如返回的錯誤信息、受影響的行數等

看到這里我明白原因了。

Mysql的數據包中沒有辦法區分出一個連接中“不同的數據包”。A、B兩條SQL語句,可以通過一個Socket發送到服務器端;服務器端也會返回兩個執行結果。問題是——客戶端如何區分出哪個是A的執行結果哪個是B的執行結果呢?

仔細觀察上面的數據包唯一的方式是sequence_id,A分配一個id,B分配一個;服務器端在返回的時候把相應的sequence_id帶回來表示這是某個SQL語句的執行結果。遺憾的是——sequence_id根本沒用到,服務器端不會返回sequence_id信息。(看Mysql的響應數據包)

正是因為這個原因導致了所有的Mysql客戶端Connection對象都不是線程安全的。如果想要同時執行多條SQL語句就只能構造多個Connection。

有意思的是MongoDB的協議格式幾乎和Mysql的一樣,messageLength,requestID,opCode;但是響應數據包“修正”了這個bug,messageLength,responseID,opCode。這就意味著mongodb的conneciton是不需要阻塞的而且根本不需要“線程池”。(根據我觀察connectionsPerHost似乎是沒有用到,難道這個是為了給大家“安全感”?——我們帶線程池,放心用吧)

更多思考

我想到了更多東西,HTTP 2.0的多路復用(Multiplexing)。在HTTP1.0中每個HTTP請求都是一個TCP請求,瀏覽器載入頁面的時候會大量加載css、js、圖片、html短時間內會發起大量的TCP請求。在HTTP2.0中同時向一臺主機發起css、js、圖片可以被承載在同一個TCP連接中。

AMQP中也有相似的設計,叫Channel;一個TCP連接可以被多個線程同時使用。比如用一個TCP連接可以同時實現“訂閱”和“發布”消息。

微軟RDP協議中也有相同的設計,區分圖片、聲音、鼠標、鍵盤操作(Citrix的ICA設計號稱的32個通道就是這個意思)。

SSH協議中有一個叫Channel Mechanism的東西,它也是為了實現“多路復用”的(這意味著提高了ansible的效率)。

技術就是這么奇妙,很多東西都是你“借鑒我”,我“借鑒你”。相同的問題相同的解決辦法,如果用心其實可以匯編成一本書,比如我們上面講的或許就可以叫——“多路復用的協議設計模式”吧。

【本文是51CTO專欄作者邢森的原創文章,轉載請聯系作者本人獲取授權】

戳這里,看該作者更多好文

責任編輯:武曉燕 來源: 寫程序的康德
相關推薦

2022-08-01 08:04:58

MySQL客戶端字符

2014-08-11 16:35:35

KafkaJava客戶端

2021-09-22 15:46:29

虛擬桌面瘦客戶端胖客戶端

2010-12-30 12:13:03

Skype宕機Windows客戶端漏

2014-06-12 13:44:19

2010-04-21 12:57:33

RAC負載均衡配置

2010-03-18 16:49:43

Java Socket

2011-03-21 14:53:36

Nagios監控Linux

2011-04-06 14:24:20

Nagios監控Linux

2011-08-17 10:10:59

2010-06-02 10:27:56

MySQL客戶端工具

2020-11-17 08:53:07

MySQL數據庫技術

2010-03-18 17:30:46

Java Socket

2011-03-24 13:00:31

配置nagios客戶端

2010-12-21 11:03:15

獲取客戶端證書

2011-03-02 14:36:24

Filezilla客戶端

2011-10-26 13:17:05

2010-05-31 10:11:32

瘦客戶端

2010-07-22 12:24:31

Telnet客戶端

2011-03-25 12:50:29

nagios安裝
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产综合在线视频 | 欧美久久久电影 | 国产精品视频一区二区三区四区国 | 91在线精品播放 | 18成人在线观看 | 特级丰满少妇一级aaaa爱毛片 | 亚洲欧美日韩精品久久亚洲区 | 91色在线视频| 欧美夜夜 | 波多野结衣精品在线 | 精品视频一区二区三区在线观看 | 欧美久久不卡 | 久久高清精品 | 精品一二三区在线观看 | 欧美精品一区三区 | 久久久影院 | 国产精品视频一区二区三区不卡 | 日韩精品一区二区三区 | 91久久精品一区二区二区 | 在线免费视频一区 | 性欧美精品一区二区三区在线播放 | 久久亚洲国产 | 成人av资源在线 | 国产一区二区精品在线观看 | 日韩精品免费视频 | 日本精品久久久一区二区三区 | 日韩精品成人av | 国产一区在线免费观看 | 国产一区二区在线免费观看 | 国产精品国产三级国产aⅴ中文 | 日韩精品一区二区三区视频播放 | 国产91丝袜在线播放 | 日本中文字幕视频 | 色综合久久天天综合网 | 日韩视频在线免费观看 | 国产免费拔擦拔擦8x高清 | 亚洲一区二区在线播放 | 日韩一区不卡 | wwww.xxxx免费 | 亚洲一区三区在线观看 | 日韩在线精品 |