程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> MYSQL數據庫 >> MySQL綜合教程 >> MySQL行級鎖、表級鎖、頁級鎖具體引見

MySQL行級鎖、表級鎖、頁級鎖具體引見

編輯:MySQL綜合教程

MySQL行級鎖、表級鎖、頁級鎖具體引見。本站提示廣大學習愛好者:(MySQL行級鎖、表級鎖、頁級鎖具體引見)文章只能為提供參考,不一定能成為您想要的結果。以下是MySQL行級鎖、表級鎖、頁級鎖具體引見正文


頁級:引擎 BDB。
表級:引擎 MyISAM , 懂得為鎖住全部表,可以同時讀,寫不可
行級:引擎 INNODB , 零丁的一行記載加鎖

表級,直接鎖定整張表,在你鎖按期間,其它過程沒法對該表停止寫操作。假如你是寫鎖,則其它過程則讀也不許可
行級,,僅對指定的記載停止加鎖,如許其它過程照樣可以對統一個表中的其它記載停止操作。
頁級,表級鎖速度快,但抵觸多,行級抵觸少,但速度慢。所以取了調和的頁級,一次鎖定相鄰的一組記載。

MySQL 5.1支撐對MyISAM和MEMORY表停止表級鎖定,對BDB表停止頁級鎖定,對InnoDB表停止行級鎖定。
對WRITE,MySQL應用的表鎖定辦法道理以下:
假如在表上沒有鎖,在它下面放一個寫鎖。
不然,把鎖定要求放在寫鎖定隊列中。

對READ,MySQL應用的鎖定辦法道理以下:
假如在表上沒有寫鎖定,把一個讀鎖定放在它下面   
不然,把鎖要求放在讀鎖定隊列中。

InnoDB應用行鎖定,BDB應用頁鎖定。關於這兩種存儲引擎,都能夠存在逝世鎖。這是由於,在SQL語句處置時代,InnoDB主動取得行鎖定和BDB取得頁鎖定,而不是在事務啟動時取得。 

行級鎖定的長處:
·         當在很多線程中拜訪分歧的行時只存在大批鎖定抵觸。
·         回滾時只要大批的更改。
·         可以長時光鎖訂單一的行。

行級鎖定的缺陷:
·         比頁級或表級鎖定占用更多的內存。
·         當在表的年夜部門中應用時,比頁級或表級鎖定速度慢,由於你必需獲得更多的鎖。
·         假如你在年夜部門數據上常常停止GROUP BY操作或許必需常常掃描全部表,比其它鎖定顯著慢許多。
·         用高等別鎖定,經由過程支撐分歧的類型鎖定,你也能夠很輕易地調理運用法式,由於其鎖本錢小於行級鎖定。

在以下情形下,表鎖定優先於頁級或行級鎖定:
·         表的年夜部門語句用於讀取。
·         對嚴厲的症結字停止讀取和更新,你可以更新或刪除可以用單一的讀取的症結字來提取的一行:
·                UPDATE tbl_name SET column=value WHERE unique_key_col=key_value;
·                DELETE FROM tbl_name WHERE unique_key_col=key_value;
·         SELECT 聯合並行的INSERT語句,而且只要很少的UPDATE或DELETE語句。
·         在全部表上有很多掃描或GROUP BY操作,沒有任何寫操作。

/* ========================= mysql 鎖表類型息爭鎖語句 ========================= */

假如想要在一個表上做年夜量的 INSERT 和 SELECT 操作,然則並行的拔出卻弗成能時,可以將記載拔出莅臨時表中,然後按期將暫時表中的數據更新到現實的內外。可以用以下敕令完成:

mysql> LOCK TABLES real_table WRITE, insert_table WRITE;
mysql> INSERT INTO real_table SELECT * FROM insert_table;
mysql> TRUNCATE TABLE insert_table;
mysql> UNLOCK TABLES;

行級鎖的長處有:
 在許多線程要求分歧記載時削減抵觸鎖。
 事務回滾時削減轉變數據。
 使長時光對零丁的一行記載加鎖成為能夠。

