成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

為什么MySQL默認使用RR隔離級別?

數據庫 MySQL
我們現在明白了為什么MySQL選擇Repeatable Read作為默認的數據庫隔離級別了,實際上是為了與歷史上那種statement格式的binlog保持兼容性。

對于數據庫的默認隔離級別,Oracle默認的隔離級別是 RC,而MySQL默認的隔離級別是 RR。

那么,你知道為什么Oracle選擇RC作為默認級別,而MySQL要選擇RR作為默認的隔離級別嗎?

Oracle的隔離級別

Oracle支持ANSI/ISO SQL定義的Serializable和Read Committed兩種隔離級別,根據Oracle官方文檔的介紹,Oracle的隔離級別包括Read Committed、Serializable和Read-Only。

圖片圖片

Read-Only的隔離級別類似于Serializable,然而僅允許只讀事務進行數據檢索,不允許在事務中修改數據,除非使用者是SYS用戶。

在Oracle的這三種隔離級別中,顯而易見,Serializable和Read-Only都不適合作為默認隔離級別,因此唯一的選擇就是Read Committed了。

MySQL的隔離級別

與Oracle相比,MySQL提供的默認隔離級別范圍更加廣泛。

首先,我們排除了Serializable和Read Uncommitted這兩種級別,原因是一個隔離級別過高會影響并發度,另一個過低則存在臟讀問題。

剩下的RR和RC兩種,如何選擇呢?

MySQL在設計之初就旨在提供一個穩定的關系型數據庫。為解決MySQL單點故障問題,MySQL采取了主從復制機制。

所謂的主從復制,即通過建立MySQL集群,以整體向外提供服務。集群內的機器分為主服務器(Master)和從服務器(Slave),主服務器負責提供寫服務,而從服務器則提供讀服務。

在MySQL主從復制過程中,數據的同步通過binlog進行。簡單來說,主服務器將數據變更記錄到binlog中,然后將binlog同步傳輸給從服務器。從服務器接收到binlog后,將其中的數據恢復到自己的數據庫存儲中。

那么,binlog里記錄的究竟是什么內容?它的格式又是怎樣的呢?

MySQL的binlog主要支持三種格式,即statement、row和mixed。MySQL從5.1.5版本開始支持row格式,在5.1.8版本中開始支持mixed格式。

statement和row之間最重要的區別在于,當binlog的格式為statement時,binlog記錄的是SQL語句的原文。

由于MySQL早期僅支持statement這一種binlog格式,因此在使用提交讀(Read Committed)和未提交讀(Read Uncommitted)這兩種隔離級別時都可能會出現問題。

舉個例子,有一個數據庫表t1,表中有如下兩條記錄:

CREATE TABLE `t1` (
  `a` int(11) DEFAULT NULL,
  `b` int(11) DEFAULT NULL,
  KEY `b` (`b`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

insert into t1 values(10,1);

接著開始執行兩個事務的寫操作:

Session 1

Session 2

set session transaction isolation level read committed;


set autocommit = 0;

set session transaction isolation level read committed;

begin;

begin;

delete from t1 where b < 100;



insert into t1 values(10,99);


commit;

commit;


以上兩個事務執行之后,數據庫里面的記錄會只有一條記錄(10,99),這個發生在主庫的數據變更大家都能理解。

即使 Session 1 的刪除操作在 Session 2 的插入操作之后提交,由于 READ COMMITTED 的隔離級別,Session 2 的插入操作不會看到 Session 1 的刪除操作,所以最后數據庫中仍然會留下 Session 2 插入的記錄 (10,99)。

這種行為是 READ COMMITTED 隔禽級別的一種特性,它會在事務開始時創建一個快照。確保事務之間的隔離性,避免了數據不一致性的問題。

以上兩個事務執行之后,會在bin log中記錄兩條記錄,因為事務2先提交,所以insert into t1 values(10,99);會被優先記錄,然后再記錄delete from t1 where b < 100;(再次提醒:statement格式的bin log記錄的是SQL語句的原文)

這樣bin log同步到備庫之后,SQL語句回放時,會先執行insert into t1 values(10,99);,再執行delete from t1 where b < 100;。

這時候,數據庫中的數據就會變成 EMPTY SET,即沒有任何數據。這就導致主庫和備庫的數據不一致了!!!

為了解決這種問題,MySQL將數據庫的默認隔離級別設置為Repeatable Read。在Repeatable Read隔離級別下,針對更新數據時會不僅對更新的行加行級鎖,還會增加GAP鎖和next-key鎖。在上述例子中,當事務 2 執行時,由于事務 1 添加了GAP鎖和next-key鎖,這將導致事務 2 執行被阻塞,需要等待事務 1 提交或回滾后才能繼續執行。

除了設置默認的隔離級別外,MySQL還禁止在使用statement格式的binlog的情況下,將事務隔離級別設置為READ COMMITTED。

一旦用戶主動修改隔離級別,嘗試更新時,會報錯:

ERROR 1598 (HY000): Binary logging not possible. Message: Transaction level 'READ-COMMITTED' in InnoDB is not safe for binlog mode 'STATEMENT'

因此,我們現在明白了為什么MySQL選擇Repeatable Read作為默認的數據庫隔離級別了,實際上是為了與歷史上那種statement格式的binlog保持兼容性。

責任編輯:武曉燕 來源: 碼上遇見你
相關推薦

2021-12-10 11:45:49

MySQLRRRC

2024-07-16 08:19:46

MySQL數據InnoDB

2021-06-17 09:16:34

MySQL數據庫隔離級別

2022-09-08 08:02:26

MySQL隔離

2021-06-11 16:59:41

MySQLRepeatableRead

2021-08-26 06:58:15

Innodb RR隔離級別

2018-12-19 16:46:38

MySQL事務隔離數據庫

2021-07-26 10:28:13

MySQL事務隔離

2024-04-26 09:17:20

MySQL事務隔離

2022-06-10 11:51:49

MySQL事務隔離

2021-08-04 13:19:42

MySQL 事務隔離

2024-12-02 08:37:04

2021-10-19 10:10:51

MySQL事務隔離級別數據庫

2022-07-26 07:14:20

線程隔離Thread

2010-11-19 16:13:06

oracle事務隔離級

2009-06-29 17:54:47

Spring事務隔離

2024-06-26 00:43:54

MySQL測試TOTAL?

2025-03-03 08:20:00

MySQL事務隔離數據庫

2020-10-13 10:32:24

MySQL事務MVCC

2025-01-13 13:12:54

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 久久久久久久久中文字幕 | 农夫在线精品视频免费观看 | 亚洲高清av在线 | 欧美日韩一区二区在线播放 | 国产一级精品毛片 | 日一区二区三区 | 欧美电影免费观看 | 亚洲视频一区在线观看 | 欧美日韩综合一区 | 国产小视频在线 | 日本a∨精品中文字幕在线 亚洲91视频 | 精品成人在线观看 | 亚洲精品一区二区另类图片 | 国产欧美日韩精品在线观看 | 欧美日韩一区在线观看 | 国产在线观看一区二区三区 | 日韩高清一区 | 久久久久久久久久久久91 | 久久99国产精品 | 草草视频在线免费观看 | av中文字幕在线 | 日韩精品一区二区三区在线观看 | 综合精品久久久 | 亚洲一区二区精品视频 | 性高朝久久久久久久3小时 av一区二区三区四区 | 久久在线 | 精品久久久久久久久久久久 | 日韩毛片免费看 | 97国产精品 | 色婷婷综合久久久久中文一区二区 | 久久久久一区二区三区 | 日韩第一页 | 老司机67194精品线观看 | 国产精品美女www爽爽爽 | 久草中文在线 | 久久av一区二区三区 | 黄视频欧美 | 日韩中文字幕免费在线观看 | 精品一区二区三区四区 | 亚洲午夜精品 | 色综合美女|