【MySQL】當前讀、快照讀、MVCC

  • 當前讀:

  select...lock in share mode (共享讀鎖)
  select...for update
  update , delete , inserthtml

  當前讀, 讀取的是最新版本, 而且對讀取的記錄加鎖, 阻塞其餘事務同時改動相同記錄,避免出現安全問題安全

  例如,假設要update一條記錄,可是另外一個事務已經delete這條數據而且commit了,若是不加鎖就會產生衝突。因此update的時候確定要是當前讀,獲得最新的信息而且鎖定相應的記錄。併發

  

  • 當前讀的實現方式:next-key鎖(行記錄鎖+Gap間隙鎖)

   間隙鎖:只有在Read Repeatable、Serializable隔離級別纔有,就是鎖定範圍空間的數據,假設id有3,4,5,鎖定id>3的數據,是指的4,5及後面的數字都會被鎖定,由於此時若是不鎖定沒有的數據,例如當加入了新的數據id=6,就會出現幻讀,間隙鎖避免了幻讀。spa

  1.對主鍵或惟一索引,若是當前讀時,where條件所有精確命中(=或者in),這種場景自己就不會出現幻讀,因此只會加行記錄鎖。指針

  2.沒有索引的列,當前讀操做時,會加全表gap鎖,生產環境要注意。日誌

  3.非惟一索引列,若是where條件部分命中(>、<、like等)或者全未命中,則會加附近Gap間隙鎖。例如,某表數據以下,非惟一索引2,6,9,9,11,15。以下語句要操做非惟一索引列9的數據,gap鎖將會鎖定的列是(6,11],該區間內沒法插入數據。code

 

   

 

  •  快照讀

  單純的select操做,不包括上述 select ... lock in share mode, select ... for update。    htm

  Read Committed隔離級別:每次select都生成一個快照讀。blog

  Read Repeatable隔離級別:開啓事務後第一個select語句纔是快照讀的地方,而不是一開啓事務就快照讀。索引

 

  • 快照讀的實現方式:undolog和多版本併發控制MVCC

  下圖右側綠色的是數據:一行數據記錄,主鍵ID是10,name='Jack',age=10,  被update更新set爲name= 'Tom',age=23。

  事務會先使用「排他鎖」鎖定改行,將該行當前的值複製到undo log中,而後再真正地修改當前行的值,最後填寫事務的DB_TRX_ID,使用回滾指針DB_ROLL_PTR指向undo log中修改前的行DB_ROW_ID

'

  DB_TRX_ID: 6字節DB_TRX_ID字段,表示最後更新的事務id(update,delete,insert)。此外,刪除在內部被視爲更新,其中行中的特殊位被設置爲將其標記爲已軟刪除。

  DB_ROLL_PTR: 7字節回滾指針,指向前一個版本的undolog記錄,組成undo鏈表。若是更新了行,則撤消日誌記錄包含在更新行以前重建行內容所需的信息。
  DB_ROW_ID
6字節的DB_ROW_ID字段,包含一個隨着新行插入而單調遞增的行ID, 當由innodb自動產生彙集索引時,彙集索引會包括這個行ID的值,不然這個行ID不會出如今任何索引中。若是表中沒有主鍵或合適的惟一索引, 也就是沒法生成聚簇索引的時候, InnoDB會幫咱們自動生成彙集索引, 聚簇索引會使用DB_ROW_ID的值來做爲主鍵; 若是表中有主鍵或者合適的惟一索引, 那麼聚簇索引中也就不會包含 DB_ROW_ID了 。  

  其它:insert undo log只在事務回滾時須要, 事務提交就能夠刪掉了。update undo log包括update 和 delete , 回滾和快照讀 都須要。

 

原文出處:https://www.cnblogs.com/wwcom123/p/10727194.html

相關文章
相關標籤/搜索