MySQL 幻象行

當同一個查詢在不一樣的時間產生不一樣的行集時,就會出現所謂的幻像問題。例如,若是執行了兩次SELECT,可是第二次返回了第一次沒有返回的行,那麼該行就是一個「幻象」行。算法

假設在表child的id列上有一個索引,你想讀取並鎖定表中標識符值大於100的全部行,並打算稍後更新所選行的某些列:spa

SELECT * FROM child WHERE id > 100 FOR UPDATE;

該查詢從id大於100的第一個記錄開始掃描索引。假設表包含id值爲90和102的行。若是在掃描範圍內的索引記錄上設置的鎖沒有鎖定在間隙(在本例中是90到102之間的間隙),另外一個會話能夠向表中插入一個id爲101的新行。若是要在同一個事務中執行相同的SELECT,則會在查詢返回的結果集中看到一個id爲101的新行(「幻象」)。這就違反了事務的隔離原則。code

爲了防止出現幻象,InnoDB使用了一種名爲next-key鎖定的算法,它結合了索引行鎖和間隙鎖。InnoDB執行行級鎖的方式是這樣的:當它搜索或掃描一個表索引時,它會在遇到的索引記錄上設置共享鎖或排他鎖。所以,行級鎖其實是索引記錄鎖。此外,索引記錄上的next-key鎖也會影響該索引記錄以前的「間隙」。也就是說,next-key鎖是索引記錄鎖加上索引記錄以前的間隙鎖。若是一個會話在一個索引中的記錄R上有一個共享鎖或排他鎖,另外一個會話不能在緊接在索引順序中的R以前的間隙中插入新的索引記錄。blog

當InnoDB掃描一個索引時,它也能夠鎖定索引中最後一條記錄以後的間隙。就像在前面的例子中發生的那樣:爲了防止插入id大於100的表,InnoDB設置的鎖包括id值102後面的間隙鎖。索引

相關文章
相關標籤/搜索