国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當(dāng)前位置: 首頁 > news >正文

網(wǎng)站安全如何做百度 營銷推廣多少錢

網(wǎng)站安全如何做,百度 營銷推廣多少錢,單獨(dú)做網(wǎng)站要學(xué)程序設(shè)計嗎,網(wǎng)絡(luò)營銷外包靠譜嗎MVCC是什么? MVCC,是MultiVersion Concurrency Control的縮寫,翻譯成中文就是多版本并發(fā)控制,多個事務(wù)同時訪問同一數(shù)據(jù)時,調(diào)控每一個事務(wù)獲取到數(shù)據(jù)的具體版本。和數(shù)據(jù)庫鎖一樣,它也是一種并發(fā)控制的解決…

MVCC是什么?

MVCC,是MultiVersion Concurrency Control的縮寫,翻譯成中文就是多版本并發(fā)控制,多個事務(wù)同時訪問同一數(shù)據(jù)時,調(diào)控每一個事務(wù)獲取到數(shù)據(jù)的具體版本。和數(shù)據(jù)庫鎖一樣,它也是一種并發(fā)控制的解決方案。主要用于解決臟讀、可重復(fù)讀部分幻讀問題,所以MVCC主要被運(yùn)用于讀提交、可重復(fù)讀這兩種事務(wù)隔離級別下。

MVCC解決并發(fā)讀寫問題主要依賴于UndoLog隱藏字段ReadView讀視圖這三個部分。其中最重要的就是ReadView隱藏字段。

MVCC解決了哪些問題

讀未提交事務(wù)隔離級別下,直接讀取UndoLog版本鏈中的最新記錄即可。

讀提交事務(wù)隔離級別下,通過MVCC中每次讀取數(shù)據(jù)的時候生成一次ReadView解決臟讀問題

可重復(fù)讀事務(wù)隔離級別下,通過MVCC中每次開啟一次事務(wù)的時候生成一次ReadView解決不可重復(fù)讀問題

可重復(fù)讀事務(wù)隔離級別下,通過MVCC中每次開啟一次事務(wù)的時候生成一次ReadView讀視圖,后續(xù)的查詢都是根據(jù)這個ReadView讀視圖來判斷哪些數(shù)據(jù)是可讀的,即使中途有其他事務(wù)插入了新紀(jì)錄,也是查詢不出來這條數(shù)據(jù)的,所以就很好了避免幻讀問題。

快照讀與當(dāng)前讀

MVCC在MySQL InnoDB中的實現(xiàn)主要是為了提高數(shù)據(jù)庫并發(fā)性能,用更好的方式去處理 讀-寫沖突 ,做到即使有讀寫沖突時,也能做到 不加鎖 ,即非阻塞并發(fā)讀 ,而這個讀指的就是 快照讀 , 而非 當(dāng)前讀 。當(dāng)前讀實際上是一種加鎖的操作,是悲觀鎖的實現(xiàn)。而MVCC本質(zhì)是采用樂觀鎖思想的一種方式。

快照讀

快照讀又叫一致性讀,讀取的是快照數(shù)據(jù)。不加鎖的簡單的 SELECT 都屬于快照讀,即不加鎖的非阻塞 讀;比如這樣:

SELECT * FROM player WHERE ...

之所以出現(xiàn)快照讀的情況,是基于提高并發(fā)性能的考慮,快照讀的實現(xiàn)是基于MVCC,它在很多情況下, 避免了加鎖操作,降低了開銷。

既然是基于多版本,那么快照讀可能讀到的并不一定是數(shù)據(jù)的最新版本,而有可能是之前的歷史版本。

快照讀的前提是隔離級別不是串行級別,串行級別下的快照讀會退化成當(dāng)前讀。

當(dāng)前讀