行級鎖的缺陷有:
 比頁級鎖和表級鎖消費更多的內存。
 鎖是盤算機調和多個過程或線程並發拜訪某一資本的機制,分歧的數據庫的鎖機制年夜同小異。因為數據庫資本是一種供很多用戶同享的資本,所以若何包管數據並發拜訪的分歧性、有用性是一切數據庫必需處理的一個成績,鎖抵觸也是影響數據庫並發拜訪機能的一個主要身分。懂得鎖機制不只可使我們更有用的開辟應用數據庫資本,也使我們可以或許更好地保護數據庫,從而進步數據庫的機能。

MySQL的鎖機制比擬簡略,其最明顯的特色是分歧的存儲引擎支撐分歧的鎖機制。

例如,MyISAM和MEMORY存儲引擎采取的是表級鎖(table-level-locking);BDB存儲引擎采取的是頁面鎖(page-level-locking),同時也支撐表級鎖;InnoDB存儲引擎既支撐行級鎖,也支撐表級鎖,默許情形下是采取行級鎖。

上述三種鎖的特征可年夜致歸結以下:
1) 表級鎖:開支小,加鎖快;不會湧現逝世鎖;鎖定粒度年夜,產生鎖抵觸的幾率最高,並發度最低。
2) 行級鎖:開支年夜,加鎖慢;會湧現逝世鎖;鎖定粒度最小,產生鎖抵觸的幾率最低,並發度也最高。
3) 頁面鎖:開支和加鎖時光界於表鎖和行鎖之間;會湧現逝世鎖;鎖定粒度界於表鎖和行鎖之間,並發度普通。

     三種鎖各有各的特色,若僅從鎖的角度來講,表級鎖更合適於以查詢為主,只要大批按索引前提更新數據的運用,如WEB運用;行級鎖更合適於有年夜量按索引前提並發更新大批分歧數據,同時又有並發查詢的運用,如一些在線事務處置(OLTP)體系。

     MySQL表級鎖有兩種形式:表同享讀鎖(Table Read Lock)和表獨有寫鎖(Table Write Lock)。甚麼意思呢,就是說對MyISAM表停止讀操作時,它不會壅塞其他用戶對統一表的讀要求,但會壅塞 對統一表的寫操作;而對MyISAM表的寫操作,則會壅塞其他用戶對統一表的讀和寫操作。

     MyISAM表的讀和寫是串行的,即在停止讀操作時不克不及停止寫操作,反之也是一樣。但在必定前提下MyISAM表也支撐查詢和拔出的操作的並發停止,其機制是經由過程掌握一個體系變量(concurrent_insert)來停止的,當其值設置為0時,不許可並發拔出;當其值設置為1 時,假如MyISAM表中沒有空泛(即表中沒有被刪除的行),MyISAM許可在一個過程讀表的同時,另外一個過程從表尾拔出記載;當其值設置為2時,不管MyISAM表中有無空泛,都許可在表尾並發拔出記載。

     MyISAM鎖調劑是若何完成的呢,這也是一個很症結的成績。例如,當一個過程要求某個MyISAM表的讀鎖,同時另外一個過程也要求統一表的寫鎖,此時MySQL將會如優先處置過程呢?經由過程研討注解,寫過程將先取得鎖(即便讀要求先到鎖期待隊列)。但這也形成一個很年夜的缺點,即年夜量的寫操作會形成查詢操作很難取得讀鎖,從而能夠形成永久壅塞。所幸我們可以經由過程一些設置來調理MyISAM的調劑行動。我們可經由過程指定參數low-priority-updates,使MyISAM默許引擎賜與讀要求以優先的權力,設置其值為1(set low_priority_updates=1),使優先級下降。

     InnoDB鎖與MyISAM鎖的最年夜分歧在於:一是支撐事務(TRANCSACTION),二是采取了行級鎖。我們曉得事務是由一組SQL語句構成的邏輯處置單位,其有四個屬性(簡稱ACID屬性),分離為:

原子性(Atomicity):事務是一個原子操作單位,其對數據的修正,要末全體履行,要末全都不履行;
分歧性(Consistent):在事務開端和完成時,數據都必需堅持分歧狀況;
隔離性(Isolation):數據庫體系供給必定的隔離機制,包管事務在不受內部並發操作影響的“自力”情況履行;
耐久性(Durable):事務完成以後,它關於數據的修正是永遠性的,即便湧現體系毛病也可以或許堅持。

