国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

MySQL 是如何實現 ACID 的?

數據庫 MySQL
本文主要探討MySQL InnoDB 引擎下ACID的實現原理,對于諸如什么是事務,隔離級別的含義等基礎知識不做過多闡述。

 

ACID

MySQL 作為一個關系型數據庫,以最常見的 InnoDB 引擎來說,是如何保證 ACID 的。

  •  (Atomicity)原子性: 事務是最小的執行單位,不允許分割。原子性確保動作要么全部完成,要么完全不起作用;
  •  (Consistency)一致性: 執行事務前后,數據保持一致;
  •  (Isolation)隔離性: 并發訪問數據庫時,一個事務不被其他事務所干擾。
  •  (Durability)持久性: 一個事務被提交之后。對數據庫中數據的改變是持久的,即使數據庫發生故障。

隔離性

先說說隔離性,首先是四種隔離級別。

說明
讀未提交 一個事務還沒提交時,它做的變更就能被別的事務看到
讀提交 一個事務提交之后,它做的變更才會被其他事務看到
可重復讀 一個事務中,對同一份數據的讀取結果總是相同的,無論是否有其他事務對這份數據進行操作,以及這個事務是否提交。InnoDB默認級別
串行化 事務串行化執行,每次讀都需要獲得表級共享鎖,讀寫相互都會阻塞,隔離級別最高,犧牲系統并發性。

不同的隔離級別是為了解決不同的問題。也就是臟讀、幻讀、不可重復讀。

隔離級別 臟讀 不可重復讀 幻讀
讀未提交 可以出現 可以出現 可以出現
讀提交 不允許出現 可以出現 可以出現
可重復讀 不允許出現 不允許出現 可以出現
序列化 不允許出現 不允許出現 不允許出現

那么不同的隔離級別,隔離性是如何實現的,為什么不同事物間能夠互不干擾?答案是 鎖 和 MVCC。

先來說說鎖, MySQL 有多少鎖。

粒度

從粒度上來說就是表鎖、頁鎖、行鎖。表鎖有意向共享鎖、意向排他鎖、自增鎖等。行鎖是在引擎層由各個引擎自己實現的。但并不是所有的引擎都支持行鎖,比如 MyISAM 引擎就不支持行鎖。

行鎖的種類

在 InnoDB 事務中,行鎖通過給索引上的索引項加鎖來實現。這意味著只有通過索引條件檢索數據,InnoDB才使用行級鎖,否則將使用表鎖。行級鎖定同樣分為兩種類型:共享鎖和排他鎖,以及加鎖前需要先獲得的意向共享鎖和意向排他鎖。

  •  共享鎖:讀鎖,允許其他事務再加S鎖,不允許其他事務再加X鎖,即其他事務只讀不可寫。select...lock in share mode 加鎖。
  •  排它鎖:寫鎖,不允許其他事務再加S鎖或者X鎖。insert、update、delete、for update加鎖。

行鎖是在需要的時候才加上的,但并不是不需要了就立刻釋放,而是要等到事務結束時才釋放。這個就是兩階段鎖協議。

行鎖的實現算法

Record Lock

單個行記錄上的鎖,總是會去鎖住索引記錄。

Gap Lock

間隙鎖,想一下幻讀的原因,其實就是行鎖只能鎖住行,但新插入記錄這個動作,要更新的是記錄之間的“間隙”。所以加入間隙鎖來解決幻讀。

Next-Key Lock

Gap Lock + Record Lock, 左開又閉。

鎖之于隔離性

大致介紹了下鎖,可以看到。有了鎖,當某事務正在寫數據時,其他事務獲取不到寫鎖,就無法寫數據,一定程度上保證了事務間的隔離。但前面說,加了寫鎖,為什么其他事務也能讀數據呢,不是獲取不到讀鎖嗎?

MVCC

前面說到,有了鎖,當前事務沒有寫鎖就不能修改數據,但還是能讀的,而且讀的時候,即使該行數據其他事務已修改且提交,還是可以重復讀到同樣的值。這就是MVCC,多版本的并發控制,Multi-Version Concurrency Control。

