mysql myisam的鎖機制

賀子_DBA時代發表於2018-03-23
首先我們知道MySQL支援多種引擎,並且不同儲存引擎有很多不同,最重要的
即便是自動提交模式下 當start transaction;之後,必須要顯現的commit;才能釋放鎖資源,
myisam的鎖機制:
不支援行級鎖,支援的是表級鎖,分為共享讀鎖和獨佔寫鎖。
1)什麼是表鎖
表鎖:操作物件是資料表。Mysql大多數鎖策略都支援(常見mysql innodb),是系統開銷最低但併發性最低的一個鎖策略。事務t對整個表加讀鎖,則其他事務可讀不可寫,若加寫鎖,則其他事務增刪改都不行
2)什麼是讀鎖
 讀鎖:也叫共享鎖、S鎖,若事務T對錶A加上S鎖,則事務T可以讀表A但不能修改表A,其他事務只能再對錶A加S鎖,而不能加X鎖,直到T釋放A上的S 鎖。這保證了其他事務可以讀表A,但在事務T釋放表A上的S鎖之前不能對錶A做任何修改,總結起來就是:我讀的時候你不能寫;
3)什麼是寫鎖
寫鎖:又稱排他鎖、X鎖。若事務T對錶A加上X鎖,事務T可以讀表A也可以修改表A,其他事務不能再對錶A加任何鎖,直到事務T釋放表A上的鎖。這保證了其他事務在事務T釋放表A上的鎖之前不能再讀取和修改表A,總結起來就是:我寫的時候,你不能讀,也不能寫。
實驗一:我讀的時候你不能寫,但是你可以讀;
首先表company_info是myisam引擎的表;
事務1,執行長時間的查詢操作
mysql> select company_id from company_info where company_name like '%liluwedafasdf%';
Empty set (43.27 sec)
事務2,嘗試更新表company_info ,發現等待。。。執行了21秒。
mysql>update company_info set company_name='liuhehhe' where company_id='4028809f60bf40fd0160bf4678be0000';
+----------------------------------+--------------+
| company_id | company_name |
+----------------------------------+--------------+
| 4028809f60bf40fd0160bf4678be0000 | liuhehhe |
+----------------------------------+--------------+
Query OK, 0 rows affected(21.98 sec)
Rows matched: 1 Changed: 0 Warnings: 0
再開啟一個視窗,可以看到,事務2確實在等待一個表級別的鎖:
mysql> show processlist;
+----+------+-----------+----------+---------+------+------------------------------+------------------------------------------------------------------------------------------------------+
| Id | User | Host | db | Command | Time | State | Info |
+----+------+-----------+----------+---------+------+------------------------------+------------------------------------------------------------------------------------------------------+
| 14 | root | localhost | liuwenhe | Sleep | 4506 | | NULL |
| 15 | root | localhost | liuwenhe | Query | 1 | Sending data | select company_id from company_info where company_name like '%liluwedafasdf%' |
| 16 | root | localhost | liuwenhe | Query | 1 |Waiting for table level lock| update company_info set company_name='liuhehhe' where company_id='4028809f60bf40fd0160bf4678be0000 |
| 17 | root | localhost | NULL | Query | 0 | init | show processlist |
+----+------+-----------+----------+---------+------+------------------------------+------------------------------------------------------------------------------------------------------+
4 rows in set (0.00 sec)
然後再開啟一個視窗,執行查詢操作(事務3):發現事務1還沒有執行完,事務3就執行完了,說明事務1不會阻塞事務3;
mysql> select company_name from company_info where company_id='4028809f60bf40fd0160bf4678be0000';
+--------------+
| company_name |
+--------------+
| liuhehhe |
+--------------+
1 row in set (2.10 sec)
實驗一證明:事務1對錶A加上S鎖,則事務1可以讀表A但不能修改表A,其他事務只能再對錶A加S鎖,而不能加X鎖,直到T釋放A上的S 鎖。也就是說我讀的時候你不能寫,但是你可以讀;
實驗二:我寫的時候,你不能讀,也不能寫;
事務1:執行更新一個表的一個欄位。
mysql> update company_info set company_name='liuhehhe' where company_name like '%liuwehe%';
Query OK, 0 rows affected (1.95 sec)
Rows matched: 0 Changed: 0 Warnings: 0
事務2嘗試查詢這個表,發現等待。。
mysql> select count(*) from company_info;
+----------+
| count(*) |
+----------+
| 1818708 |
+----------+
1 row in set (1.11 sec)
再開啟一個視窗,檢視程式,發現事務2確實在等待一個表級別的鎖;
mysql> show processlist;
+----+------+-----------+----------+---------+------+------------------------------+----------------------------------------------------------------------------------------+
| Id | User | Host | db | Command | Time | State | Info |
+----+------+-----------+----------+---------+------+------------------------------+----------------------------------------------------------------------------------------+
| 19 | root | localhost | liuwenhe | Query | 1 | updating | update company_info set company_name='liuhehhe' where company_name like '%liuwehe%' |
| 20 | root | localhost | liuwenhe | Query | 1 |Waiting for table level lock| select count(*) from company_info |
| 21 | root | localhost | NULL | Query | 0 | init | show processlist |
+----+------+-----------+----------+---------+------+------------------------------+----------------------------------------------------------------------------------------+
3 rows in set (0.00 sec)
實驗二證明:mysql的myisam引擎下,更新表的一行資料,也會上一個表級別的鎖排他鎖,不允許其他事務讀取該表的資料,當然也不允許其他事務去寫這個表,也就是說:我寫的時候,你不能讀,也不能寫;
mysql myisam的鎖小結:
MyISAM的讀操作和寫操作,以及寫操作之間是序列的!MyISAM在執行讀寫操作的時候會自動給表加相應的鎖(也就是說不用顯示的使用lock table命令,然後注意是表級別的鎖),MyISAM總是一次獲得SQL語句所需要的全部鎖,這也是MyISAM不會出現死鎖的原因.區別於mysql innodb的鎖機制,innodb的一般的select 是不會加任何鎖的,接下來會介紹innodb的鎖機制,請看下一篇文章

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29654823/viewspace-2152158/,如需轉載,請註明出處,否則將追究法律責任。

相關文章