MySQL索引的講解

2021-09-20 18:53:41 字數 2999 閱讀 5858

mysql 的鎖按照範圍可以分為全域性鎖、表鎖、行鎖,其中行鎖是由資料庫引擎實現的,並不是所有的引擎都提供行鎖,myisam 就不支援行鎖,所以文章介紹行鎖會以innodb引擎為例來介紹行鎖。

mysql 提供全域性鎖來對整個資料庫例項加鎖。

語法:

flush tables with read lock
這條語句一般都是用來備份的,當執行這條語句後,資料庫所有開啟的表都會被關閉,並且使用全域性讀鎖鎖定資料庫的所有表,同時,其他執行緒的更新語句(增刪改),資料定義語句(建表,修改表結構)和更新類的事務提交都會被阻塞。

在mysql 8.0 以後,對於備份,mysql可以直接使用備份鎖。

語句:

lock instance for backup

unlock instance

這個鎖的作用範圍更廣,這個鎖會阻止檔案的建立,重新命名,刪除,包括repair table truncate table, optimize table操作以及賬戶的管理都會被阻塞。當然這些操作對於記憶體臨時表來說是可以執行的,為什麼記憶體表不受這些限制呢?因為記憶體表不需要備份,所以也就沒必要滿足這些條件。

mysql的表級別鎖分為兩類,一類是元資料鎖(metadata lock,mdl),一種是表鎖。

元資料鎖(mdl)不需要顯式使用,在訪問乙個表的時候會被自動加上。這個特性需要mysql5.5版本以上才會支援,當對乙個表做增刪改查的時候,該錶會被加mdl讀鎖;當對表做結構變更的時候,加mdl寫鎖。mdl鎖有一些規則:

所以我們在運算元據庫表結構時候必須要注意不要使用長事務,這裡具體是什麼意思呢?我舉個例子說明下:

上圖表示演示了4個session執行語句,首先sessiona開啟了事務沒有提交,接著sessionb執行查詢,因為是獲取mdl讀鎖,所以互相不影響,可以正常執行,sessionc新增乙個字段,由於mdl寫和讀是互斥的,所以sessionc會被阻塞,之後sessiond開始執行乙個查詢語句,由於sessionc的阻塞,所以sessiond也阻塞了。所以,我們模擬的sessiona的事務是長事務,然後後面執行了修改表結構,會導致後續對該錶所有的讀寫操作都不可行了。所以在實際場景中,如果業務請求比較頻繁的時候,對錶結構進行修改的時候就有可能導致該庫的執行緒被阻塞滿。

表鎖的語法如下:

lock tables

tbl_name [[as] alias] lock_type

[, tbl_name [[as] alias] lock_type] ...

lock_type:

unlock tables

表鎖分為讀鎖和寫鎖,讀鎖不互斥,但是獲取讀鎖不能寫入資料,其他沒有獲取到讀鎖的session也是可以讀取表的,所以讀鎖的目的就是限制表被寫。如果表被讀鎖鎖住後,再執行插入語句會報錯,報錯如下:

1099 - table '***x' was locked with a read lock and can't be updated
寫鎖被獲取後可以對錶進行讀寫,寫鎖是互斥的,一旦某個session獲取到表的寫鎖,另外的session無法訪問這個表,直到寫鎖被釋放。

表的解鎖可以使用unlock tables解鎖,也可以客戶端口自動解鎖。lock tables鎖表會獨佔式的鎖住表,除了限制其他執行緒對該錶的讀寫,也會限制本執行緒接下來的操作物件。

mysql的行鎖是在引擎層面實現的,所以這裡討論的也是innodb引擎下的行鎖,下面會詳細介紹innodb下常見的幾種行鎖

共享鎖能允許事務獲取到鎖後進行讀操作,共享鎖是不互斥的,乙個事務獲取到共享鎖後,另外乙個事務也可以獲取共享鎖,獲取共享鎖後不能進行寫操作。

