欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

一文詳解MYSQL的多版本并發(fā)控制MVCC(Multi-Version Concurrency Control)

 更新時間:2023年10月10日 11:33:24   作者:寅恪光潛  
MVCC是一種用于數(shù)據(jù)庫管理系統(tǒng)的并發(fā)控制技術,允許多個事務同時訪問數(shù)據(jù)庫,而不會導致讀寫沖突,本文就詳細的介紹了MVCC的具體用法,具有一定的參考價值,感興趣的可以了解一下

1、概述

MVCC是一種用于數(shù)據(jù)庫管理系統(tǒng)的并發(fā)控制技術,允許多個事務同時訪問數(shù)據(jù)庫,而不會導致讀寫沖突。也就是說在讀寫的時候,線程不用去爭搶讀寫鎖。因為加鎖的過程比較耗性能。
當然很多時候還是必須的,不能避免,比如說,去ATM機取錢的時候,同時又在手機APP上進行提現(xiàn),這種操作就需要加鎖,不能讓其同時提現(xiàn),一次只能一個操作,而且只有在ATM取錢這個事務被提交之后才能做其他操作。

處理并發(fā)的場景無外乎三種:

  • 讀、讀:這個不需要做控制,因為數(shù)據(jù)沒有變化
  • 讀、寫:存在線程安全問題,可能出現(xiàn)臟讀、幻讀,不可重復讀
  • 寫、寫:存在線程安全問題,可能出現(xiàn)更新丟失的情況

這里介紹的MVCC是在存儲引擎為InnoDB實現(xiàn)的,目的也是為了提高數(shù)據(jù)庫的并發(fā)性能,不使用加鎖的方式去處理讀、寫并發(fā)。

2、MVCC特點

這里的讀操作,有兩種方式:
快照讀:SELECT語句,在讀寫的時候不用加鎖,所以效率很高,但也存在讀取的時候有更新操作,可能會讀到歷史數(shù)據(jù)。

當前讀:讀取的是最新數(shù)據(jù),是一種悲觀鎖的操作。它會對當前讀取的數(shù)據(jù)進行加鎖,避免其他事物對其進行寫操作。主要包括以下幾種操作:

  • select lock in share mode(共享鎖)
  • select for update(排他鎖)
  • update(排他鎖)
  • insert(排他鎖)
  • delete(排他鎖)

3、準備數(shù)據(jù)

在介紹之前,沒有安裝MYSQL的,可以先進行安裝,下載地址:https://dev.mysql.com/downloads/
安裝好了之后,我們就新建庫與表,插入一些數(shù)據(jù)來做個測試

