真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

mysql怎么執(zhí)行當(dāng)前讀 mysql如何執(zhí)行

mysql執(zhí)行快捷鍵

這要分情況,如果你的系統(tǒng)是windows快捷鍵是ctrl+回車鍵;如果系統(tǒng)是Mac os,也就是蘋果系統(tǒng),那么快捷鍵就是Command+回車鍵

創(chuàng)新互聯(lián)憑借專業(yè)的設(shè)計(jì)團(tuán)隊(duì)扎實(shí)的技術(shù)支持、優(yōu)質(zhì)高效的服務(wù)意識(shí)和豐厚的資源優(yōu)勢(shì),提供專業(yè)的網(wǎng)站策劃、網(wǎng)站制作、網(wǎng)站建設(shè)、網(wǎng)站優(yōu)化、軟件開發(fā)、網(wǎng)站改版等服務(wù),在成都10余年的網(wǎng)站建設(shè)設(shè)計(jì)經(jīng)驗(yàn),為成都上1000家中小型企業(yè)策劃設(shè)計(jì)了網(wǎng)站。

mysql是如何實(shí)現(xiàn)可重復(fù)讀的?

一個(gè)事務(wù)要更新一行,如果剛好有另外一個(gè)事務(wù)擁有這一行的行鎖,會(huì)被鎖住,進(jìn)入等待狀態(tài)。既然進(jìn)入了等待狀態(tài),那么等到這個(gè)事務(wù)自己獲取到行鎖要更新數(shù)據(jù)的時(shí)候,它讀到的值又是什么呢?

可重復(fù)讀隔離級(jí)別下,事務(wù)在啟動(dòng)的時(shí)候就“拍了個(gè)整個(gè)庫(kù)的快照”。如果一個(gè)庫(kù)有100G,那么我啟動(dòng)一個(gè)事務(wù),MySQL就要拷?100G的數(shù)據(jù)出來,這個(gè)過程得多慢啊。但是平時(shí)事務(wù)執(zhí)行起來卻是非??斓?。不是全部拷貝出來那是怎么實(shí)現(xiàn)的呢?

InnoDB里面每個(gè)事務(wù)有一個(gè)唯一的事務(wù)ID,叫作transaction id。它是在事務(wù)開始的時(shí)候向InnoDB的事務(wù)系統(tǒng)申請(qǐng)的,是按申請(qǐng)順序嚴(yán)格遞增的。

而每行數(shù)據(jù)也都是有多個(gè)版本的。每次事務(wù)更新數(shù)據(jù)的時(shí)候,都會(huì)生成一個(gè)新的數(shù)據(jù)版本,并且把transaction id賦值給這個(gè)數(shù) 據(jù)版本的事務(wù)ID,記為row trx_id。同時(shí),舊的數(shù)據(jù)版本要保留,并且在新的數(shù)據(jù)版本中,能夠有信息可以直接拿到它。

數(shù)據(jù)表中的一行記錄,其實(shí)可能有多個(gè)版本(row),每個(gè)版本有自己的row trx_id。

圖中虛線框里是同一行數(shù)據(jù)的4個(gè)版本,當(dāng)前最新版本是V4,k的值是22,它是被transaction id 為25的事務(wù)更新的,因此它的row trx_id也是25。語(yǔ)句更新會(huì)生成undo log(回滾日志),圖中的三個(gè)虛線箭頭,就是undo log。

按照可重復(fù)讀的定義,一個(gè)事務(wù)啟動(dòng)的時(shí)候,能夠看到所有已經(jīng)提交的事務(wù)結(jié)果。但是之后,這個(gè)事務(wù)執(zhí)行期間,其他事務(wù)的更新對(duì)它不可?。

一個(gè)事務(wù)只需要在啟動(dòng)的時(shí)候聲明說,“以我啟動(dòng)的時(shí)刻為準(zhǔn),如果一個(gè)數(shù)據(jù)版本是在我啟動(dòng)之前生成的,就認(rèn);如果是我啟動(dòng)以后才生成的,我就不認(rèn),我必須要找到它的上一個(gè)版本”。

如果“上一個(gè)版本”也不可?,那就得繼續(xù)往前找。如果是這個(gè)事務(wù)自己更新的數(shù)據(jù),它自己還是要認(rèn)的。

在實(shí)現(xiàn)上, InnoDB為每個(gè)事務(wù)構(gòu)造了一個(gè)數(shù)組,用來保存這個(gè)事務(wù)啟動(dòng)瞬間,當(dāng)前正在“活躍”的所有事務(wù)ID?!盎钴S”指的就 是,啟動(dòng)了但還沒提交。數(shù)組里面事務(wù)ID的最小值記為低水位,當(dāng)前系統(tǒng)里面已經(jīng)創(chuàng)建過的事務(wù)ID的最大值加1記為高水位。 這個(gè)視圖數(shù)組和高水位,就組成了當(dāng)前事務(wù)的一致性視圖(read-view)。而數(shù)據(jù)版本的可?性規(guī)則,就是基于數(shù)據(jù)的row trx_id和這個(gè)一致性視圖的對(duì)比結(jié)果得到的。

InnoDB利用了“所有數(shù)據(jù)都有多個(gè)版本”的這個(gè)特性,實(shí)現(xiàn)了“秒級(jí)創(chuàng)建快照”的能力。

回到我們最開始的表格,看看最后執(zhí)行的結(jié)果是多少。做如下假設(shè):

事務(wù)A的視圖數(shù)組就是[99,100], 事務(wù)B的視圖數(shù)組是[99,100,101], 事務(wù)C的視圖數(shù)組是[99,100,101,102]。為了簡(jiǎn)化分析,我先把其他干擾語(yǔ)句去掉,只畫出跟事務(wù)A查詢邏輯有關(guān)的操作:

第一個(gè)有效更新是事務(wù)C,把數(shù)據(jù)從(1,1)改成了(1,2)。這時(shí)候,這個(gè)數(shù)據(jù)的最新版本的row trx_id是102,而90這個(gè)版本已經(jīng)成為了歷史版本。 第二個(gè)有效更新是事務(wù)B,把數(shù)據(jù)從(1,2)改成了(1,3)。這時(shí)候,這個(gè)數(shù)據(jù)的最新版本(即row trx_id)是101,而102又成為了歷史版本。

事務(wù)B的update語(yǔ)句,如果按照一致性讀,好像結(jié)果不對(duì)哦?

事務(wù)B的視圖數(shù)組是先生成的,之后事務(wù)C才提交,不是應(yīng)該看不?(1,2)嗎,怎么能算出(1,3)來?

事務(wù)B在更新之前查詢一次數(shù)據(jù),這個(gè)查詢返回的k的值確實(shí)是1。 但是,當(dāng)它要去更新數(shù)據(jù)的時(shí)候,就不能再在歷史版本上更新了,否則事務(wù)C的更新就丟失了。因此,事務(wù)B此時(shí)的set k=k+1是在(1,2)的基礎(chǔ)上進(jìn)行的操作。 所以,這里就用到了這樣一條規(guī)則:更新數(shù)據(jù)都是先讀后寫的,而這個(gè)讀,只能讀當(dāng)前的值,稱為 “當(dāng)前讀” ( current read )。

在更新的時(shí)候,當(dāng)前讀拿到的數(shù)據(jù)是(1,2),更新后生成了新版本的數(shù)據(jù)(1,3),這個(gè)新版本的row trx_id是101。

所以,在執(zhí)行事務(wù)B查詢語(yǔ)句的時(shí)候,一看自己的版本號(hào)是101,最新數(shù)據(jù)的版本號(hào)也是101,是自己的更新,可以直接使用, 所以查詢得到的k的值是3。

select語(yǔ)句如果加鎖,也是當(dāng)前讀。

如果把事務(wù)A的查詢語(yǔ)句select * from t where id=1修改一下,加上lock in share mode 或 for update,也都可以讀到版本號(hào)是101的數(shù)據(jù),返回的k的值是3。下面這兩個(gè)select語(yǔ)句,就是分別加了讀鎖(S鎖,共享鎖)和寫鎖(X鎖,排他鎖)。

事務(wù)C’的不同是,更新后并沒有?上提交,在它提交前,事務(wù)B的更新語(yǔ)句先發(fā)起了。前面說過了,雖然事務(wù)C’還沒提交,但是(1,2)這個(gè)版本也已經(jīng)生成了,并且是當(dāng)前的最新版本。那么,事務(wù)B的更新語(yǔ)句會(huì)怎么處理呢?

兩階段鎖協(xié)議,事務(wù)C’沒提交,也就是說(1,2)這個(gè)版本上的寫鎖還沒釋放。 而事務(wù)B是當(dāng)前讀,必須要讀最新版本,而且必須加鎖,因此就被鎖住了,必須等到事務(wù)C’釋放這個(gè)鎖,才能繼續(xù)它的當(dāng)前讀。

回到最初的問題,事務(wù)的可重復(fù)讀的能力是怎么實(shí)現(xiàn)的?

正確理解MYSQL的幻讀

一、定義

1、幻讀MYSQL官方叫法是Phantom Rows,意為鬼影行或者幻影行,請(qǐng)看官方定義:

The so-called phantom problem occurs within a transaction when the same query produces different sets of rows at different times. For example, if a [ SELECT ] is executed twice, but returns a row the second time that was not returned the first time, the row is a “phantom” row.

翻譯一下:

所謂的幻影行問題是指,在同一個(gè)事務(wù)中,同樣的查詢語(yǔ)句執(zhí)行多次,得到了不同的行結(jié)果集。

例如,如果同一個(gè)SELECT語(yǔ)句執(zhí)行了兩次,第二次執(zhí)行的時(shí)候比第一次執(zhí)行時(shí)多出一行,則該行就是所謂的幻影行。

2、幻讀與不可重復(fù)讀的區(qū)別

從官方的定義來看,幻讀的定義側(cè)重于多條記錄,就是記錄條數(shù)的變化,而不可重復(fù)讀側(cè)重于單條記錄數(shù)據(jù)的變化,這樣區(qū)分原因在于解決幻讀需要范圍鎖,解決不可重復(fù)讀只需要單條記錄加鎖

二、InnoDB的REPEATABLE READ級(jí)別

InnoDB支持由SQL1992標(biāo)準(zhǔn)描述的所有四個(gè)事務(wù)隔離級(jí)別,默認(rèn)隔離級(jí)別是 REPEATABLE READ。

1、快照讀:

在RR模式下,第一次讀取會(huì)建立快照,后續(xù)查詢會(huì)讀取快照。

這意味著,如果在同一事務(wù)中發(fā)出多個(gè)普通[ SELECT ](非鎖定)語(yǔ)句,則這些 [ SELECT ]語(yǔ)句的結(jié)果也是一致的。

2、[locking reads](鎖定讀取,又叫當(dāng)前讀)

[ SELECT ]語(yǔ)句中使用 FOR UPDATE 或 FOR SHARE

3、行鎖

在RR模式下,使用當(dāng)前讀以及 [ UPDATE ]和 [ DELETE ]語(yǔ)句會(huì)對(duì)數(shù)據(jù)記錄加行鎖,鎖定范圍取決于該語(yǔ)句使用的是具有唯一搜索條件的唯一索引還是范圍類型搜索條件。

三、InnoDB的READ COMMITTED級(jí)別

1、在RC模式下,每次讀取都會(huì)刷新快照,因此不能保證可重復(fù)讀

2、在RC模式下,使用當(dāng)前讀以及 [ UPDATE ]和 [ DELETE ]語(yǔ)句會(huì)對(duì)數(shù)據(jù)記錄加行鎖,但是不會(huì)加范圍鎖,間隙鎖定僅用于外鍵約束檢查和重復(fù)鍵檢查。

3、由于禁用了間隙鎖定,因此可能會(huì)產(chǎn)生幻影行問題,因?yàn)槠渌麜?huì)話可以在間隙中插入新行。

4、 對(duì)于[ UPDATE ]或 [ DELETE ]語(yǔ)句, InnoDB 僅對(duì)其更新或刪除的行持有鎖。MySQL評(píng)估 WHERE 條件后,將釋放不匹配行的記錄鎖 。這大大降低了死鎖的可能性,但是仍然可以發(fā)生。

5、對(duì)于[ UPDATE ]語(yǔ)句,如果某行已被鎖定,則 InnoDB 執(zhí)行“半一致”讀取,將最新提交版本的數(shù)據(jù)返回給MySQL,以便MySQL可以確定該行是否符合 WHERE 條件。如果該行匹配(必須更新),則MySQL會(huì)再次讀取該行,這一次 InnoDB 會(huì)將其鎖定或等待獲取鎖。

6、注意

從MySQL 8.0.22開始,DML操作(增刪改,通過聯(lián)接列表或子查詢)從MySQL授權(quán)表中讀取數(shù)據(jù),但不對(duì)其進(jìn)行修改,無論隔離級(jí)別如何,都不會(huì)在MySQL授權(quán)表上獲得讀取鎖。

有關(guān)更多信息,請(qǐng)參見 Grant Table Concurrency 。

四、樂觀鎖與悲觀鎖

1、樂觀鎖

在UPDATE的WHERE子句中加入版本信息來確定修改是否生效

使用樂觀鎖時(shí)仍然需要非常謹(jǐn)慎,因?yàn)镽R是可重復(fù)讀的,在UPDATE之前讀取版本號(hào),應(yīng)該使用[當(dāng)前讀],不能使用[快照讀]

2、悲觀鎖

在UPDATE執(zhí)行前,SELECT后面加上FOR UPDATE來給記錄加鎖,保證記錄在UPDATE前不被修改。SELECT ... FOR UPDATE是加上了X鎖,也可以通過SELECT ... LOCK IN SHARE MODE加上S鎖,來防止其他事務(wù)對(duì)該行的修改。

3、無論是樂觀鎖還是悲觀鎖,使用的思想都是一致的,那就是當(dāng)前讀。樂觀鎖利用當(dāng)前讀判斷是否是最新版本,悲觀鎖利用當(dāng)前讀鎖定行。

五、總結(jié)

1、RC級(jí)別沒有范圍鎖一定會(huì)導(dǎo)致不可重復(fù)讀和幻影行

2、RR級(jí)別安全性更高,實(shí)現(xiàn)可重復(fù)讀的方式為快照,如果需要最新數(shù)據(jù)可以選擇[當(dāng)前讀],因此RR級(jí)別是首選

3、不論RR還是RC級(jí)別,增、刪、改的操作都會(huì)進(jìn)行一次[當(dāng)前讀]操作,以此獲取最新版本的數(shù)據(jù),并檢測(cè)是否有重復(fù)的索引。

4、RR級(jí)別下,當(dāng)前事務(wù)如果未發(fā)生更新操作(增刪改),快照版本會(huì)保持不變,多次查詢讀取的快照是同一個(gè)

5、RR級(jí)別下,當(dāng)前事務(wù)如果發(fā)生更新(增刪改),會(huì)刷新快照,會(huì)導(dǎo)致不可重復(fù)讀和幻影行

6、RR級(jí)別下,使用當(dāng)前讀,會(huì)刷新快照,會(huì)導(dǎo)致不可重復(fù)讀和幻影行

7、RR級(jí)別下,可以通過提交當(dāng)前事務(wù)并在此之后發(fā)出新查詢來為查詢獲取更新的快照。

8、RR級(jí)別可以部分解決不可重復(fù)讀和幻讀問題

9、其實(shí)問題的關(guān)鍵是你的業(yè)務(wù)邏輯需要可重復(fù)讀還是最新數(shù)據(jù)

mysql原理(十) 當(dāng)前讀與快照讀

首先我們做一個(gè)模擬,執(zhí)行以下的sql,其中有如下圖數(shù)據(jù):

我把執(zhí)行結(jié)果按照表格如下展示:

分析:

在會(huì)話1當(dāng)中,只有當(dāng)會(huì)話1的事務(wù)提交后,才能查到最終會(huì)話2更改的數(shù)據(jù)。

在會(huì)話2當(dāng)中,開啟事務(wù)后更新數(shù)據(jù),之后查詢發(fā)現(xiàn)數(shù)據(jù)變成了17。

針對(duì)上面的現(xiàn)象我們進(jìn)行個(gè)原理分析:

實(shí)際上產(chǎn)生上述顯現(xiàn)是因?yàn)镮nnoDB采用的MVCC(多版本并發(fā)控制),其中針對(duì)每條數(shù)據(jù)會(huì)有它自己的事務(wù)id,以及一個(gè)最大事務(wù)id。針對(duì)事務(wù)中數(shù)據(jù)每次修改,會(huì)產(chǎn)生不同的版本。

1)假設(shè)開始id = 2的數(shù)據(jù),其事務(wù)txid = 1000;

2)當(dāng)會(huì)話1開始,此時(shí)txid變成了1001,而會(huì)話2開啟,txid又變成了1002,同理會(huì)話3會(huì)變成1003,此時(shí)都生成了不同版本的快照。

3)會(huì)話1在事務(wù)當(dāng)中去讀取時(shí)候,采用了快照讀的方式,即拿到一個(gè)1001的事務(wù)id,此時(shí)只會(huì)讀取小于等于自己版本的數(shù)據(jù),所以在事務(wù)中最終只能拿到值為17的數(shù)據(jù)。

4)會(huì)話2在更新數(shù)據(jù)的時(shí)候,采用的當(dāng)前讀的方式,即對(duì)數(shù)據(jù)增加X鎖,獲取最新的事務(wù)id,讀取最新的版本數(shù)據(jù)。所以在更新之前,就讀取到了age的年齡是16,之后在進(jìn)行+1,得到17.

總結(jié)一下:

快照讀 解決了幻讀的問題,即多次讀取數(shù)據(jù)不一致的問題。

update、insert、delete都會(huì)執(zhí)行 當(dāng)前讀 ,防止并發(fā)更新數(shù)據(jù)導(dǎo)致數(shù)據(jù)錯(cuò)誤,此過程或添加X鎖。

MySQL中如何執(zhí)行SQL語(yǔ)句?

wow單機(jī)版一般還需要你安裝MySQL的管理工具的,例如navicat之類,里面就有時(shí)間查看器啊之類的東西了,用那個(gè)就可以執(zhí)行了。還是去弄一個(gè)一鍵的安裝版吧。那個(gè)SQL腳本太多了,一個(gè)個(gè)打你要整死的。

好了分給我吧。

mysql可重復(fù)讀的幻讀解決方案

首先需要明確的就是“幻讀”概念: 隔離級(jí)別是可重復(fù)讀,在一個(gè)事務(wù)中前后兩次查詢,查到了其他事務(wù)insert進(jìn)來的數(shù)據(jù)。

強(qiáng)調(diào)的是讀取到了其他事務(wù)插入進(jìn)來的數(shù)據(jù)。

下面來論證一下可重復(fù)讀下幻讀的解決方案

先明確一下,for update語(yǔ)法就是當(dāng)前讀,也就是查詢當(dāng)前已經(jīng)提交的數(shù)據(jù),并且是帶悲觀鎖的。沒有for update就是快照讀,也就是根據(jù)readView讀取的undolog中的數(shù)據(jù)。

如果按照以上猜想,那么整個(gè)執(zhí)行結(jié)果就違背了 可重復(fù)讀 的隔離級(jí)別了。

那么我們?cè)偌僭O(shè)select * from TABLE where d = 5 for update;這條語(yǔ)句鎖定的是所有被掃描到的數(shù)據(jù)。

這是因?yàn)門2階段的update會(huì)被阻塞住,畢竟所有被掃描到的記錄都被鎖定了。

按照上述推理過程,很顯然,即使鎖定所有掃描到的數(shù)據(jù)行,也依然存在幻讀的情況。違背了 可重復(fù)讀 的隔離級(jí)別。

針對(duì)這個(gè)情況,我們要解決幻讀的問題,那么就要求針對(duì)所有被掃描的記錄行以及還不存在的d=5的記錄行都給鎖住。

至此,當(dāng)前查詢結(jié)果完全滿足 可重復(fù)讀 的隔離級(jí)別。

通過以上推論,我們可以總結(jié)一下,在可重復(fù)讀的隔離級(jí)別下,解決幻讀除了需要鎖定所有掃描到的記錄行外,還需要鎖定行之間的間隙,也就是通過間隙鎖來解決幻讀的問題。


網(wǎng)頁(yè)名稱:mysql怎么執(zhí)行當(dāng)前讀 mysql如何執(zhí)行
轉(zhuǎn)載來源:http://weahome.cn/article/dooegps.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部