日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長(zhǎng)提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

MySQL是主流的開源關(guān)系型數(shù)據(jù)庫(kù),提供高性能的數(shù)據(jù)存儲(chǔ)服務(wù)。我們?cè)谧龊蠖碎_發(fā)時(shí),性能瓶頸往往不是應(yīng)用本身,而是數(shù)據(jù)庫(kù)層面。所以掌握Mysql的一些底層原理有助于我們更好地理解Mysql,對(duì)Mysql進(jìn)行性能調(diào)優(yōu),從而開發(fā)高性能的后端服務(wù)。

Mysql的邏輯架構(gòu)

Mysql的邏輯架構(gòu)如下圖:

資深程序員經(jīng)典總結(jié):Mysql的并發(fā)控制原理

 

最上層是處理客戶端過來的連接的。主要做連接處理、授權(quán)認(rèn)證、安全等。Mysql在這一層維護(hù)了一個(gè)線程池,用于處理來自客戶端的連接。Mysql可以使用用戶名密碼認(rèn)證,也可以使用SSL基于X.509證書認(rèn)證。

第二層由三部分組成:查詢緩存、解析器、優(yōu)化器。解析器用來解析SQL語(yǔ)句,優(yōu)化器會(huì)對(duì)解析之后的語(yǔ)句進(jìn)行優(yōu)化。在解析查詢前,服務(wù)器會(huì)先檢查查詢緩存,如果能在其中找到對(duì)應(yīng)的查詢結(jié)果,則無需再進(jìn)行查詢解析、優(yōu)化等過程,直接返回查詢結(jié)果。存儲(chǔ)過程、觸發(fā)器、視圖等都在這一層實(shí)現(xiàn)。

第三層是存儲(chǔ)引擎,存儲(chǔ)引擎負(fù)責(zé)在MySQL中存儲(chǔ)數(shù)據(jù)、提取數(shù)據(jù)、開啟一個(gè)事務(wù)等等。存儲(chǔ)引擎通過API與上層進(jìn)行通信,這些API屏蔽了不同存儲(chǔ)引擎之間的差異,使得這些差異對(duì)上層查詢過程透明。存儲(chǔ)引擎不會(huì)去解析SQL。

資深程序員經(jīng)典總結(jié):Mysql的并發(fā)控制原理

 

Mysql最常用的存儲(chǔ)引擎是InnoDB

Mysql的并發(fā)控制

如果多個(gè)線程同時(shí)操作數(shù)據(jù),就有可能引發(fā)并發(fā)控制的問題。本文接下來將介紹Mysql是如何控制并發(fā)讀寫的。

讀寫鎖

如果多個(gè)線程都只是讀數(shù)據(jù),其實(shí)可以一起讀,不會(huì)互相影響,這個(gè)時(shí)候應(yīng)該使用“讀鎖”,也稱為共享鎖。獲取讀鎖的線程之間互相不會(huì)阻塞,可以同時(shí)讀取一個(gè)資源。

如果有一個(gè)線程需要寫數(shù)據(jù),則應(yīng)該使用“寫鎖”,也成為排它鎖。寫鎖會(huì)阻塞其它的寫鎖和讀鎖,直至寫操作完成。

鎖粒度

首先明確一個(gè)概念:在給定的資源上,需要加鎖的數(shù)據(jù)越少,系統(tǒng)能夠承載的并發(fā)量就越高。但加鎖也是需要消耗資源的,如果系統(tǒng)花費(fèi)大量的時(shí)間來管理鎖,而不是存取數(shù)據(jù),那么系統(tǒng)的性能可能會(huì)因此受影響。

所以一個(gè)好的“鎖策略”就是要在鎖的開銷和數(shù)據(jù)的安全性之間尋求平衡,Mysql支持多個(gè)存儲(chǔ)引擎的架構(gòu),每種存儲(chǔ)引擎都可以實(shí)現(xiàn)自己的鎖策略和鎖粒度。

資深程序員經(jīng)典總結(jié):Mysql的并發(fā)控制原理

 

表鎖和行鎖

表鎖顧名思義就是鎖住整張表。表鎖開銷比較小。對(duì)表加寫鎖后,其它用戶對(duì)這張表的所有讀寫操作都會(huì)被阻塞。在Mysql中,盡管存儲(chǔ)引擎可以提供自己的鎖,但Mysql有時(shí)候也會(huì)使用表鎖,比如 ALTER TABLE 之類的語(yǔ)句。

寫鎖比讀鎖有更高的優(yōu)先級(jí),因此一個(gè)寫鎖請(qǐng)求可能會(huì)被插入到讀鎖隊(duì)列的前面。

行級(jí)鎖即鎖住整行,可以最大程度地支持并發(fā)處理,但加解鎖的開銷也會(huì)比較大。行級(jí)鎖只在儲(chǔ)存引擎層實(shí)現(xiàn),所有的存儲(chǔ)引擎都以自己的方式實(shí)現(xiàn)了行級(jí)鎖。

MVCC

MVCC即“多版本并發(fā)控制”,可以認(rèn)為MVCC是行級(jí)鎖的一個(gè)變種,但是它在很多情況下避免了加鎖操作,因此開銷更低。

主流的關(guān)系型數(shù)據(jù)庫(kù)都實(shí)現(xiàn)了MVCC,但實(shí)現(xiàn)機(jī)制各有不同。實(shí)際上MVCC也沒有一個(gè)統(tǒng)一的標(biāo)準(zhǔn)。但大都實(shí)現(xiàn)了非阻塞的讀操作,寫操作也只是鎖定必要的行。

MVCC保證的是每個(gè)事務(wù)里面在執(zhí)行期間看到的數(shù)據(jù)都是一致的。但不同的事務(wù)由于開始的時(shí)間不同,所以可能對(duì)同一張表,同一時(shí)刻看到的數(shù)據(jù)是不一樣的。

在Mysql的InnoDB引擎,是通過給每行記錄后面保存兩個(gè)隱藏的列來實(shí)現(xiàn)的。一個(gè)是保存行的創(chuàng)建時(shí)間,另一個(gè)保存了行的過期時(shí)間(或刪除時(shí)間)。

資深程序員經(jīng)典總結(jié):Mysql的并發(fā)控制原理

 

實(shí)際上存儲(chǔ)的并不是實(shí)際的一個(gè)時(shí)間戳,而是“系統(tǒng)版本號(hào)”。

每次開啟一個(gè)事務(wù),系統(tǒng)版本號(hào)都會(huì)遞增。事務(wù)開始時(shí),系統(tǒng)版本號(hào)會(huì)作為事務(wù)的版本號(hào),用來和查詢到的行的版本號(hào)進(jìn)行比較。下面分別介紹常見的CRUD操作中版本號(hào)是怎么工作的:

INSERT

保存當(dāng)前系統(tǒng)版本號(hào)作為行版本號(hào)

DELETE

保存當(dāng)前的系統(tǒng)版本號(hào)到這行數(shù)據(jù)的“刪除版本”。

UPDATE

插入一行新紀(jì)錄,保存當(dāng)前系統(tǒng)版本號(hào)作為行版本號(hào),同時(shí)保存當(dāng)前系統(tǒng)版本號(hào)到原來的行的“刪除版本”。

SELECT

  • 只查找版本早于當(dāng)前事務(wù)版本的行。這樣可以保證事務(wù)讀取都的行,要么之前就存在,要么是這個(gè)事務(wù)本身自己插入或者修改的。
  • 行的“刪除版本”要么未定義,要么大于當(dāng)前事務(wù)版本號(hào)。這樣可以確保事務(wù)讀取到的行,在事務(wù)之前沒有被刪除。

MVCC只在REPEATABLE READ和READ COMMITTED兩個(gè)隔離級(jí)別下工作,其它兩個(gè)隔離級(jí)別不能工作。因?yàn)镽EAD UNCOMMITTED總是讀取最新的數(shù)據(jù)防,而不是符合當(dāng)前事務(wù)版本的數(shù)據(jù)行。而SERIALIZABLE則會(huì)對(duì)所有讀取的行都加鎖。

分享到:
標(biāo)簽:并發(fā) 控制 Mysql
用戶無頭像

網(wǎng)友整理

注冊(cè)時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫(kù),初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績(jī)?cè)u(píng)定2018-06-03

通用課目體育訓(xùn)練成績(jī)?cè)u(píng)定