CREATE DATABASE mydb;
USE mydb;
CREATE TABLE `tb1` (
  `id` int(12) NOT NULL AUTO_INCREMENT,
  `name` varchar(32) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=UTF8;
INSERT INTO tb1(name) VALUES ('XIAO1'),('XIAO2'),('XIAO3');
CREATE TABLE `tb2` (
  `id` int(12) NOT NULL AUTO_INCREMENT,
  `name` varchar(32) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=myisam;
INSERT INTO tb2(name) VALUES ('LAO1'),('LAO2'),('LAO3');

這里我特地創(chuàng)建了兩張表,分別是表tb1對應的是InnoDB引擎,表tb2對應的是myisam引擎,創(chuàng)建之后,也可以看到兩者的數(shù)據(jù)格式也是不一樣的,我們先查詢下,新建的數(shù)據(jù)庫mydb以及保存的數(shù)據(jù)在什么地方:

mysql> show variables like '%datadir%';
+---------------+---------------------------------------------+
| Variable_name | Value                                       |
+---------------+---------------------------------------------+
| datadir       | C:\ProgramData\MySQL\MySQL Server 8.0\Data\ |
+---------------+---------------------------------------------+
1 row in set, 1 warning (0.00 sec)

然后可以看到,InnoDB引擎對應的是:tb1.ibd ,myisam對應的是:tb2.MYD(數(shù)據(jù))、tb2.MYI(索引)、tb2_402.sdi(表結構)[這個在以前的版本沒有出現(xiàn)]
MySQL5.5之后都是默認為InnoDB引擎

4、MVCC原理

MYSQL存儲的數(shù)據(jù)中,除了我們顯式定義的字段,還隱含著兩個字段。
trx_id:事務id,每進行一次事務操作,就會自增1。
roll_pointer:回滾指針,用于找到上一個版本的數(shù)據(jù),結合undolog進行回滾。

我們用SELECT讀數(shù)據(jù)時,這一時刻的數(shù)據(jù)會有很多個版本【比如上圖四個版本】,但我們并不知道讀取哪個版本,依賴ReadView來對我們進行版本的選擇,通過ReadView我們就能夠知道讀取哪個版本。我們來看下這個ReadView的定義:

class ReadView {
/* ... */
private:
trx_id_t m_low_limit_id; /* 大于等于這個 ID 的事務均不可見 */
trx_id_t m_up_limit_id; /* 小于這個 ID 的事務均可見 */
trx_id_t m_creator_trx_id; /* 創(chuàng)建該 Read View 的事務ID */
trx_id_t m_low_limit_no; /* 事務 Number, 小于該 Number 的 Undo Logs 均可以被 Purge */
ids_t m_ids; /* 創(chuàng)建 Read View 時的活躍事務列表 */
m_closed; /* 標記 Read View 是否 close */
}

字段的解釋:

  • m_low_limit_id:目前出現(xiàn)的最大事務ID+1(下一個將被分配的事務ID)。大于等于這個ID的數(shù)據(jù)版本均不可見,也就訪問不到。
  • m_up_limit_id:活躍事務列表m_ids中最小的事務ID,如果為空,則m_up_limit_id為m_low_limit_id。小于這個ID的數(shù)據(jù)版本均可見。
  • m_ids:ReadView創(chuàng)建時其他未提交的活躍事務ID列表。創(chuàng)建ReadView時,將當前未提交事務ID記錄下來,后續(xù)即使它們修改了記錄行的值,對于當前事務也是不可見的。m_ids 不包括當前事務自己和已提交的事務(正在內存中)
  • m_creator_trx_id:創(chuàng)建該ReadView的事務ID

5、實踐操作

開四個終端,新建三個事務,兩個寫操作,一個讀操作,還有一個就是單純的查詢。大家可以根據(jù)不同的進入時間來了解這個過程,會產生未提交和已提交事務狀態(tài),對應的查詢信息都是不一樣的,具體代碼分別如下:

BEGIN;
UPDATE tb1 SET  name='XXX' WHERE id=1;
UPDATE tb1 SET  name='YYY' WHERE id=1;
COMMIT;
BEGIN;
UPDATE tb1 SET  name='ZZZ' WHERE id=1;
UPDATE tb1 SET  name='QQQ' WHERE id=1;
DELETE FROM tb1 WHERE id=5;
COMMIT;
BEGIN;
SELECT * FROM tb1 WHERE id=1;
COMMIT;
SELECT * FROM tb1;

6、小結

對于這種讀寫并發(fā),以及對性能的要求,大家需要看實際業(yè)務情況來做決定,其中這里主要是介紹InnoDB引擎,這個要高效很多,在以前的舊版本可能大家使用MyISAM這個更多,因為性能很好,不過不支持事務操作,所以很多場景也就不適應,MYSQL5.5版本之后就是默認InnoDB引擎了。
最后大家也可以嘗試在表tb2中去嘗試下,看下是什么結果,因為這張表使用的是MyISAM引擎,就起不到作用了。
另外需要注意的是,事務的提交是默認自動的,有些時候需要關閉,將默認的1修改為0:

SET AUTOCOMMIT=0;
SELECT @@AUTOCOMMIT;

比如說對于臟讀的情況,我們需要當前讀,也就是需要排它鎖:

SET AUTOCOMMIT=0;
BEIGIN;
DELETE FROM tb1 WHERE id=2;

這種情況如果我們的事務在這個時候進去,對這個id=2進行讀寫操作,就會出現(xiàn)臟讀的情況,這個時候就需要使用SELECT FOR UPDATE,等待事務處理完畢之后再做相應的操作。

對于臟讀這種情況,很常見,比如說事務在做刪除操作,這個時候記錄已被刪除但是還沒有提交事務,如果進行查詢操作就會出現(xiàn)臟讀,如下:

SET AUTOCOMMIT=0;
BEGIN;
SELECT * FROM tb1 WHERE id=2 FOR UPDATE;
UPDATE tb1 SET  name='QQQ' WHERE id=1;
COMMIT;

到此這篇關于一文詳解MYSQL的多版本并發(fā)控制MVCC(Multi-Version Concurrency Control)的文章就介紹到這了,更多相關MYSQL多版本并發(fā)控制MVCC內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 詳解mysql的limit經典用法及優(yōu)化實例

    詳解mysql的limit經典用法及優(yōu)化實例

    這篇文章詳細介紹了mysql的limit經典用法及優(yōu)化實例,有需要的朋友可以參考一下
    2013-09-09
  • MySql常用操作SQL語句匯總

    MySql常用操作SQL語句匯總

    這篇文章主要介紹了MySql常用操作SQL語句匯總,本文講解了增加、刪除、查詢、修改等常用SQL語句實例,需要的朋友可以參考下
    2015-03-03
  • MySQL之模糊查詢特殊字符處理方式

    MySQL之模糊查詢特殊字符處理方式

    這篇文章主要介紹了MySQL之模糊查詢特殊字符處理方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • 使用JDBC從數(shù)據(jù)庫中查詢數(shù)據(jù)的方法

    使用JDBC從數(shù)據(jù)庫中查詢數(shù)據(jù)的方法

    下面小編就為大家?guī)硪黄褂肑DBC從數(shù)據(jù)庫中查詢數(shù)據(jù)的方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-08-08
  • 揭秘SQL優(yōu)化技巧 改善數(shù)據(jù)庫性能

    揭秘SQL優(yōu)化技巧 改善數(shù)據(jù)庫性能

    這篇文章是以 MySQL 為背景,很多內容同時適用于其他關系型數(shù)據(jù)庫,需要有一些索引知識為基礎,重點講述如何優(yōu)化SQL,來提高數(shù)據(jù)庫的性能
    2012-01-01
  • MySQL 存儲過程的基本用法介紹

    MySQL 存儲過程的基本用法介紹

    我們大家都知道MySQL 存儲過程是從 MySQL 5.0 開始逐漸增加新的功能。存儲過程在實際應用中也是優(yōu)點大于缺點。不過最主要的還是執(zhí)行效率和SQL 代碼封裝。特別是 SQL 代碼封裝功能,如果沒有存儲過程。
    2010-12-12
  • MySQL中的聯(lián)合索引學習教程

    MySQL中的聯(lián)合索引學習教程

    這篇文章主要介紹了MySQL中的聯(lián)合索引學習教程,其中談到了聯(lián)合索引對排序的優(yōu)化等知識點,需要的朋友可以參考下
    2015-11-11
  • mysql 教程 存儲過程

    mysql 教程 存儲過程

    最近用mysql + asp.net來寫網站,既然mysql已經支持存儲過程了,那么像分頁這么常用的東西,當然要用存儲過程啦
    2009-06-06
  • mysqldump你可能不知道的參數(shù)

    mysqldump你可能不知道的參數(shù)

    這篇文章主要介紹了mysqldump你可能不知道的參數(shù),幫助大家更好的理解和使用MySQL,感興趣的朋友可以了解下
    2020-11-11
  • MySQL配置文件my.cnf中文詳解附mysql性能優(yōu)化方法分享

    MySQL配置文件my.cnf中文詳解附mysql性能優(yōu)化方法分享

    Mysql參數(shù)優(yōu)化對于新手來講,是比較難懂的東西,其實這個參數(shù)優(yōu)化,是個很復雜的東西,對于不同的網站,及其在線量,訪問量,帖子數(shù)量,網絡情況,以及機器硬件配置都有關系,優(yōu)化不可能一次性完成,需要不斷的觀察以及調試,才有可能得到最佳效果。
    2011-09-09

最新評論