MYSQL加鎖的測驗

MYSQL加鎖的測驗

 

 存儲引擎  支持的鎖定級別 

myisam      表級別 

memory     表級別 

  inndb       行級別 

 bdb:        頁級別 

 

lock鎖定類型

 鎖定方式            目的

 讀鎖                   自己與其他線程只能讀取該表

  寫鎖                  只有當前線程能夠對錶進行寫入操作(其他線程也無法讀這部分數據)

 

 

讀鎖的英文叫法是shared locks,shared是共享的意思,共享鎖,就是所有用戶都可以共享進行讀(包括加鎖的用戶),不能寫。

 

寫鎖的英文叫法是Exclusive Locks,Exclusive是獨有、排外的意思,只有自己(加鎖的用戶)才能進行些寫入操作,其他用戶只能讀。有些書籍中有不同叫法,比如互斥鎖、排他鎖。

 

糾正一下:以前理解錯誤了。加了排他鎖定,其他事務是無法讀取數據的。網上的資料比較零散。

最近看了jim Gray那本《事務處理概念與技術》,裏面提到排他鎖時:保留對該節點寫的權利,防止其他事務在該節點及其後代節點加{x,u,s,six,is,ix}鎖。

 

提到的s就是共享鎖了,既然防止其他事務加s鎖,那麼其他線程是無法讀的(所有線程獲取數據之前必須先申請鎖才能操作)。文章下面加的試驗也會證明了這點。

 

ps:看來總結也好,加深了理解,如果不總結,也不會發現細節理解偏差。

 

 

 測試一:測驗讀鎖

 運行一個讀鎖:“lock table `cat` READ”

然後嘗試使用update語句操作 :

update `cat` set remark= 'ceshi'

 

報錯如下:

 

Table 'a' was locked with a READ lock and can't be updated

現在解鎖(針對當前線程鎖定的所有表解鎖):"unlock tables" 

 

然後再次運行update語句,報錯消失。完成更新操作。說明已經解除讀鎖了(可以進行更新) 

 

 測驗二:測驗寫鎖 

1、 我在一個客戶端SQLyog中運行一個寫鎖sql:LOCK TABLE cat WRITE;

2、另外開一個客戶端(線程),嘗試運行更新:

update `cat` set remark= 'jgjgjg'

 

情況:因爲使用了寫鎖,只有自己能夠修改數據,其他線程無法執行update操作,此時服務器端的php程序一直等待數據庫給予響應結果,數據被鎖定了,根本沒法執行sql語句,處於等待中,數據庫並不會報錯,因爲這本來就是一個很正常的情況,需要等待釋放鎖才能執行update操作,其實大併發環境下就是這種情況(很多用戶同時在執行sql操作,有的加了寫鎖定),於是速度就慢下來了。

結果phpmyadmin一直處於等待中,等待服務器給予客戶端(瀏覽器)數據,截圖如下:

 

 

 

 經驗:使用phpmyadmin無法模擬出一個線程的情況。因爲每次php運行完畢後,與數據庫的連接就會自動斷開(php腳本特性)。

而SQLyog這樣的工具能夠保持連接不斷掉。所以,測驗寫鎖的時候完全可以使用同一個工具測驗出來。

 

 

 增加測驗:測驗加寫鎖後,其他事務無法讀數據的情況

同樣也是在SQLyog這樣的工具中運行:LOCK TABLE cat WRITE

 

因爲加了x鎖後,其他事務是無法獲得s鎖,所以根本無法讀數據。phpmyadmin這邊查詢這個表,都是等待狀態。

 


 

 下面我在SQLyog釋放掉寫鎖後,phpmyadmin這邊就能讀取數據了

 



InnoDB使用行鎖定,BDB使用頁鎖定。對於這兩種存儲引擎,都可能存在死鎖。這是因爲,在SQL語句處理期間,InnoDB自動獲得行鎖定和BDB獲得頁鎖定,而不是在事務啓動時獲得。

 

update語句默認比select語句優先權高。可以修改,在啓動mysql的時候加上參數,用--low-priority-updates啓動mysqld 

 

 

在大流量、大數量的網站,往往瓶頸不在於具體的語言,其實.net、java、php等語言速度的差別是有,但是很小,忽略不計。往往瓶頸在於數據庫。我是這樣理解:

 


$conn->query("update where ....");

...php其他代碼

 

//php需要等待數據庫(比如mysql)給予返回結果,才能繼續往下面執行代碼,但裏mysql被鎖定了,一直沒有執行完畢。所以卡死了,一直在等待中。這就是爲什麼語言不是瓶頸,瓶頸往往在數據庫(數據量大的時候,數據庫壓力很大),這就是同步執行,需要等到上面代碼執行完畢才能繼續執行,以前聽過阿里巴巴的分享,使用一種異步執行方案。並行加載數據,那麼代碼的執行耗時取決於最耗時的操作(因爲所有操作都是並行開始運行)


其他測驗辦法:還可以開多個mysql命令行界面來測驗。每個界面就是一個session。


(轉載出處:http://www.cnblogs.com/wangtao_20/p/3463435.html)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章