當(dāng)前讀讀取的是記錄的最新版本(最新數(shù)據(jù),而不是歷史版本的數(shù)據(jù)),讀取時還要保證其他并發(fā)事務(wù) 不能修改當(dāng)前記錄,會對讀取的記錄進(jìn)行加鎖。加鎖的 SELECT,或者對數(shù)據(jù)進(jìn)行增刪改都會進(jìn)行當(dāng)前 讀。比如:

SELECT * FROM student LOCK IN SHARE MODE; # 共享鎖
SELECT * FROM student FOR UPDATE; # 排他鎖
INSERT INTO student values ... # 排他鎖
DELETE FROM student WHERE ... # 排他鎖
UPDATE student SET ... # 排他鎖

Read View 在 MVCC 里如何工作的?

我們需要了解兩個知識:

  • Read View 中四個字段作用;
  • 聚簇索引記錄中兩個跟事務(wù)有關(guān)的隱藏列;

什么是ReadView?

那 Read View 到底是個什么東西?

Read View 是事務(wù)開始或讀取數(shù)據(jù)時創(chuàng)建的一致性視圖,記錄了當(dāng)前系統(tǒng)中活躍事務(wù)的集合。這個視圖幫助事務(wù)確定哪些版本的數(shù)據(jù)是可見的。通過 Read View,事務(wù)能夠看到在其開始時已經(jīng)提交的事務(wù)產(chǎn)生的數(shù)據(jù)版本,而忽略未提交的事務(wù)的數(shù)據(jù)版本。

Read View 有四個重要的字段:

  • m_ids :當(dāng)前活躍的事務(wù)編號列表。指的是在創(chuàng)建 Read View 時,當(dāng)前數(shù)據(jù)庫中「活躍事務(wù)」的事務(wù)id編號列表,注意是一個列表,“活躍事務(wù)”指的就是,啟動了但還沒提交的事務(wù)
  • min_trx_id :最小活躍事務(wù)編號。指的是在創(chuàng)建 Read View 時,當(dāng)前數(shù)據(jù)庫中「活躍事務(wù)」中事務(wù) id編號最小的事務(wù),也就是 m_ids 的最小值。
  • max_trx_id :預(yù)分配事務(wù)編號。這個并不是 m_ids 的最大值,而是創(chuàng)建 Read View 時當(dāng)前數(shù)據(jù)庫中應(yīng)該給下一個事務(wù)的 id 值,也就是全局事務(wù)中最大的事務(wù) id 值加1;
  • creator_trx_id :ReadView 創(chuàng)建者的事務(wù)編號。指的是創(chuàng)建該 Read View 的事務(wù)的事務(wù) id。

ReadView結(jié)構(gòu)如下圖所示:

知道了 Read View 的字段,我們還需要了解聚簇索引記錄中的兩個隱藏列。

隱藏列和Undo Log版本鏈

假設(shè)在賬戶余額表插入一條小林余額為 100 萬的記錄,然后我把這兩個隱藏列也畫出來,該記錄的整個示意圖如下:

對于使用 InnoDB 存儲引擎的數(shù)據(jù)庫表,它的聚簇索引記錄中都包含下面兩個隱藏列:

  • trx_id,當(dāng)一個事務(wù)對某條聚簇索引記錄進(jìn)行改動時,就會把該事務(wù)的事務(wù) id賦值給trx_id 隱藏列
  • roll_pointer,每次對某條聚簇索引記錄進(jìn)行改動時,都會把舊版本的記錄寫入到 undo 日志中,然后這個隱藏列是個指針,指向每一個舊版本記錄,于是就可以通過它找到修改前的記錄。

創(chuàng)建student表,表結(jié)構(gòu)如下:

假設(shè)此時插入一條新記錄,該記錄的事務(wù)id為8,那么此刻該條記錄的示意圖如下所示:

注意:insert undo只在事務(wù)回滾時起作用,當(dāng)事務(wù)提交后,該類型的undo日志就沒用了,它占用的Undo Log Segment也會被系統(tǒng)回收(也就是該undo日志占用的Undo頁面鏈表要么被重用,要么被釋放)。