排他鎖允許事務獲取到鎖後進行更新一行或者刪除某一行操作,排他鎖顧名思義是互斥的,乙個事務獲取到排他鎖後,其他事務不能獲取到排他鎖,直到這個鎖被釋放。

innodb支援多種粒度的鎖,允許行鎖和表鎖共存,這裡說的意向鎖其實是一種表級別的鎖,但是我把它放在行鎖裡面是因為它不會單獨存在,它的出現肯定會伴隨著行鎖(共享鎖或者排他鎖),它主要的目的就是表示將要鎖定表中的行或者正在鎖定表中的行。

意向鎖根據和行鎖的組合可以分為:

意向鎖的獲取必須在行鎖獲取之前,也就是說獲取共享鎖之前必須先要獲取共享意向鎖,對於排他鎖也是一樣的道理。

那麼這個意向鎖到底有什麼作用呢?

解釋這個之前,我們先看看意向鎖和行鎖之前的相容關係:

---排他鎖(x)

意向排他鎖(ix)

共享鎖(s)

意向共享鎖(is)

排他鎖(x)

衝突衝突

衝突衝突

意向排他鎖(ix)

衝突相容

衝突相容

共享鎖(s)

衝突衝突

相容相容

意向共享鎖(is)

衝突相容

相容相容

我們假設有2個事務a和事務b,事務獲取到了共享鎖,鎖住了表中的某一行,這一行只能讀,不能寫,現在事務b要申請整個表的寫鎖。如果事務b申請成功,那麼肯定是可以對錶中所有的行進行寫操作的,那麼肯定與a獲取的行鎖衝突。資料庫為了避免這種衝突,就會進行衝突檢測,那麼如何去檢測呢?有兩種方式:

判斷表中的每一行需要遍歷所有記錄,效率太差,所以資料庫就用第一種方式去做衝突檢測,也就是用到了意向鎖。

本文主要從mysql的加鎖範圍來分析了mysql的鎖,mysql根據加鎖範圍可以分為全域性鎖、表鎖、行鎖。全域性鎖和表鎖是mysql自己實現,行鎖都是由引擎層面去實現。innodb下的行鎖主要分為共享鎖和排他鎖。共享鎖請求後,行只能讀,共享鎖之間不互斥。排他鎖獲取後能更新和刪除行,排他鎖與其他鎖都互斥。最後我在行鎖的基礎上提到了意向鎖,意向鎖主要表示正在鎖住行或者即將鎖住行,為了在鎖衝突檢測中提高效率。當然innodb下還有其他鎖,比如間隙鎖,記錄鎖,next-key鎖等,這些都不在本文的**範圍之內,如有興趣的同學可以自行研究。

MySQL 索引講解

索引是幫助mysql高效獲取資料的排好序的資料結構。索引的資料結構 索引的節點儲存的是key 索引列欄位 value 行資料磁碟檔案的位址指標 從索引表中找的時候,都是從根節點去找。二叉樹的資料結構 採取二分查詢的思想,o logn 的複雜度就可以完成對資料的查詢任務,查詢所需的最大次數等同於二叉樹...

Mysql索引的使用 詳細講解

1.索引的簡介 索引是對資料庫表中一列或多列的值進行排序的一種結構,使用索引可以提高資料庫中特定資料的查詢速度。2.索引的含義和特點 索引是乙個單獨的 儲存再磁碟上的資料庫結構,它們包含著對資料表裡所有記錄的引用指標。2.1索引的儲存引擎 索引是在儲存引擎中實現的,因此,每種儲存引擎的索引都不一定完...

Mysql索引的使用 詳細講解

1.索引的簡介 索引是對資料庫表中一列或多列的值進行排序的一種結構,使用索引可以提高資料庫中特定資料的查詢速度。2.索引的含義和特點 索引是乙個單獨的 儲存再磁碟上的資料庫結構,它們包含著對資料表裡所有記錄的飲用指標。2.1索引的儲存引擎 索引是在儲存引擎中實現的,因此,每種儲存引擎的索引都不一定完...