Mysql InnoDB行鎖實現方式

來源:互聯網
上載者:User

標籤:update   ica   設計   方式   engine   comm   dex   相同   需要   

Mysql InnoDB行鎖實現方式

 InnoDB行鎖是通過給索引上的索引項目加鎖來實現的,這一點MySQL與Oracle不同,後者是通過在資料區塊中對相應資料行加鎖來實現的。InnoDB這種行鎖實現特點意味著:只有通過索引條件檢索資料,InnoDB才使用行級鎖,否則,InnoDB將使用表鎖! 在實際應用中,要特別注意InnoDB行鎖的這一特性,不然的話,可能導致大量的鎖衝突,從而影響並發效能。下面通過一些實際例子來加以說明。(1)在不通過索引條件查詢的時候,InnoDB確實使用的是表鎖,而不是行鎖。 在如表20-9所示的例子中,開始tab_no_index表沒有索引:mysql> create table tab_no_index(id int,name varchar(10)) engine=innodb;Query OK, 0 rows affected (0.15 sec)mysql> insert into tab_no_index values(1,‘1‘),(2,‘2‘),(3,‘3‘),(4,‘4‘);Query OK, 4 rows affected (0.00 sec)Records: 4  Duplicates: 0  Warnings: 0表20-9         InnoDB儲存引擎的表在不使用索引時使用表鎖例子  www.2cto.com  session_1session_2mysql> set autocommit=0;Query OK, 0 rows affected (0.00 sec)mysql> select * from tab_no_index where id = 1 ;+------+------+| id   | name |+------+------+| 1    | 1    |+------+------+1 row in set (0.00 sec)mysql> set autocommit=0;Query OK, 0 rows affected (0.00 sec)mysql> select * from tab_no_index where id = 2 ;+------+------+| id   | name |+------+------+| 2    | 2    |+------+------+1 row in set (0.00 sec)mysql> select * from tab_no_index where id = 1 for update;+------+------+| id   | name |+------+------+| 1    | 1    |+------+------+1 row in set (0.00 sec)   www.2cto.com  mysql> select * from tab_no_index where id = 2 for update;等待在如表20-9所示的例子中,看起來session_1隻給一行加了獨佔鎖定,但session_2在請求其他行的獨佔鎖定時,卻出現了鎖等待!原因就是在沒有索引的情況下,InnoDB只能使用表鎖。當我們給其增加一個索引後,InnoDB就只鎖定了合格行,如表20-10所示。 建立tab_with_index表,id欄位有普通索引: mysql> create table tab_with_index(id int,name varchar(10)) engine=innodb;Query OK, 0 rows affected (0.15 sec)mysql> alter table tab_with_index add index id(id);Query OK, 4 rows affected (0.24 sec)Records: 4  Duplicates: 0  Warnings: 0表20-10    InnoDB儲存引擎的表在使用索引時使用行鎖例子  www.2cto.com  session_1session_2mysql> set autocommit=0;Query OK, 0 rows affected (0.00 sec)mysql> select * from tab_with_index where id = 1 ;+------+------+| id   | name |+------+------+| 1    | 1    |+------+------+1 row in set (0.00 sec)mysql> set autocommit=0;Query OK, 0 rows affected (0.00 sec)mysql> select * from tab_with_index where id = 2 ;+------+------+| id   | name |+------+------+| 2    | 2    |+------+------+1 row in set (0.00 sec)mysql> select * from tab_with_index where id = 1 for update;+------+------+| id   | name |+------+------+| 1    | 1    |+------+------+1 row in set (0.00 sec) mysql> select * from tab_with_index where id = 2 for update;+------+------+| id   | name |+------+------+| 2    | 2    |+------+------+1 row in set (0.00 sec)(2)由於MySQL的行鎖是針對索引加的鎖,不是針對記錄加的鎖,所以雖然是訪問不同行的記錄,但是如果是使用相同的索引鍵,是會出現鎖衝突的。應用設計的時候要注意這一點。 在如表20-11所示的例子中,表tab_with_index的id欄位有索引,name欄位沒有索引: mysql> alter table tab_with_index drop index name;Query OK, 4 rows affected (0.22 sec)Records: 4  Duplicates: 0  Warnings: 0mysql> insert into tab_with_index  values(1,‘4‘);Query OK, 1 row affected (0.00 sec)mysql> select * from tab_with_index where id = 1;+------+------+| id   | name |+------+------+| 1    | 1    || 1    | 4    |+------+------+2 rows in set (0.00 sec)表20-11    InnoDB儲存引擎使用相同索引鍵的阻塞例子  www.2cto.com  session_1session_2mysql> set autocommit=0;Query OK, 0 rows affected (0.00 sec)mysql> set autocommit=0;Query OK, 0 rows affected (0.00 sec)mysql> select * from tab_with_index where id = 1 and name = ‘1‘ for update;+------+------+| id   | name |+------+------+| 1    | 1    |+------+------+1 row in set (0.00 sec) 雖然session_2訪問的是和session_1不同的記錄,但是因為使用了相同的索引,所以需要等待鎖:mysql> select * from tab_with_index where id = 1 and name = ‘4‘ for update;等待(3)當表有多個索引的時候,不同的事務可以使用不同的索引鎖定不同的行,另外,不論是使用主鍵索引、唯一索引或普通索引,InnoDB都會使用行鎖來對資料加鎖。  www.2cto.com  在如表20-12所示的例子中,表tab_with_index的id欄位有主鍵索引,name欄位有普通索引: mysql> alter table tab_with_index add index name(name);Query OK, 5 rows affected (0.23 sec)Records: 5  Duplicates: 0  Warnings: 0表20-12    InnoDB儲存引擎的表使用不同索引的阻塞例子 ·          session_1·          session_2mysql> set autocommit=0;Query OK, 0 rows affected (0.00 sec)mysql> set autocommit=0;Query OK, 0 rows affected (0.00 sec)mysql> select * from tab_with_index where id = 1 for update;+------+------+| id   | name |+------+------+| 1    | 1    || 1    | 4    |+------+------+2 rows in set (0.00 sec)   www.2cto.com  Session_2使用name的索引訪問記錄,因為記錄沒有被索引,所以可以獲得鎖:mysql> select * from tab_with_index where name = ‘2‘ for update;+------+------+| id   | name |+------+------+| 2    | 2    |+------+------+1 row in set (0.00 sec) 由於訪問的記錄已經被session_1鎖定,所以等待獲得鎖。:mysql> select * from tab_with_index where name = ‘4‘ for update;(4)即便在條件中使用了索引欄位,但是否使用索引來檢索資料是由MySQL通過判斷不同執行計畫的代價來決定的,如果MySQL認為全表掃描效率更高,比如對一些很小的表,它就不會使用索引,這種情況下InnoDB將使用表鎖,而不是行鎖。因此,在分析鎖衝突時,別忘了檢查SQL的執行計畫,以確認是否真正使用了索引。關於MySQL在什麼情況下不使用索引的詳細討論,參見本章“索引問題”一節的介紹。  www.2cto.com  在下面的例子中,檢索值的資料類型與索引欄位不同,雖然MySQL能夠進行資料類型轉換,但卻不會使用索引,從而導致InnoDB使用表鎖。通過用explain檢查兩條SQL的執行計畫,我們可以清楚地看到了這一點。 例子中tab_with_index表的name欄位有索引,但是name欄位是varchar類型的,如果where條件中不是和varchar類型進行比較,則會對name進行類型轉換,而執行的全表掃描。 mysql> alter table tab_no_index add index name(name);Query OK, 4 rows affected (8.06 sec)Records: 4  Duplicates: 0  Warnings: 0mysql> explain select * from tab_with_index where name = 1 \G*************************** 1. row ***************************id: 1select_type: SIMPLEtable: tab_with_indextype: ALLpossible_keys: namekey: NULLkey_len: NULLref: NULLrows: 4Extra: Using where1 row in set (0.00 sec)mysql> explain select * from tab_with_index where name = ‘1‘ \G*************************** 1. row ***************************id: 1  www.2cto.com  select_type: SIMPLEtable: tab_with_indextype: refpossible_keys: namekey: namekey_len: 23ref: constrows: 1Extra: Using where1 row in set (0.00 sec)

Mysql InnoDB行鎖實現方式

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.