假設(shè)之后兩個事務(wù)id分別為 10 、 20 的事務(wù)對這條記錄進(jìn)行UPDATE 更新操作,操作流程如下圖:

每次對記錄進(jìn)行改動,都會記錄一條undo日志,每條undo日志也都有一個 roll_pointer 屬性 ( INSERT 操作對應(yīng)的undo日志沒有該屬性,因為該記錄并沒有更早的版本),可以將這些 undo日志 都連起來,串成一個鏈表:

對該記錄每次更新后,都會將舊值放到一條 undo日志 中,就算是該記錄的一個舊版本,隨著更新次數(shù) 的增多,所有的版本都會被 roll_pointer 屬性連接成一個鏈表,我們把這個鏈表稱之為 版本鏈 ,版本鏈的頭節(jié)點(diǎn)就是當(dāng)前記錄最新的值。

每個版本中還包含生成該版本時對應(yīng)的事務(wù)id。

判斷規(guī)則

在創(chuàng)建 Read View 后,我們可以將記錄中的 trx_id 劃分這三種情況:

一個事務(wù)去訪問記錄的時候,除了自己的更新記錄總是可見之外,還有這幾種判斷規(guī)則:

  • 如果被訪問表行記錄的 trx_id 值與ReadView中的 creator_trx_id 值相同,意味著當(dāng)前事務(wù)在訪問它自己修改過的記錄,所以該版本可以被當(dāng)前事務(wù)訪問,該版本的記錄對當(dāng)前事務(wù)可見。
  • 如果被訪問表行記錄的 trx_id 值小于 Read View 中的 min_trx_id,表示這個版本的記錄是在創(chuàng)建 Read View 已經(jīng)提交的事務(wù)生成的,所以該版本的記錄對當(dāng)前事務(wù)可見。
  • 如果被訪問表行記錄的 trx_id 值大于等于 Read View 中的 max_trx_id,表示這個版本的記錄是在創(chuàng)建 Read View 才啟動的事務(wù)生成的,所以該版本的記錄對當(dāng)前事務(wù)不可見。
  • 如果被訪問表行記錄的 trx_id 值在 Read View 的 min_trx_idmax_trx_id 之間,需要判斷 trx_id 是否在 m_ids 列表中:
    • 如果表行記錄的 trx_id 在 m_ids 列表中,表示生成該版本記錄的活躍事務(wù)依然活躍著(還沒提交事務(wù)),所以該版本的記錄對當(dāng)前事務(wù)不可見。
    • 如果表行記錄的 trx_id 不在 m_ids列表中,表示生成該版本記錄的活躍事務(wù)已經(jīng)被提交,所以該版本的記錄對當(dāng)前事務(wù)可見

判斷方法

判斷方法是先根據(jù) Read View 中的 4 個重要字段,先去 Undo Log 中最新的數(shù)據(jù)行進(jìn)行比對,如果滿足下面 Read View 的判斷規(guī)則中的可見規(guī)則,則返回當(dāng)前行的數(shù)據(jù),如果不滿足則繼續(xù)從Undo Log 鏈中查找當(dāng)前行的數(shù)據(jù)的下一個歷史版本數(shù)據(jù),直到找到滿足的條件的數(shù)據(jù)為止,如果查詢完Undolog版本鏈,發(fā)現(xiàn)沒有滿足條件的數(shù)據(jù),則返回 NULL。

可重復(fù)讀是如何工作的?

可重復(fù)讀隔離級別是啟動事務(wù)時生成一個 Read View,然后整個事務(wù)期間都在用這個 Read View

假設(shè)事務(wù) A (事務(wù) id 為51)啟動后,緊接著事務(wù) B (事務(wù) id 為52)也啟動了,那這兩個事務(wù)創(chuàng)建的 Read View 如下:

