真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

如何理解mysql的鎖機(jī)制

本篇文章為大家展示了如何理解MySQL的鎖機(jī)制,內(nèi)容簡(jiǎn)明扼要并且容易理解,絕對(duì)能使你眼前一亮,通過(guò)這篇文章的詳細(xì)介紹希望你能有所收獲。

創(chuàng)新互聯(lián)服務(wù)項(xiàng)目包括博興網(wǎng)站建設(shè)、博興網(wǎng)站制作、博興網(wǎng)頁(yè)制作以及博興網(wǎng)絡(luò)營(yíng)銷策劃等。多年來(lái),我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢(shì)、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,博興網(wǎng)站推廣取得了明顯的社會(huì)效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到博興省份的部分城市,未來(lái)相信會(huì)繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!

 鎖

0.1 鎖機(jī)制

當(dāng)前MySQL已經(jīng)支持 ISAM, MyISAM, MEMORY (HEAP) 類型表的表級(jí)鎖了,BDB 表支持頁(yè)級(jí)鎖,InnoDB 表支持行級(jí)鎖。
很多時(shí)候,可以通過(guò)經(jīng)驗(yàn)來(lái)猜測(cè)什么樣的鎖對(duì)應(yīng)用程序更合適,不過(guò)通常很難說(shuō)一個(gè)鎖比別的更好,這全都要依據(jù)應(yīng)用程序來(lái)決定,不同的地方可能需要不同的鎖。
想要決定是否需要采用一個(gè)支持行級(jí)鎖的存儲(chǔ)引擎,就要看看應(yīng)用程序都要做什么,其中的查詢、更新語(yǔ)句是怎么用的。例如,很多的web應(yīng)用程序大量的做查詢,很少刪除,主要是基于索引的更新,只往特定的表中插入記錄。采用基本的MySQL MyISAM 表就很合適了。
MySQL中對(duì)表級(jí)鎖的存儲(chǔ)引擎來(lái)說(shuō)是釋放死鎖的。避免死鎖可以這樣做到:在任何查詢之前先請(qǐng)求鎖,并且按照請(qǐng)求的順序鎖表。
MySQL中用于 WRITE(寫(xiě)) 的表鎖的實(shí)現(xiàn)機(jī)制如下:

  • 如果表沒(méi)有加鎖,那么就加一個(gè)寫(xiě)鎖。

  • 否則的話,將請(qǐng)求放到寫(xiě)鎖隊(duì)列中。

MySQL中用于 READ(讀) 的表鎖的實(shí)現(xiàn)機(jī)制如下:

  • 如果表沒(méi)有加寫(xiě)鎖,那么就加一個(gè)讀鎖。

  • 否則的話,將請(qǐng)求放到讀鎖隊(duì)列中。

當(dāng)鎖釋放后,寫(xiě)鎖隊(duì)列中的線程可以用這個(gè)鎖資源,然后才輪到讀鎖隊(duì)列中的線程。
這就是說(shuō),如果表里有很多更新操作的話,那么 Select 必須等到所有的更新都完成了之后才能開(kāi)始。
從 MySQL 3.23.33 開(kāi)始,可以通過(guò)狀態(tài)變量 Table_locks_waitedTable_locks_immediate 來(lái)分析系統(tǒng)中的鎖表爭(zhēng)奪情況:

mysql> SHOW STATUS LIKE 'Table%';+-----------------------+---------+| Variable_name         | Value   |+-----------------------+---------+| Table_locks_immediate | 1151552 || Table_locks_waited    | 15324   |+-----------------------+---------+

在 MySQL 3.23.7(在Windows上是3.23.25)以后,在 MyISAM 表中只要沒(méi)有沖突的 Insert 操作,就可以無(wú)需使用鎖表自由地并行執(zhí)行 InsertSelect 語(yǔ)句。也就是說(shuō),可以在其它客戶端正在讀取 MyISAM 表記錄的同時(shí)時(shí)插入新記錄。如果數(shù)據(jù)文件的中間沒(méi)有空余的磁盤塊的話,就不會(huì)發(fā)生沖突了,因?yàn)檫@種情況下所有的新記錄都會(huì)寫(xiě)在數(shù)據(jù)文件的末尾(當(dāng)在表的中間做刪除或者更新操作時(shí),就可能導(dǎo)致空洞)。當(dāng)空洞被新數(shù)據(jù)填充后,并行插入特性就會(huì)自動(dòng)重新被啟用了。
如果想要在一個(gè)表上做大量的 InsertSelect 操作,但是并行的插入?yún)s不可能時(shí),可以將記錄插入到臨時(shí)表中,然后定期將臨時(shí)表中的數(shù)據(jù)更新到實(shí)際的表里??梢杂靡韵旅顚?shí)現(xiàn):

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;