版本鏈

Innodb 中行記錄的存儲格式,有一些額外的字段:DATA_TRX_ID和DATA_ROLL_PTR。

  •  DATA_TRX_ID:數據行版本號。用來標識最近對本行記錄做修改的事務 id。
  •  DATA_ROLL_PTR:指向該行回滾段的指針。該行記錄上所有舊版本,在 undo log 中都通過鏈表的形式組織。

undo log : 記錄數據被修改之前的日志,后面會詳細說。

ReadView

在每一條 SQL 開始的時候被創建,有幾個重要屬性:

  •  trx_ids: 當前系統活躍(未提交)事務版本號集合。
  •  low_limit_id: 創建當前 read view 時“當前系統最大事務版本號+1”。
  •  up_limit_id: 創建當前read view 時“系統正處于活躍事務最小版本號”
  •  creator_trx_id: 創建當前read view的事務版本號;

 

開始查詢

現在開始查詢,一個 select 過來了,找到了一行數據。

  •  DATA_TRX_ID <up_limit_id :說明數據在當前事務之前就存在了,顯示。
  •  DATA_TRX_ID >= low_limit_id:

          說明該數據是在當前read view 創建后才產生的,數據不顯示。

  •   不顯示怎么辦,根據 DATA_ROLL_PTR 從 undo log 中找到歷史版本,找不到就空。

    up_limit_id <DATA_TRX_ID <low_limit_id :就要看隔離級別了。

RR 級別的幻讀

有了鎖和 MVCC , 事務的隔離性得到解決。這里要引申一下,默認的 RR 的級別,解決了幻讀嗎?幻讀通常針對的是 INSERT, 不可重復度則針對 UPDATE 。

 

事物 1 事物 2
begin begin
select * from dept  
- insert into dept(name) values("A")
- commit
update dept set name="B"  
commit  

 

我們期望是 

  1. id  name  
  2. 1   A  
  3. 2   B 

實際卻是 

  1. id  name  
  2. 1   B  
  3. 2   B 

其實在 MySQL 可重復讀的隔離級別中并不是完全解決了幻讀的問題,而是解決了讀數據情況下的幻讀問題。而對于修改的操作依舊存在幻讀問題,就是說 MVCC 對于幻讀的解決時不徹底的。另外,MySQL 系列面試題和答案全部整理好了,微信搜索Java技術棧,在后臺發送:面試,可以在線閱讀。

原子性

接著說說原子性。前文有提到 undo log ,回滾日志。隔離性的MVCC其實就是依靠它來實現的,原子性也是。實現原子性的關鍵,是當事務回滾時能夠撤銷所有已經成功執行的sql語句。

最新 Java 核心技術推薦:https://github.com/javastacks/javastack

當事務對數據庫進行修改時,InnoDB會生成對應的 undo log;如果事務執行失敗或調用了 rollback,導致事務需要回滾,便可以利用 undo log 中的信息將數據回滾到修改之前的樣子。undo log 屬于邏輯日志,它記錄的是sql執行相關的信息。當發生回滾時,InnoDB 會根據 undo log 的內容做與之前相反的工作:

  •  對于每個 insert,回滾時會執行 delete;
  •  對于每個 delete,回滾時會執行insert;
  •  對于每個 update,回滾時會執行一個相反的 update,把數據改回去。

以update操作為例:當事務執行update時,其生成的undo log中會包含被修改行的主鍵(以便知道修改了哪些行)、修改了哪些列、這些列在修改前后的值等信息,回滾時便可以使用這些信息將數據還原到update之前的狀態。

持久性

Innnodb有很多 log,持久性靠的是 redo log。

一條SQL更新語句怎么運行

持久性肯定和寫有關,MySQL 里經常說到的 WAL 技術,WAL 的全稱是 Write-Ahead Logging,它的關鍵點就是先寫日志,再寫磁盤。就像小店做生意,有個粉板,有個賬本,來客了先寫粉板,等不忙的時候再寫賬本。點擊在線刷題,看看你可以打多少分了。