事務(wù) A 和 事務(wù) B 的 Read View 具體內(nèi)容如下:

  • 在事務(wù) A 的 Read View 中,它的事務(wù) id 是 51,由于它是第一個啟動的事務(wù),所以此時活躍事務(wù)的事務(wù) id 列表就只有 51,活躍事務(wù)的事務(wù) id 列表中最小的事務(wù) id 是事務(wù) A 本身,下一個事務(wù) id 則是 52。
  • 在事務(wù) B 的 Read View 中,它的事務(wù) id 是 52,由于事務(wù) A 是活躍的,所以此時活躍事務(wù)的事務(wù) id 列表是 51 和 52,活躍的事務(wù) id 中最小的事務(wù) id 是事務(wù) A,下一個事務(wù) id 應(yīng)該是 53。

接著,在可重復(fù)讀隔離級別下,事務(wù) A 和事務(wù) B 按順序執(zhí)行了以下操作:

  • 事務(wù) B 讀取小林的賬戶余額記錄,讀到余額是 100 萬;
  • 事務(wù) A 將小林的賬戶余額記錄修改成 200 萬,并沒有提交事務(wù);
  • 事務(wù) B 讀取小林的賬戶余額記錄,讀到余額還是 100 萬;
  • 事務(wù) A 提交事務(wù);
  • 事務(wù) B 讀取小林的賬戶余額記錄,讀到余額依然還是 100 萬;

接下來,跟大家具體分析下。

事務(wù) B 第一次讀小林的賬戶余額記錄,在找到記錄后,它會先看這條記錄的 trx_id,此時發(fā)現(xiàn) trx_id 為 50,比事務(wù) B 的 Read View 中的 min_trx_id 值(51)還小,這意味著修改這條記錄的事務(wù)早就在事務(wù) B 啟動前提交過了,所以該版本的記錄對事務(wù) B 可見的,也就是事務(wù) B 可以獲取到這條記錄。

接著,事務(wù) A 通過 update 語句將這條記錄修改了(還未提交事務(wù)),將小林的余額改成 200 萬,這時 MySQL 會記錄相應(yīng)的 undo log,并以鏈表的方式串聯(lián)起來,形成版本鏈,如下圖:

你可以在上圖的「記錄的字段」看到,由于事務(wù) A 修改了該記錄,以前的記錄就變成舊版本記錄了,于是最新記錄和舊版本記錄通過鏈表的方式串起來,而且最新記錄的 trx_id 是事務(wù) A 的事務(wù) id(trx_id = 51)。

然后事務(wù) B 第二次去讀取該記錄,發(fā)現(xiàn)這條記錄的 trx_id 值為 51,在事務(wù) B 的 Read View 的 min_trx_id 和 max_trx_id 之間,則需要判斷 trx_id 值是否在 m_ids 范圍內(nèi),判斷的結(jié)果是在的,那么說明這條記錄是被還未提交的事務(wù)修改的,這時事務(wù) B 并不會讀取這個版本的記錄。而是沿著 undo log 鏈條往下找舊版本的記錄,直到找到 trx_id 「小于」事務(wù) B 的 Read View 中的 min_trx_id 值的第一條記錄,所以事務(wù) B 能讀取到的是 trx_id 為 50 的記錄,也就是小林余額是 100 萬的這條記錄。

最后,當(dāng)事物 A 提交事務(wù)后,由于隔離級別時「可重復(fù)讀」,所以事務(wù) B 再次讀取記錄時,還是基于啟動事務(wù)時創(chuàng)建的 Read View 來判斷當(dāng)前版本的記錄是否可見。所以,即使事物 A 將小林余額修改為 200 萬并提交了事務(wù), 事務(wù) B 第三次讀取記錄時,讀到的記錄都是小林余額是 100 萬的這條記錄

就是通過這樣的方式實現(xiàn)了,「可重復(fù)讀」隔離級別下在事務(wù)期間讀到的記錄都是事務(wù)啟動前的記錄。

讀提交是如何工作的?

讀提交隔離級別是在每次讀取數(shù)據(jù)時,都會生成一個新的 Read View

也意味著,事務(wù)期間的多次讀取同一條數(shù)據(jù),前后兩次讀的數(shù)據(jù)可能會出現(xiàn)不一致,因為可能這期間另外一個事務(wù)修改了該記錄,并提交了事務(wù)。

那讀提交隔離級別是怎么工作呢?我們還是以前面的例子來聊聊。

假設(shè)事務(wù) A (事務(wù) id 為51)啟動后,緊接著事務(wù) B (事務(wù) id 為52)也啟動了,接著按順序執(zhí)行了以下操作:

  • 事務(wù) B 讀取數(shù)據(jù)(創(chuàng)建 Read View),小林的賬戶余額為 100 萬;
  • 事務(wù) A 修改數(shù)據(jù)(還沒提交事務(wù)),將小林的賬戶余額從 100 萬修改成了 200 萬;
  • 事務(wù) B 讀取數(shù)據(jù)(創(chuàng)建 Read View),小林的賬戶余額為 100 萬;
  • 事務(wù) A 提交事務(wù);
  • 事務(wù) B 讀取數(shù)據(jù)(創(chuàng)建 Read View),小林的賬戶余額為 200 萬;

那具體怎么做到的呢?我們重點(diǎn)看事務(wù) B 每次讀取數(shù)據(jù)時創(chuàng)建的 Read View。前兩次 事務(wù) B 讀取數(shù)據(jù)時創(chuàng)建的 Read View 如下圖:

我們來分析下為什么事務(wù) B 第二次讀數(shù)據(jù)時,讀不到事務(wù) A (還未提交事務(wù))修改的數(shù)據(jù)?

事務(wù) B 在找到小林這條記錄時,會看這條記錄的 trx_id 是 51,在事務(wù) B 的 Read View 的 min_trx_id 和 max_trx_id 之間,接下來需要判斷 trx_id 值是否在 m_ids 范圍內(nèi),判斷的結(jié)果是在的,那么說明這條記錄是被還未提交的事務(wù)修改的,這時事務(wù) B 并不會讀取這個版本的記錄。而是,沿著 undo log 鏈條往下找舊版本的記錄,直到找到 trx_id 「小于」事務(wù) B 的 Read View 中的 min_trx_id 值的第一條記錄,所以事務(wù) B 能讀取到的是 trx_id 為 50 的記錄,也就是小林余額是 100 萬的這條記錄。

我們來分析下為什么事務(wù) A 提交后,事務(wù) B 就可以讀到事務(wù) A 修改的數(shù)據(jù)?

在事務(wù) A 提交后,由于隔離級別是「讀提交」,所以事務(wù) B 在每次讀數(shù)據(jù)的時候,會重新創(chuàng)建 Read View,此時事務(wù) B 第三次讀取數(shù)據(jù)時創(chuàng)建的 Read View 如下:

事務(wù) B 在找到小林這條記錄時,會發(fā)現(xiàn)這條記錄的 trx_id 是 51,比事務(wù) B 的 Read View 中的 min_trx_id 值(52)還小,這意味著修改這條記錄的事務(wù)早就在創(chuàng)建 Read View 前提交過了,所以該版本的記錄對事務(wù) B 是可見的

正是因為在讀提交隔離級別下,事務(wù)每次讀數(shù)據(jù)時都重新創(chuàng)建 Read View,那么在事務(wù)期間的多次讀取同一條數(shù)據(jù),前后兩次讀的數(shù)據(jù)可能會出現(xiàn)不一致,因為可能這期間另外一個事務(wù)修改了該記錄,并提交了事務(wù)。

可重復(fù)讀事務(wù)隔離級別下使用MVCC可能發(fā)生幻讀現(xiàn)象的場景有哪些?

1. 快照讀和當(dāng)前讀穿插的場景下使用MVCC依舊會發(fā)生幻讀

當(dāng)?shù)谝粋€事務(wù)如果先使用快照讀來讀取范圍數(shù)據(jù),讀取期間第二個事務(wù)對這個范圍進(jìn)行插入數(shù)據(jù)的操作,然后第一個事務(wù)又使用當(dāng)前讀來讀取這個范圍的數(shù)據(jù),此時就會出現(xiàn)幻讀問題。

例如如下場景:

  1. T1 時刻:事務(wù) A 先執(zhí)行「快照讀語句」:select * from t_test where id > 100 得到了 3 條記錄。
  2. T2 時刻:事務(wù) B 往插入一個 id= 200 的記錄并提交;
  3. T3 時刻:事務(wù) A 再執(zhí)行「當(dāng)前讀語句」 select * from t_test where id > 100 for update 就會得到 4 條記錄,此時也發(fā)生了幻讀現(xiàn)象。

要避免這類特殊場景下發(fā)生幻讀的現(xiàn)象的話,就是盡量在開啟事務(wù)之后,馬上執(zhí)行 select ... for update 這類當(dāng)前讀的語句,因為它會對記錄加 next-key lock,從而避免其他事務(wù)插入一條新記錄。

http://aloenet.com.cn/news/44186.html

相關(guān)文章:

  • tomcat做網(wǎng)站站長之家查詢的網(wǎng)址
  • 十堰微網(wǎng)站建設(shè)淘寶自動推廣軟件
  • 淘寶客做的比較好的網(wǎng)站友情鏈接有哪些作用
  • 網(wǎng)站中的圖片必須用 做嗎網(wǎng)站建設(shè)純免費(fèi)官網(wǎng)
  • 個人網(wǎng)站怎么建設(shè)關(guān)鍵詞分為哪幾類
  • 網(wǎng)站策劃怎么做內(nèi)容環(huán)球軍事網(wǎng)
  • 網(wǎng)站制作怎樣做背景常用的網(wǎng)絡(luò)推廣方法有
  • 旅游網(wǎng)站建設(shè)系統(tǒng)百度一下官網(wǎng)頁
  • 企業(yè)做網(wǎng)站設(shè)計百度seo營銷推廣
  • 如何自己做網(wǎng)站一年賺一億東莞推廣公司
  • cms 開源持續(xù)優(yōu)化疫情防控舉措
  • 買了兩臺服務(wù)器可以做網(wǎng)站嗎濟(jì)南優(yōu)化網(wǎng)頁
  • 用織夢做的網(wǎng)站怎么上傳虛擬網(wǎng)絡(luò)營銷的實現(xiàn)方式有哪些
  • 營銷助手appseo網(wǎng)絡(luò)營銷的技術(shù)
  • 建一個網(wǎng)站邁年廣州白云區(qū)最新信息
  • 啥是深圳網(wǎng)站建設(shè)com域名多少錢一年
  • 金融公司網(wǎng)站開發(fā)汕頭seo計費(fèi)管理
  • 生活做爰網(wǎng)站北京seo優(yōu)化wyhseo
  • 國家安全人民防線建設(shè)網(wǎng)站如何在網(wǎng)上推廣產(chǎn)品
  • wordpress如何發(fā)布視頻seo搜索引擎工具
  • wordpress+站群軟件東莞網(wǎng)絡(luò)推廣營銷公司
  • 關(guān)注網(wǎng)站制作seo診斷
  • 中小企業(yè)建站模板百度免費(fèi)發(fā)布信息
  • 石巖小學(xué)網(wǎng)站建設(shè)網(wǎng)絡(luò)營銷策劃書的主要內(nèi)容
  • 石家莊網(wǎng)站開發(fā)設(shè)計百度網(wǎng)站下載
  • 做甜品網(wǎng)站的需求分析網(wǎng)站如何發(fā)布
  • 如何給網(wǎng)站做流量百度推廣網(wǎng)址是多少
  • 網(wǎng)站域名使用費(fèi)多少網(wǎng)絡(luò)營銷與直播電商學(xué)什么
  • 武漢電商網(wǎng)站建設(shè)sem是什么設(shè)備
  • 世界十大建筑設(shè)計公司排名外鏈seo推廣