InnoDB 使用行級(jí)鎖,BDB 使用頁(yè)級(jí)鎖。對(duì)于 InnoDBBDB 存儲(chǔ)引擎來(lái)說(shuō),是可能產(chǎn)生死鎖的。這是因?yàn)?InnoDB 會(huì)自動(dòng)捕獲行鎖,BDB 會(huì)在執(zhí)行 SQL 語(yǔ)句時(shí)捕獲頁(yè)鎖的,而不是在事務(wù)的開(kāi)始就這么做。
行級(jí)鎖的優(yōu)點(diǎn)有:

  • 在很多線程請(qǐng)求不同記錄時(shí)減少?zèng)_突鎖。

  • 事務(wù)回滾時(shí)減少改變數(shù)據(jù)。

  • 使長(zhǎng)時(shí)間對(duì)單獨(dú)的一行記錄加鎖成為可能。

行級(jí)鎖的缺點(diǎn)有:

  • 比頁(yè)級(jí)鎖和表級(jí)鎖消耗更多的內(nèi)存。

  • 當(dāng)在大量表中使用時(shí),比頁(yè)級(jí)鎖和表級(jí)鎖更慢,因?yàn)樗枰?qǐng)求更多的所資源。

  • 當(dāng)需要頻繁對(duì)大部分?jǐn)?shù)據(jù)做 GROUP BY 操作或者需要頻繁掃描整個(gè)表時(shí),就明顯的比其它鎖更糟糕。

  • 使用更高層的鎖的話,就能更方便的支持各種不同的類型應(yīng)用程序,因?yàn)檫@種鎖的開(kāi)銷比行級(jí)鎖小多了。

表級(jí)鎖在下列幾種情況下比頁(yè)級(jí)鎖和行級(jí)鎖更優(yōu)越:

  • 很多操作都是讀表。

  • 在嚴(yán)格條件的索引上讀取和更新,當(dāng)更新或者刪除可以用單獨(dú)的索引來(lái)讀取得到時(shí):

    Updatetbl_nameSETcolumn=valueWhereunique_key_col=key_value;    Delete FROMtbl_nameWhereunique_key_col=key_value;
  • SelectInsert 語(yǔ)句并發(fā)的執(zhí)行,但是只有很少的 UpdateDelete 語(yǔ)句。

  • 很多的掃描表和對(duì)全表的 GROUP BY 操作,但是沒(méi)有任何寫(xiě)表。

表級(jí)鎖和行級(jí)鎖或頁(yè)級(jí)鎖之間的不同之處還在于:
將同時(shí)有一個(gè)寫(xiě)和多個(gè)讀的地方做版本(例如在MySQL中的并發(fā)插入)。也就是說(shuō),數(shù)據(jù)庫(kù)/表支持根據(jù)開(kāi)始訪問(wèn)數(shù)據(jù)時(shí)間點(diǎn)的不同支持各種不同的試圖。其它名有:時(shí)間行程,寫(xiě)復(fù)制,或者是按需復(fù)制。
原文: Versioning (such as we use in MySQL for concurrent inserts) where you can have one writer at the same time as many readers. This means that the database/table supports different views for the data depending on when you started to access it. Other names for this are time travel, copy on write, or copy on demand.
按需復(fù)制在很多情況下比頁(yè)級(jí)鎖或行級(jí)鎖好多了。盡管如此,最壞情況時(shí)還是比其它正常鎖使用了更多的內(nèi)存。
可以用應(yīng)用程序級(jí)鎖來(lái)代替行級(jí)鎖,例如MySQL中的 GET_LOCK()RELEASE_LOCK()。但它們是勸告鎖(原文:These are advisory locks),因此只能用于安全可信的應(yīng)用程序中。

7.3.2 鎖表

為了能有快速的鎖,MySQL除了 InnoDBBDB 這兩種存儲(chǔ)引擎外,所有的都是用表級(jí)鎖(而非頁(yè)、行、列級(jí)鎖)。
對(duì)于 InnoDBBDB 表,MySQL只有在指定用 LOCK TABLES 鎖表時(shí)才使用表級(jí)鎖。在這兩種表中,建議最好不要使用 LOCK TABLES,因?yàn)?InnoDB 自動(dòng)采用行級(jí)鎖,BDB 用頁(yè)級(jí)鎖來(lái)保證事務(wù)的隔離。
如果數(shù)據(jù)表很大,那么在大多數(shù)應(yīng)用中表級(jí)鎖會(huì)比行級(jí)鎖好多了,不過(guò)這有一些陷阱。
表級(jí)鎖讓很多線程可以同時(shí)從數(shù)據(jù)表中讀取數(shù)據(jù),但是如果另一個(gè)線程想要寫(xiě)數(shù)據(jù)的話,就必須要先取得排他訪問(wèn)。正在更新數(shù)據(jù)時(shí),必須要等到更新完成了,其他線程才能訪問(wèn)這個(gè)表。
更新操作通常認(rèn)為比讀取更重要,因此它的優(yōu)先級(jí)更高。不過(guò)最好要先確認(rèn),數(shù)據(jù)表是否有很高的 Select 操作,而更新操作并非很‘急需’。
表鎖鎖在一個(gè)線程在等待,因?yàn)榇疟P空間滿了,但是卻需要有空余的磁盤空間,這個(gè)線程才能繼續(xù)處理時(shí)就有問(wèn)題了。這種情況下,所有要訪問(wèn)這個(gè)出問(wèn)題的表的線程都會(huì)被置為等待狀態(tài),直到有剩余磁盤空間了。
表鎖在以下設(shè)想情況中就不利了:

  • 一個(gè)客戶端提交了一個(gè)需要長(zhǎng)時(shí)間運(yùn)行的 Select 操作。

  • 其他客戶端對(duì)同一個(gè)表提交了 Update 操作,這個(gè)客戶端就要等到 Select 完成了才能開(kāi)始執(zhí)行。

  • 其他客戶端也對(duì)同一個(gè)表提交了 Select 請(qǐng)求。由于 Update 的優(yōu)先級(jí)高于 Select,所以 Select 就會(huì)先等到 Update完成了之后才開(kāi)始執(zhí)行,它也在等待第一個(gè) Select 操作。

下列所述可以減少表鎖帶來(lái)的資源爭(zhēng)奪:

  • Select 速度盡量快,這可能需要?jiǎng)?chuàng)建一些摘要表。

  • 啟動(dòng) mysqld 時(shí)使用參數(shù) --low-priority-updates。這就會(huì)讓更新操作的優(yōu)先級(jí)低于 Select。這種情況下,在上面的假設(shè)中,第二個(gè) Select 就會(huì)在 Insert 之前執(zhí)行了,而且也無(wú)需等待第一個(gè)Select了。

  • 可以執(zhí)行 SET LOW_PRIORITY_UpdateS=1 命令,指定所有的更新操作都放到一個(gè)指定的鏈接中去完成。詳情請(qǐng)看“14.5.3.1 SET Syntax”。

  • LOW_PRIORITY 屬性來(lái)降低 Insert,Update,Delete 的優(yōu)先級(jí)。

  • HIGH_PRIORITY 來(lái)提高 Select 語(yǔ)句的優(yōu)先級(jí)。詳情請(qǐng)看“14.1.7 Select Syntax”。

  • 從MySQL 3.23.7 開(kāi)始,可以在啟動(dòng) mysqld 時(shí)指定系統(tǒng)變量 max_write_lock_count 為一個(gè)比較低的值,它能強(qiáng)制臨時(shí)地提高表的插入數(shù)達(dá)到一個(gè)特定值后的所有 Select 操作的優(yōu)先級(jí)。它允許在 WRITE 鎖達(dá)到一定數(shù)量后有 READ 鎖。

  • 當(dāng) InsertSelect 一起使用出現(xiàn)問(wèn)題時(shí),可以轉(zhuǎn)而采用 MyISAM 表,它支持并發(fā)的Select Insert 操作。

  • 當(dāng)在同一個(gè)表上同時(shí)有插入和刪除操作時(shí),Insert DELAYED 可能會(huì)很有用。詳情請(qǐng)看“14.1.4.2 Insert DELAYED Syntax”。

  • 當(dāng) SelectDelete 一起使用出現(xiàn)問(wèn)題時(shí),DeleteLIMIT 參數(shù)可能會(huì)很有用。詳情請(qǐng)看“14.1.1 Delete Syntax”

  • 執(zhí)行 Select 時(shí)使用 SQL_BUFFER_RESULT 有助于減短鎖表的持續(xù)時(shí)間.詳情請(qǐng)看“14.1.7 Select Syntax”。

  • 可以修改源代碼 `mysys/thr_lock.c',只用一個(gè)所隊(duì)列。這種情況下,寫(xiě)鎖和讀鎖的優(yōu)先級(jí)就一樣了,這對(duì)一些應(yīng)用可能有幫助。

以下是MySQL鎖的一些建議:

  • 只要對(duì)同一個(gè)表沒(méi)有大量的更新和查詢操作混在一起,目前的用戶并不是問(wèn)題。

  • 執(zhí)行 LOCK TABLES 來(lái)提高速度(很多更新操作放在一個(gè)鎖之中比沒(méi)有鎖的很多更新快多了)。將數(shù)據(jù)拆分開(kāi)到多個(gè)表中可能也有幫助。

  • 當(dāng)MySQL碰到由于鎖表引起的速度問(wèn)題時(shí),將表類型轉(zhuǎn)換成 InnoDBBDB 可能有助于提高性能。詳情請(qǐng)看“16 The InnoDB Storage Engine”和“15.4 The BDB (BerkeleyDB) Storage Engine”。

上述內(nèi)容就是如何理解mysql的鎖機(jī)制,你們學(xué)到知識(shí)或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識(shí)儲(chǔ)備,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。


當(dāng)前文章:如何理解mysql的鎖機(jī)制
網(wǎng)站地址:http://weahome.cn/article/pgjsdd.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部