Mysql高可用高性能存儲(chǔ)應(yīng)用系列2 - 深入理解鎖和Mvcc
概述
Mysql數(shù)據(jù)庫(kù)在處理并發(fā)中下了很多功夫,鎖是為了更好的保護(hù)數(shù)據(jù)的正確和可靠,Mvcc是維持一個(gè)數(shù)據(jù)的多個(gè)版本,使得讀寫(xiě)操作沒(méi)有沖突的解決并發(fā)的數(shù)據(jù)庫(kù)方案。
【資料圖】
鎖
當(dāng)數(shù)據(jù)訪問(wèn)多了,就會(huì)出現(xiàn)并發(fā)的問(wèn)題,Mysql鎖設(shè)計(jì)的初衷是處理并發(fā)問(wèn)題。作為多用戶共享的資源,當(dāng)出現(xiàn)并發(fā)訪問(wèn)的時(shí)候,數(shù)據(jù)庫(kù)需要合理地控制資源的訪問(wèn)規(guī)則。而鎖就是用來(lái)實(shí)現(xiàn)這些訪問(wèn)規(guī)則的重要數(shù)據(jù)結(jié)構(gòu)。
根據(jù)加鎖的范圍,MySQL 里面的鎖大致可以分成全局鎖、表級(jí)鎖和行鎖三類(lèi)。
全局鎖
全局鎖就是對(duì)整個(gè)數(shù)據(jù)庫(kù)實(shí)例加鎖,當(dāng)你需要讓整個(gè)庫(kù)處于只讀狀態(tài)的時(shí)候,可以使用這個(gè)命令,之后其他線程的以下語(yǔ)句會(huì)被阻塞:數(shù)據(jù)更新語(yǔ)句(數(shù)據(jù)的增刪改)、數(shù)據(jù)定義語(yǔ)句(包括建表、修改表結(jié)構(gòu)等)和更新類(lèi)事務(wù)的提交語(yǔ)句。
全局鎖命令:
//加鎖Flush tables with read lock;//釋放鎖命令unlock tables;
全局鎖的典型使用場(chǎng)景是,做全庫(kù)邏輯備份。也就是把整庫(kù)每個(gè)表都 select 出來(lái)存成文本。
mysql> UPDATE runoob_tbl SET runoob_title="學(xué)習(xí) C++" WHERE runoob_id=1;2013 - Lost connection to server during querymysql> INSERT INTO runoob_tbl (runoob_title, runoob_author, submission_date) VALUES ("學(xué)習(xí) PHP", "菜鳥(niǎo)教程", NOW());2013 - Lost connection to server during querymysql> SELECT * FROM runoob_tbl;+-----------+--------------+---------------+-----------------+| runoob_id | runoob_title | runoob_author | submission_date |+-----------+--------------+---------------+-----------------+| 1 | Go 學(xué)習(xí) | 菜鳥(niǎo)教程 | 2023-03-22 |+-----------+--------------+---------------+-----------------+1 row in set (0.01 sec)
釋放全局鎖后,所有的進(jìn)程得到釋放,需要注意的是如果是終端操作需要清空鏈接緩存,或者打開(kāi)新鏈接重試,mysql釋放鎖在當(dāng)前的鏈接中是不生效的。
mysql> use mysql2;Database changedmysql> INSERT INTO runoob_tbl (runoob_title, runoob_author, submission_date) VALUES ("學(xué)習(xí) PHP", "菜鳥(niǎo)教程", NOW());Query OK, 1 row affected (0.03 sec)
表級(jí)鎖
MySQL 里面表級(jí)別的鎖有兩種:一種是表鎖,一種是元數(shù)據(jù)鎖(meta data lock,MDL)。
表鎖是最常用的處理并發(fā)的方式。而對(duì)于 InnoDB 這種支持行鎖的引擎,一般不使用 lock tables 命令來(lái)控制并發(fā),畢竟鎖住整個(gè)表的影響面還是太大。
另一類(lèi)表級(jí)的鎖是 MDL(metadata lock)。
//加鎖lock tables 表名 ... read/write;//釋放鎖unlock tables;
表級(jí)鎖分讀鎖和寫(xiě)鎖,1)讀鎖,在進(jìn)行讀鎖時(shí),讀不會(huì)受到影響但是會(huì)阻塞其他進(jìn)程的insert、update操作。
mysql> lock tables runoob_tbl read;Query OK, 0 rows affected (0.05 sec) mysql> select * from runoob_tbl;+-----------+--------------+---------------+-----------------+| runoob_id | runoob_title | runoob_author | submission_date |+-----------+--------------+---------------+-----------------+| 1 | 學(xué)習(xí) C++ | 菜鳥(niǎo)教程 | 2023-03-22 || 2 | 學(xué)習(xí) PHP | 菜鳥(niǎo)教程 | 2023-03-22 || 3 | 學(xué)習(xí) PHP | 菜鳥(niǎo)教程 | 2023-03-22 |+-----------+--------------+---------------+-----------------+3 rows in set (0.02 sec)//寫(xiě)操作mysql> INSERT INTO runoob_tbl (runoob_title, runoob_author, submission_date) VALUES ("學(xué)習(xí) PHP", "菜鳥(niǎo)教程", NOW());2013 - Lost connection to server during querymysql> UPDATE runoob_tbl SET runoob_title="學(xué)習(xí) C++" WHERE runoob_id=1;2013 - Lost connection to server during query
2)寫(xiě)鎖,對(duì)指定表加了寫(xiě)鎖,會(huì)阻塞右側(cè)客戶端的讀和寫(xiě)。
mysql> lock tables runoob_tbl write;Query OK, 0 rows affected (0.02 sec)mysql> unlock tables;Query OK, 0 rows affected (0.03 sec)
行鎖
MySQL 的行鎖是在引擎層由各個(gè)引擎自己實(shí)現(xiàn)的,但并不是所有的引擎都支持行鎖,比如 MyISAM 引擎就不支持行鎖。
行鎖就是針對(duì)數(shù)據(jù)表中行記錄的鎖。這很好理解,比如事務(wù) A 更新了一行,而這時(shí)候事務(wù) B 也要更新同一行,則必須等事務(wù) A 的操作完成后才能進(jìn)行更新。
兩階段鎖協(xié)議:在 InnoDB 事務(wù)中,行鎖是在需要的時(shí)候才加上的,但并不是不需要了就立刻釋放,而是要等到事務(wù)結(jié)束時(shí)才釋放。這個(gè)就是兩階段鎖協(xié)議。
每個(gè)新來(lái)的被堵住的線程,都要判斷會(huì)不會(huì)由于自己的加入導(dǎo)致了死鎖,這是一個(gè)時(shí)間復(fù)雜度是 O(n) 的操作,要耗費(fèi)大量的 CPU 資源,應(yīng)該在邏輯上進(jìn)行優(yōu)化。
Mvcc
因?yàn)榧渔i會(huì)影響效率,MVCC全稱多版本并發(fā)控制(Multiversion concurrency control, MCC 或 MVCC),是數(shù)據(jù)庫(kù)管理系統(tǒng)常用的一種并發(fā)控制,理念是維持一個(gè)數(shù)據(jù)的多個(gè)版本,使得讀寫(xiě)操作沒(méi)有沖突的解決并發(fā)的數(shù)據(jù)庫(kù)方案。
當(dāng)前讀和快照讀
Mvcc 把事務(wù)的執(zhí)行語(yǔ)句分為當(dāng)前讀和快照讀。
當(dāng)前讀:總是讀取最新的版本的記錄??煺兆x:讀取歷史版本的記錄,歷史版本保存在undo Log(回滾日志)中,快照讀就是MySQL為我們實(shí)現(xiàn)MVCC理想模型的其中一個(gè)具體非阻塞讀功能。//select * from Table //快照讀//Insert Update Delete //當(dāng)前讀//Select ... lock in share mode //當(dāng)前讀//Select ... for update //當(dāng)前讀
事務(wù)的隔離解決有四種,可重復(fù)讀(RR)、讀已提交(RC)、讀未提交、序列化,查看全局隔離權(quán)限語(yǔ)句,舊版的myql使用tx開(kāi)頭,否則報(bào)錯(cuò)1193 - Unknown system variable "tx_isolation"
。
mysql> show variables like "transaction_isolation";+-----------------------+-----------------+| Variable_name | Value |+-----------------------+-----------------+| transaction_isolation | REPEATABLE-READ |+-----------------------+-----------------+1 row in set (0.07 sec)mysql> select @@transaction_isolation;+-------------------------+| @@transaction_isolation |+-------------------------+| REPEATABLE-READ |+-------------------------+
如果沒(méi)有設(shè)置隔離級(jí)別,可使用下面語(yǔ)句進(jìn)行設(shè)置。
mysql> SET GLOBAL TRANSACTION ISOLATION LEVEL REPEATABLE READ;Query OK, 0 rows affected (0.03 sec)
MVCC的實(shí)現(xiàn)原理
MVCC的目的就是多版本并發(fā)控制,在數(shù)據(jù)庫(kù)中的實(shí)現(xiàn),就是為了解決讀寫(xiě)沖突,它的實(shí)現(xiàn)原理主要是依賴記錄中的 3個(gè)隱式字段,undo日志 ,Read View 來(lái)實(shí)現(xiàn)的。
每行記錄除了我們自定義的字段外,還有數(shù)據(jù)庫(kù)隱式定義的DB_TRX_ID,DB_ROLL_PTR,DB_ROW_ID等字段。
DB_TRX_ID : 創(chuàng)建或最后修改記錄的事務(wù)IDDB_ROW_ID : 隱藏主鍵DB_ROLL_PTR :Undo Log里的回滾指針,7byte大小read-view:事務(wù)在快照時(shí)產(chǎn)生的讀視圖。
trx_list : 系統(tǒng)活躍的事務(wù)IDup_limit_id : 列表中事務(wù)最小的IDlow_limit_id : 系統(tǒng)尚未分配的下一個(gè)事務(wù)IDMvcc判斷的規(guī)則:
1.比較DB_TRX_ID和up_limit_id,如果小于,則當(dāng)前事務(wù)能看到DB_TRX_ID的記錄,如果大于和等于,則進(jìn)入下一個(gè)判斷
2.比較DB_TRX_ID和low_limit_id,如果大于等于則代表DB_TRX_ID的記錄在read-view生成后出現(xiàn)的,那么對(duì)于當(dāng)前事務(wù)不可見(jiàn)。如果小于,則進(jìn)入下一個(gè)判斷。
3.判斷DB_TRX_ID是否在活躍事務(wù)中,如果在,代表read-view生成時(shí),事務(wù)還在活躍狀態(tài),修改的數(shù)據(jù)當(dāng)前的事務(wù)是看不到的,如果不在,說(shuō)明事務(wù)在read-view之前就commit了,那么修改的結(jié)果就是可見(jiàn)的。
可重復(fù)讀(repeatable read):每次進(jìn)行快照讀時(shí)都生成讀視圖。
讀已提交(read committed):只有第一次時(shí)生成讀視圖,之后沒(méi)次都使用第一次時(shí)的讀視圖。
Mysql ( Innodb引擎 ) 保證數(shù)據(jù)的一致性
1.執(zhí)行更新語(yǔ)句update table set a= 1 where id = 2
2.將id=2
的行上的列值改為1
3.將修改更新到內(nèi)存中
4.記錄在第N個(gè)Page的地方做修改,并將這行記錄狀態(tài)為prepare
5.修改好了,可以提交事務(wù)了
6.寫(xiě)入binlog
7.commit,提交事務(wù)
8.將redo log里這個(gè)事務(wù)的相關(guān)記錄狀態(tài)置為commit狀態(tài)
這個(gè)數(shù)據(jù)提交過(guò)程,就是兩階段提交,在恢復(fù)數(shù)據(jù)時(shí),用binlog和redolog兩部分來(lái)比較做數(shù)據(jù)恢復(fù)就可以了。
事務(wù)
事務(wù)的特性:
原子性:UndoLog 隔離性:Mvcc持久性:RedoLog一致性:以上3個(gè)共同保證了一致性問(wèn)題
1.既然有了redolog,為什么還要有binlog呢?
redolog依賴于搜索引擎層,并不是每一個(gè)引擎都有redolog,binlog是屬于MysqlServer層。
標(biāo)簽:
- Mysql高可用高性能存儲(chǔ)應(yīng)用系列2 - 深入理解鎖和Mvcc
- 今日聚焦!普通話學(xué)習(xí)方法
- 什么是合同標(biāo)的物_什么是合同標(biāo)的
- 說(shuō)案|“名牌堅(jiān)果”流出百萬(wàn)件假冒禮盒,順藤摸瓜打擊制假售假產(chǎn)業(yè)鏈_今日熱聞
- 幼兒教師學(xué)期工作總結(jié)個(gè)人(幼兒教師學(xué)期工作總結(jié))_動(dòng)態(tài)焦點(diǎn)
- 智立方:公司目前暫未與Rokid發(fā)生業(yè)務(wù)關(guān)系 世界速看
- 植絨面料和其他面料有什么區(qū)別
- 宜家召回超11萬(wàn)件產(chǎn)品,原因是這個(gè)!引發(fā)網(wǎng)友吐槽→ 環(huán)球新視野
- 環(huán)球今日訊!LPL昨日TOP5:Leave暴風(fēng)羽刃逆羽展鋒芒
- 世界最資訊丨四川安岳:漫步在中國(guó)石刻之鄉(xiāng),盡覽千年時(shí)光,與佛對(duì)話!
- 頸霜排行榜10強(qiáng)推薦 頸霜什么牌子好
- 廣西多地出現(xiàn)強(qiáng)對(duì)流天氣 密集發(fā)布?xì)庀箢A(yù)警信息-世界熱訊
- 痔瘡出血的最佳治療方法_什么是痔瘡的微創(chuàng)治療方法
- 當(dāng)前看點(diǎn)!經(jīng)武快評(píng):立即行動(dòng)起來(lái),加強(qiáng)基礎(chǔ)研究
- 網(wǎng)傳江蘇灌云一中學(xué)要求學(xué)生向班主任私人賬戶交培養(yǎng)費(fèi) 官方調(diào)查-環(huán)球速看
- 旭輝集團(tuán)新增交付2358套新房 2023年至今已交付超1.2萬(wàn)戶-全球熱頭條
- wow懷舊服采藥路線
- ??冢航衲杲ㄔO(shè)用地?cái)M供應(yīng)865公頃,住宅用地占比約兩成
- 全球訊息:違規(guī)用個(gè)人微信提供交易建議!又有機(jī)構(gòu)被處罰
- 【環(huán)球報(bào)資訊】我軍首批殲-11B女飛行學(xué)員首次單飛
- 【環(huán)球播資訊】蘋(píng)果史上最強(qiáng)iPad明年見(jiàn)!屏幕升級(jí)為OLED 售價(jià)大漲
- 世界信息:農(nóng)發(fā)行四川內(nèi)江市分行:成功獲批3.79億元貸款助力威遠(yuǎn)鄉(xiāng)村冷鏈物流建設(shè)
- 【天天聚看點(diǎn)】貓耳面的做法
- 榆樹(shù)錢(qián)粥
- 闕店鄉(xiāng)團(tuán)委開(kāi)展人居環(huán)境整治活動(dòng)
- 哈爾濱:主動(dòng)做核酸檢出陽(yáng)性獎(jiǎng)勵(lì)1萬(wàn) 具體是什么情況-環(huán)球今日訊
- 新潔能:融資凈買(mǎi)入1646.73萬(wàn)元,融資余額4.1億元(03-23)_世界播資訊
- 吸聲降噪有絕招 ——正升環(huán)境科技股份有限公司堅(jiān)持創(chuàng)新發(fā)展紀(jì)實(shí)_速訊
- 【天天快播報(bào)】無(wú)錫電視臺(tái)
- 什么是陰極保護(hù)|全球速讀
- 韓國(guó)電信公布未來(lái)五年非基礎(chǔ)設(shè)施投資預(yù)算撥出12萬(wàn)億韓元
- 冰墩墩設(shè)計(jì)者給北京四中學(xué)生回信:祝??蓯?ài)奮進(jìn)的中國(guó)少
- 江蘇南通發(fā)現(xiàn)1人檢測(cè)結(jié)果呈陽(yáng)性 系外地返通人員
- 湖南郴州報(bào)告2例香港返湘人員新冠肺炎確診病例
- 廣西百色疫情社區(qū)傳播鏈基本阻斷
- 廣西新增1例本土確診病例 本輪本土疫情累計(jì)報(bào)告確診病例
- 葫蘆島市兩醫(yī)院不再收治非綏中地區(qū)患者 就醫(yī)患者閉環(huán)管理
- 蘇州14日新增本土確診1例,無(wú)癥狀感染者3例 詳情及軌跡公布
- 2021年北京空氣質(zhì)量創(chuàng)歷史最優(yōu) 首次全面達(dá)標(biāo)
- 化屋村火起來(lái)了
- 國(guó)家藥監(jiān)局:“小金盾”不是質(zhì)量認(rèn)證標(biāo)志
- 大霧!湖南18條高速通行受影響 157個(gè)收費(fèi)站臨時(shí)交通管制
- “0蔗糖”就是無(wú)糖、不渴不用喝水等謠言入選2021年度十大
- 廣西:監(jiān)督推動(dòng)鄉(xiāng)村振興政策項(xiàng)目資金落地見(jiàn)效
- 各國(guó)動(dòng)植物“精靈”慶冬奧 你能猜到她是誰(shuí)嗎?
- 二七廠蝶變:科技自立自強(qiáng)
- 從貨擔(dān)郎到日售數(shù)千斤 蘭州手藝人40余載“滾”元宵留年
- 大陸學(xué)生在臺(tái)度春節(jié):不一樣的年味與團(tuán)圓
- 廣東惠州全市全部封控管控解除
- 為人民健康提供可靠保障
- 青海藏族女孩小拉毛春節(jié)“重生記”
- 讓群眾遇事不煩辦事不難
- 黑河市疫情期間發(fā)放6500份元宵餃子“暖心包”
- 市場(chǎng)監(jiān)管總局:全國(guó)已建成869個(gè)進(jìn)口冷鏈?zhǔn)称芳斜O(jiān)管倉(cāng)