redo log

redo log 就是這個粉板,當有一條記錄要更新時,InnoDB 引擎就會先把記錄寫到 redo log(并更新內存),這個時候更新就算完成了。在適當的時候,將這個操作記錄更新到磁盤里面,而這個更新往往是在系統比較空閑的時候做,這就像打烊以后掌柜做的事。

redo log 有兩個特點:

  •  大小固定,循環寫
  • crash-safe

對于redo log 是有兩階段的:commit 和 prepare 如果不使用“兩階段提交”,數據庫的狀態就有可能和用它的日志恢復出來的庫的狀態不一致. 好了,先到這里,看看另一個。

Buffer Pool

InnoDB還提供了緩存,Buffer Pool 中包含了磁盤中部分數據頁的映射,作為訪問數據庫的緩沖:

  •  當讀取數據時,會先從Buffer Pool中讀取,如果Buffer Pool中沒有,則從磁盤讀取后放入Buffer Pool;
  •  當向數據庫寫入數據時,會首先寫入Buffer Pool,Buffer Pool中修改的數據會定期刷新到磁盤中。

Buffer Pool 的使用大大提高了讀寫數據的效率,但是也帶了新的問題:如果MySQL宕機,而此時 Buffer Pool 中修改的數據還沒有刷新到磁盤,就會導致數據的丟失,事務的持久性無法保證。

所以加入了 redo log。當數據修改時,除了修改Buffer Pool中的數據,還會在redo log記錄這次操作;

當事務提交時,會調用fsync接口對redo log進行刷盤。

如果MySQL宕機,重啟時可以讀取redo log中的數據,對數據庫進行恢復。

redo log采用的是WAL(Write-ahead logging,預寫式日志),所有修改先寫入日志,再更新到Buffer Pool,保證了數據不會因MySQL宕機而丟失,從而滿足了持久性要求。而且這樣做還有兩個優點:

  •  刷臟頁是隨機 IO,redo log 順序 IO
  • 刷臟頁以Page為單位,一個Page上的修改整頁都要寫;而redo log 只包含真正需要寫入的,無效 IO 減少。

binlog

說到這,可能會疑問還有個 bin log 也是寫操作并用于數據的恢復,有啥區別呢。

  •  層次:redo log 是 innoDB 引擎特有的,server 層的叫 binlog(歸檔日志)
  •  內容:redolog 是物理日志,記錄“在某個數據頁上做了什么修改”;binlog 是邏輯日志,是語句的原始邏輯,如“給 ID=2 這一行的 c 字段加 1 ”
  •  寫入:redolog 循環寫且寫入時機較多,binlog 追加且在事務提交時寫入

binlog 和 redo log

對于語句 update T set c=c+1 where ID=2;

  1.  執行器先找引擎取 ID=2 這一行。ID 是主鍵,直接用樹搜索找到。如果 ID = 2 這一行所在數據頁就在內存中,就直接返回給執行器;否則,需要先從磁盤讀入內存,再返回。
  2.  執行器拿到引擎給的行數據,把這個值加上 1,N+1,得到新的一行數據,再調用引擎接口寫入這行新數據。
  3.  引擎將這行新數據更新到內存中,同時將這個更新操作記錄到 redo log 里面,此時 redo log 處于 prepare 狀態。然后告知執行器執行完成了,隨時可以提交事務。
  4.  執行器生成這個操作的 binlog,并把 binlog 寫入磁盤。
  5.  執行器調用引擎的提交事務接口,引擎把剛剛寫入的 redo log 改成提交(commit)狀態,更新完成

為什么先寫 redo log 呢 ?

  •  先 redo 后 bin : binlog 丟失,少了一次更新,恢復后仍是0。
  •  先 bin 后 redo : 多了一次事務,恢復后是1。

一致性

一致性是事務追求的最終目標,前問所訴的原子性、持久性和隔離性,其實都是為了保證數據庫狀態的一致性。當然,上文都是數據庫層面的保障,一致性的實現也需要應用層面進行保障。

也就是你的業務,比如購買操作只扣除用戶的余額,不減庫存,肯定無法保證狀態的一致。

總結

MySQL 都很熟, ACID 也知道是個啥,但 MySQL 的 ACID 怎么實現的?

有時候,就像你知道了有 undo log、redo log 但可能并不太清楚為什么有,當知道了設計的目的,了解起來就會更加清晰了。另外,關注公眾號Java技術棧,在后臺回復:面試,可以獲取我整理的 Java/ MySQL 系列面試題和答案,非常齊全。 

 

責任編輯:龐桂玉 來源: Java技術棧
相關推薦

2021-09-27 07:11:18

MySQLACID特性

2024-12-30 13:58:14

2021-07-08 07:08:21

MySQL ACID 數據庫

2020-02-13 10:14:11

MySQL事務ACID

2021-09-07 10:33:42

MySQL事務隔離性

2019-01-29 09:36:10

MySQLACID特性

2019-04-03 09:27:01

MySQLInnoDB務ACID

2015-10-12 15:33:28

YouTubeMySQL彈性部署

2024-12-02 08:37:04

2025-09-04 01:25:00

樓層定位技術

2024-11-05 15:02:41

2022-05-16 08:22:37

零拷貝Netty

2022-07-18 23:49:19

區塊鏈民主數據

2022-08-02 11:27:25

RabbitMQ消息路由

2019-01-22 15:26:48

APP會員自動續費簽約

2023-12-07 07:46:21

MySQL寫入點LSN

2009-07-22 09:43:30

Scala類型

2023-12-26 01:07:03

TCP擁塞控制

2025-10-29 02:11:00

2024-09-14 14:18:43

點贊
收藏

51CTO技術棧公眾號

亚洲国产精品yw在线观看 | 亚洲综合小说区| 亚洲国产精品免费| 国产欧美精品国产国产专区| 国产精品动漫网站| 亚洲精品亚洲人成在线| 成人免费网站视频| 羞羞视频在线免费国产| 在线观看男女av免费网址| 999在线免费视频| 国产91在线播放九色快色| 精品国产髙清在线看国产毛片| 91老司机福利 在线| 另类图片国产| 精品国产乱码久久久| 免费av不卡在线观看| 国产激情在线播放| 日本精品久久久久影院| 亚洲激情自拍视频| 婷婷另类小说| 麻豆网站在线看| 日韩亚洲视频| 国产一区二区三区在线观看网站 | 成人激情综合| 日韩免费一级视频| 91精品国产自产91精品| 一区二区三区精品在线| 日韩午夜精品视频| 一区二区三区四区视频| 国产精品国产精品国产专区不蜜 | 无码国模国产在线观看| yes4444视频在线观看| 日本大片在线播放| 国产精品xnxxcom| 日韩av在线播放网址| 亚洲精品一级| 国产suv精品一区二区883| 一区二区三区日韩欧美精品| 91黄色免费网站| 欧美日韩一级黄| 337p日本欧洲亚洲大胆色噜噜| 色婷婷精品大在线视频| 一本色道**综合亚洲精品蜜桃冫| 亚洲动漫第一页| 国产精品日韩成人| 国产喷白浆一区二区三区| 欧美日韩不卡一区二区| 日韩亚洲国产精品| 99只有精品| 九草视频在线观看| 日韩一区国产在线观看| 久久99热这里只有精品国产| 色综合天天狠狠| 风间由美性色一区二区三区| 欧美伦理在线视频| 奇米777日韩| 久草在线新视觉| 精品人妻人人做人人爽| 成人福利视频网| 在线成人中文字幕| 欧美日韩激情小视频| 国产成人午夜精品影院观看视频 | 亚洲理论电影片| 高清久久一区| 99热这里只有精品8| 亚洲欧美日韩在线| 亚洲人午夜精品| 久久精品国产综合精品| 交换国产精品视频一区| 国产日韩一区二区三免费高清| 亚洲美女黄色| 国产精品一二三区在线| 综合激情成人伊人| 欧美日韩一区在线观看| 日韩精品中文字幕视频在线| 国内精品久久久久久久久| 国产日产欧美精品| 日本一区视频在线| 日本888xxxx| 日韩精品在线播放| 亚洲综合偷拍欧美一区色| 免费在线成人网| 精品国产一区探花在线观看 | 欧美专区福利在线| 亚洲精品电影在线观看| 精品久久中文字幕| av午夜精品一区二区三区| 国产精品一国产精品k频道56| 欧美深夜视频| 日韩影片中文字幕| 亚洲精品承认| 91骚色在线| 欧美一级视频在线播放| 精品影片在线观看的网站| 国产馆精品极品| 色综合久久综合网| 91久久精品午夜一区二区| 日本精品va在线观看| 成视人a免费观看视频| 成人精品小视频| 一级在线观看| 狠狠做六月爱婷婷综合aⅴ| 欧美性xxxx在线播放| 超碰97国产在线| av免费在线免费| 国产一区二区三区免费观看| 精品免费一区二区三区| 亚洲欧美99| 不卡亚洲精品| 肉肉av福利一精品导航| 欧美麻豆精品久久久久久| 91九色国产视频| 成人免费在线小视频| 欧美片第一页| 石原莉奈在线亚洲二区| 亚洲香肠在线观看| 欧美激情综合亚洲一二区 | 91麻豆天美传媒在线| 国产视频一区二区三区四区| 91精品在线影院| 国产啪精品视频| 国产精品九九九| 欧美最猛黑人xxxx黑人猛叫黄| 欧美精品在线观看91| 日韩亚洲成人av在线| 亚洲香蕉成人av网站在线观看| 日韩av网站电影| 亚洲第一中文字幕在线观看| 欧美成人一区二区三区| 欧美一二区视频| 日韩天堂在线观看| 日韩欧美精品三级| 在线电影院国产精品| 欧美日本在线播放| 精品视频1区2区3区| 欧美日免费三级在线| 亚洲一区站长工具| 亚洲国产精品99久久久久久久久 | 日日噜噜噜噜久久久精品毛片| av福利导福航大全在线| 日本欧美韩国一区三区| 性色av一区二区三区| 一道本在线免费视频| 亚洲久久视频| 色噜噜亚洲精品中文字幕| 午夜影院观看视频免费| 亚洲精品日本| 欧美国产在线电影| 日本中文字幕电影在线免费观看 | 久久久久久91| 青春草免费在线视频| 任我爽精品视频在线播放| 欧美色中文字幕| 99re免费99re在线视频手机版| 欧美激情精品久久久六区热门| 深夜成人在线观看| 香蒸焦蕉伊在线| 亚洲国产岛国毛片在线| 欧美日韩一区二区三区在线视频 | 国产成人黄色av| 国产麻豆一区| 日韩一区二区三区三四区视频在线观看| 男人透女人免费视频| 日韩制服丝袜av| 成人a在线视频| 伊人久久大香线蕉| 日韩一区二区三区国产| 丝袜美腿av在线| 一本一本久久a久久精品综合麻豆| 国产一区亚洲二区三区| 国产一区二区三区在线看麻豆| 91免费在线视频| 国产精品极品国产中出| 亚洲免费视频网站| 77导航福利在线| 精品国产乱码久久久久久天美 | 欧美日韩一区二区三区视频播放| 综合网日日天干夜夜久久| 黄色av电影在线播放| 亚洲高清不卡在线| xx免费视频| 亚洲欧美另类久久久精品2019| 91n.com在线观看| 91首页免费视频| 欧美视频在线播放一区| 国产·精品毛片| 日韩视频在线免费播放| 紧缚捆绑精品一区二区| 婷婷视频在线播放| 精品一二线国产| 一区二区三区在线视频看| 国产成人免费视频网站 | 久久综合九色99| 亚洲激情在线| 亚洲一区二区精品在线观看| 九九精品视频在线看| 黄色成人在线看| 亚洲国产成人一区二区三区| 天堂av电影在线观看| 精品捆绑美女sm三区|