InnoDB有兩種形式的行鎖:

1)同享鎖:許可一個事務去讀一行,阻攔其他事務取得雷同數據集的排他鎖。
    ( Select * from table_name where ......lock in share mode)

2)排他鎖:許可取得排他鎖的事務更新數據,阻攔其他事務獲得雷同數據集的同享讀鎖和  排他寫鎖。(select * from table_name where.....for update)
    為了許可行鎖和表鎖共存,完成多粒度鎖機制;同時還有兩種外部應用的意向鎖(都是表鎖),分離為意向同享鎖和意向排他鎖。
    InnoDB行鎖是經由過程給索引項加鎖來完成的,即只要經由過程索引前提檢索數據,InnoDB才應用行級鎖,不然將應用表鎖!

別的:拔出,更新機能優化的幾個主要參數

bulk_insert_buffer_size
批量拔出緩存年夜小, 這個參數是針對MyISAM存儲引擎來講的.實用於在一次性拔出100-1000+筆記錄時, 進步效力.默許值是8M.可以針對數據量的年夜小,翻倍增長.

concurrent_insert
並發拔出, 當表沒有空泛(刪除過記載), 在某過程獲得讀鎖的情形下,其他過程可以在表尾部停止拔出.

值可以設0不許可並發拔出, 1當表沒有空泛時, 履行並發拔出, 2不論能否有空泛都履行並發拔出.
默許是1 針對表的刪除頻率來設置.

delay_key_write
針對MyISAM存儲引擎,延遲更新索引.意思是說,update記載時,先將數據up到磁盤,但不up索引,將索引存在內存裡,當表封閉時,將內存索引,寫到磁盤. 值為 0不開啟, 1開啟. 默許開啟.

delayed_insert_limit, delayed_insert_timeout, delayed_queue_size
延遲拔出, 將數據先交給內存隊列, 然後漸漸地拔出.然則這些設置裝備擺設,不是一切的存儲引擎都支撐, 今朝來看, 經常使用的InnoDB不支撐, MyISAM支撐. 依據現實情形調年夜, 普通默許夠用了

/* ==================== MySQL InnoDB 鎖表與鎖行 ======================== */

因為InnoDB預設是Row-Level Lock,所以只要「明白」的指定主鍵,MySQL才會履行Row lock (只鎖住被拔取的材料例) ,不然MySQL將會履行Table Lock (將全部材料表單給鎖住)。

舉個例子: 假定有個表單products ,外面有id跟name二個欄位,id是主鍵。

例1: (明白指定主鍵,而且有此筆材料,row lock)
SELECT * FROM products WHERE id='3' FOR UPDATE;
SELECT * FROM products WHERE id='3' and type=1 FOR UPDATE;

例2: (明白指定主鍵,若查無此筆材料,無lock)
SELECT * FROM products WHERE id='-1' FOR UPDATE;

例3: (無主鍵,table lock)
SELECT * FROM products WHERE name='Mouse' FOR UPDATE;

例4: (主鍵不明白,table lock)
SELECT * FROM products WHERE id<>'3' FOR UPDATE;

例5: (主鍵不明白,table lock)
SELECT * FROM products WHERE id LIKE '3' FOR UPDATE;

注1: FOR UPDATE僅實用於InnoDB,且必需在生意業務區塊(BEGIN/COMMIT)中能力失效。
注2: 要測試鎖定的狀態,可以應用MySQL的Command Mode ,開二個視窗來做測試。

在MySql 5.0中測試確切是如許的

別的:MyAsim 只支撐表級鎖,InnerDB支撐行級鎖
添加了(行級鎖/表級鎖)鎖的數據不克不及被其它事務再鎖定,也不被其它事務修正(修正、刪除)
是表級鎖時,不論能否查詢到記載,都邑鎖定表
另外,假如A與B都對表id停止查詢但查詢不到記載,則A與B在查詢上不會停止row鎖,但A與B都邑獲得排它鎖,此時A再拔出一筆記錄的話則會由於B曾經有鎖而處於期待中,此時B再拔出一條異樣的數據則會拋出Deadlock found when trying to get lock; try restarting transaction然後釋放鎖,此時A就取得了鎖而拔出勝利
 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved