溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

數(shù)據(jù)庫的讀一致性分析

發(fā)布時(shí)間:2020-07-29 01:04:15 來源:網(wǎng)絡(luò) 閱讀:929 作者:zfz_linux_boy 欄目:數(shù)據(jù)庫

前言

提起數(shù)據(jù)庫的事務(wù),我們就會(huì)想到ACID特性:

A:Atomicity 原子性    事務(wù)中包含的各種操作,要么一起成功,要么全部失敗

C:Consistency 一致性  事務(wù)從一個(gè)一致性的狀態(tài)轉(zhuǎn)變成另一個(gè)一致性的狀態(tài) 

I:Isolation 隔離性   各個(gè)事務(wù)之間的可見程度

D:Durability 持久性  數(shù)據(jù)庫中的數(shù)據(jù)的改變應(yīng)該是可以持久存儲(chǔ)的

本篇博客將以MySQL為例分析數(shù)據(jù)庫的讀一致性。想分析清楚一致性,必先了解隔離級(jí)別。


數(shù)據(jù)庫的隔離級(jí)別

在SQL標(biāo)準(zhǔn)中是定義了幾種隔離級(jí)別的:


RU:Read Uncommitted(讀取未提交內(nèi)容)

RC:Read Committed(讀取提交內(nèi)容)

RR:Repeatable Read(可重讀)

Serializable(可串行化)


Serializable這種隔離級(jí)別最高,若幾個(gè)事務(wù)對(duì)同一份數(shù)據(jù)進(jìn)行操作(即便是查詢操作),它也針對(duì)每一個(gè)事務(wù)進(jìn)行排序,嚴(yán)格按照排序進(jìn)行事務(wù)的執(zhí)行,顯然解決了事務(wù)可能存在的沖突,但是會(huì)導(dǎo)致大量的超時(shí)以及鎖競(jìng)爭(zhēng),因此在實(shí)際中大多是不會(huì)采用此種隔離級(jí)別的。

Oracle默認(rèn)的隔離級(jí)別是:RC,并且Oracle只支持RC和Serializable這2種級(jí)別。RC,簡(jiǎn)單一句話,就是一個(gè)事務(wù)中只能看到另一個(gè)事務(wù)已經(jīng)提交的數(shù)據(jù)的改變。那么RC會(huì)帶來什么問題呢?在同一事務(wù)中,同一條SELECT語句可能會(huì)返回不一樣的結(jié)果,即會(huì)產(chǎn)生  不可重復(fù)讀。


MySQL默認(rèn)的隔離級(jí)別是:RR。在該隔離級(jí)別下,可以保證在同一事務(wù)中,獲取到的數(shù)據(jù)一致。這就是所謂的MySQL的讀一致性,它的實(shí)現(xiàn)基于MVCC,后文中會(huì)分析。


RU可以讓所有事務(wù)都讀取到其他事務(wù)未提交的數(shù)據(jù),會(huì)帶來 臟讀,同Serializable一樣,在實(shí)際中,應(yīng)用較少。



淺析MySQL MVCC原理

MVCC(MultiVersion Concurrency Control )多版本并發(fā)控制,可以簡(jiǎn)單的理解成為一個(gè)row lock的一個(gè)變種,只是在必要的時(shí)候加行鎖。MySQL InnoDB的MVCC簡(jiǎn)單來講是通過給表添加兩列隱藏列來是實(shí)現(xiàn)的。一列是insert/update的時(shí)間,另一列是delete的時(shí)間,當(dāng)然這里的時(shí)間并不是真正的時(shí)間,而是指SVN,即System Version Number,系統(tǒng)版本號(hào),就是一個(gè)數(shù)字。每次開啟一個(gè)事務(wù),那么SVN號(hào)遞增。



現(xiàn)在討論在REPEATABLE READ下的MVCC實(shí)現(xiàn):


SELECT


  • Innodb查找insert/update SVN小于等于當(dāng)前事務(wù)的SVN的行,如果是小于,說明行之前就已經(jīng)存在,如果是等于,說明這行是事務(wù)本身修改過的。

  • 行的刪除時(shí)間列要么為空(說明該行未被刪除)要么刪除時(shí)間列的SVN大于當(dāng)前事物的SVN(表示行是在事物開始之后被刪除的)。


只有記錄滿足以上兩條,才會(huì)被select語句返回!


這就是為何MYSQL在RR級(jí)別下,一個(gè)事務(wù)中是肯定讀取不到“之后建立的”別的事務(wù)提交的數(shù)據(jù),但是在本事務(wù)中更新的數(shù)據(jù),可以讀取出來的緣故!


INSERT


  • 插入之后以當(dāng)前事務(wù)的SVN號(hào)更新創(chuàng)建列


DELETE


  • 刪除之后,用當(dāng)前SVN更新刪除列


UPDATE


  • 更新創(chuàng)建列為當(dāng)前SVN,同時(shí)更新刪除列為update之前的創(chuàng)建列的SVN值


這樣設(shè)計(jì)的優(yōu)點(diǎn)是大部分的讀操作都不用加鎖了,而且是非阻塞的讀取操作,使數(shù)據(jù)庫操作簡(jiǎn)單,性能好,不足之處是增加了存儲(chǔ)開銷,需要額外的維護(hù)工作。


還是那句老話,用空間換取時(shí)間!




向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI