1. 程式人生 > >MySQL效能調優——鎖定機制與鎖優化分析

MySQL效能調優——鎖定機制與鎖優化分析

——針對多執行緒的併發訪問,任何一個數據庫都有其鎖定機制,它的優劣直接關係著資料的一致完整性與資料庫系統的高併發處理效能。鎖定機制也因此成了各種資料庫的核心技術之一。不同資料庫儲存引擎的鎖定機制是不同的,本文將從MySQL最常見的儲存引擎MyISAM與InnoDB的鎖定機制說起。

一、MyISAM的鎖機制——表級鎖定

MySQL表級鎖定的常見型別主要分為兩種,一種是讀鎖,一種是寫鎖。

誰持有讀鎖?誰持有寫鎖?誰在等待讀鎖資源?誰在等待寫鎖資源?資料庫系統都是要記錄的。MySQL中,主要通過如下4個佇列來儲存相關資訊:

讀鎖持有佇列:Current read-lock queue(lock->read)——存放所有正在鎖定的讀鎖資訊

寫鎖持有佇列:Current write-lock queue(lock->write)——存放所有正在鎖定的寫鎖資訊

讀鎖等待佇列:Pending read-lock queue(lock->read_wait)——存放所有等待對資源加讀鎖的執行緒資訊

寫鎖等待佇列:Pending write-lock queue(lock->write_wait)——存放所有等待對資源加寫鎖的執行緒資訊

為保證資料一致完整性,多執行緒可以為同一份資源加多個讀鎖,而同一份資源只能加一個寫鎖,讀鎖與寫鎖也不能同時加在一份資源上。

1、讀鎖定

客戶端請求獲取讀鎖定資源時,如果滿足如下兩個要求,則請求通過,進入讀鎖持有佇列;否則,請求失敗,進入讀鎖等待佇列。

(1)請求鎖定的資源當前沒有寫鎖定;

(2)寫鎖等待佇列中沒有優先順序更高的寫鎖定在等待。

2、寫鎖定

客戶端請求獲取寫鎖定的時候:

(1)先通過寫鎖持有佇列檢查這份資源是否已經被加上寫鎖定,如果有,自然暫停自身執行緒進入寫鎖等待佇列等待,如果沒有,進行第(2)步

(2)檢查寫鎖等待佇列中是否有執行緒同樣在等待獲取這份資源的寫鎖定,如果有,則進入寫鎖等待佇列等待,如果沒有,進行第(3)步

(3)通過讀鎖持有佇列檢查這份資源是否已經被加上讀鎖定,如果有,則進行寫鎖等待佇列等待,如果沒有,可以獲取寫鎖定,進入寫鎖持有佇列中

請注意:對於MySQL使用者,展現出來的鎖定型別只有讀鎖定與寫鎖定兩種,但實際上,MySQL內部實現中卻有11種枚舉出來的鎖定型別,因為表面與實現的差異,上述請求過程會有特例,在此不再贅述,如想深入瞭解,可參看簡朝陽《MySQL效能調優與架構設計》。

那我們說,MyISAM在對錶的操作上只能是序列處理,不能並行操作嗎?並不是,MyISAM有一個很重要的機制就是併發插入(Concurrent Insert)特性,我們在下面第三部分MyISAM表級鎖定優化建議再詳細介紹。

二、InnoDB的鎖機制——行級鎖定

不光InnoDB儲存引擎,MySQL的分散式儲存引擎NDB Cluster都使用行級鎖定。InnoDB的行級鎖定同樣分為兩種,一種是共享鎖,一種是排它鎖

1、當一個事務需要給某份資源加鎖的時候,主要情況有如下:

(1)如果遇到一個共享鎖正鎖定著資源,那麼事務只能再加上一個共享鎖,而不能加排它鎖。

(2)如果遇到一個排他鎖正鎖定著資源,那麼事務只能等待該鎖定釋放資源後他才能獲得資源並新增自己的鎖定。

2、InnoDB鎖機制的實現與弊端

InnoDB鎖機制是基於索引實現的,通過在指向資料記錄的第一個索引鍵之前與最後一個索引鍵之後的空域空間(間隙或著說是範圍)標記鎖定資訊實現,被稱為間隙鎖。

間隙鎖的弊端:會在執行範圍查詢時,對範圍內所有鍵值加鎖,即使鍵值不存在,這會造成在加鎖後無法插入鎖定鍵值範圍內的任何資料,影響效能。比如:

SELECT *
FROM user
WHERE user_id BETWEEM 1 AND 100 
執行這個查詢時,會對1-100範圍內所有索引鍵值(1-100)加間隙鎖,即使並不存在user_id為10的使用者資訊,所以在加鎖後,要想插入一條user_id為10的使用者資訊是不可行的,這對於行級鎖來說並不符合常理。InnoDB給出的解釋是:為了防止幻讀的出現。

當沒有索引時或無法利用索引時,InnoDB會棄用行級鎖,改用表級鎖,併發處理效能降低。

另外,因為InnoDB的行級鎖與事務處理特性,一定會產生死鎖現象,對於如何降低死鎖產生概率,我在第四部分InnoDB行級鎖定優化建議中詳述。

三、MyISAM表級鎖定優化建議

因為表級鎖的鎖定顆粒較大,其實現難度複雜性行都降低了,成本自然降低,但是付出了高併發處理效能較低的代價,所以表級鎖的優化就從如何提高併發處理效能說起。

1、縮短鎖定時間

(1)降低查詢複雜度,將複雜的查詢劃分成幾個簡單的查詢分步進行。

(2)建立合適的索引加快查詢效率。

(3)優化表結構,只存放必要的資訊,且控制欄位型別與欄位長度(等長最優)。

2、利用MyISAM併發插入特性(Concurrent Insert),通過設定concurrent_insert引數實現

(1)concurrent_insert=2,無論MyISAM表資料檔案的中間部分是否有因為刪除資料留下的空閒空間,都允許在資料檔案尾部進行併發插入。

(2)concurrent_insert=1,當MyISAM表資料檔案中間不存在空閒空間時,才允許在資料檔案尾部進行併發插入。

(3)concurrent_insert=0,無論MyISAM表資料檔案的中間部分是否有因為刪除資料留下的空閒空間,都不允許在資料檔案尾部進行併發插入。

如果資料被刪除的可能性比較小,而且對暫時性浪費並不在乎的話,可以嘗試把concurrent_insert設定為2;但當刪除量不是很小,查詢時需要讀取更多的空域空間時,推薦設定為1。

3、合理利用讀寫優先順序

預設情況下,寫優先順序要高於讀優先順序。

(1)當資料庫系統以讀為主,要優先保證查詢效能時,可通過low_priority_updates=1設定讀優先順序高於寫優先順序。

(2)當資料庫系統需要保證寫入效能,則不用設定low_priority_updates引數。

四、InnoDB行級鎖定優化建議

InnoDB的行級鎖最大的優勢就是增強了高併發的處理能力,缺點就是複雜性較高、易死鎖,且基於索引實現有一定弊端。我們要做的就是揚長避短,合理利用InnoDB行級鎖定,為此我們就應該做的:

1、儘可能讓所有的資料檢索都通過索引實現,因為InnoDB行級鎖是基於索引實現的,沒有索引或無法使用索引系統會改為使用表級鎖。

2、合理設計索引,以縮小加鎖範圍,避免“間隙鎖”造成不該鎖定的鍵值被鎖定。

3、儘量控制事務的大小,因為行級鎖的複雜性會加大資源量以及鎖定時間。

4、使用較低級別的事務隔離,以減少因實現事務隔離而付出的成本。

5、避免死鎖,可以通過如下方式實現:

(1)類似的業務模組中,儘可能按照相同的訪問順序來訪問,防止產生死鎖。

(2)同一個事務中,儘量做到一次性鎖定需要的所有資源。

(3)對於易產生死鎖的業務部分,增大處理顆粒度,升級為表級鎖以降低死鎖產生的概率。

相關推薦

MySQL效能調——鎖定機制優化分析

——針對多執行緒的併發訪問,任何一個數據庫都有其鎖定機制,它的優劣直接關係著資料的一致完整性與資料庫系統的高併發處理效能。鎖定機制也因此成了各種資料庫的核心技術之一。不同資料庫儲存引擎的鎖定機制是不同

MySQL效能調架構設計(六)—— MySQL資料庫鎖定機制

前言 在說鎖定機制之前,有必要理解下併發與並行的基本概念。 併發是指一臺處理器上同時處理多個任務,並行是指多個處理器同時處理多個任務,如hadoop分散式叢集。 通俗的講,併發就是不同執行緒同時幹一件事情,並行就是不同執行緒同時幹不同的事情。 所以併發程式設計的目

MySQL效能優化總結___本文乃《MySQL效能調架構設計》讀書筆記!

一、MySQL的主要適用場景 1、Web網站系統 2、日誌記錄系統 3、資料倉庫系統 4、嵌入式系統 二、MySQL架構圖:   三、MySQL儲存引擎概述 1)MyISAM儲存引擎 MyISAM儲存引擎的表在資料庫中,每一個表

MySQL效能調架構設計-筆記

MySQL的主要適用場景 ①Web網站系統:免費開源、安裝配置簡單。 ②日誌記錄系統:MyISAM實現高效能插入和查詢。 ③資料倉庫系統:免費支援主從複製。 InnoDB儲存引擎的特點: a. 支援事務安全

MySQL效能調——索引詳解索引的優化

——索引優化,可以說是資料庫相關優化、理解尤其是查詢優化中最常用的優化手段之一。所以,只有深入索引的實現原理、儲存方式、不同索引間區別,才能設計或使用最優的索引,最大幅度的提升查詢效率! 一、BTree索引 1、概述 Mysql資料庫中使用最頻繁的索引型別,基本所有儲存引

讀《MySQL效能調架構設計》筆記之充分利用 Explain和Profiling

1.1. Explain 的使用     我們先看一下在MySQL Explain 功能中給我們展示的各種資訊的解釋:     ◆ ID:MySQL Query Optimizer選定的執行計劃中查詢的序列號。表示查詢中執行select子句或操作表的順序,id值越大優先順序

MySQL 效能調技巧

技巧#1:確定MySQL的最大連線數 對於MySQL的最大連線數,一次最好是傳送5個請求到Web伺服器。對Web伺服器的5個請求中的一部分將用於CSS樣式表,影象和指令碼等資源。由於諸如瀏覽器快取等原因,要獲得準確的MySQL到Web伺服器的請求比率可能很困難; 要想得到一個確切的數字,就需要分

MySQL效能調-使用ROLLUP代替UNION ALL

需求:統計各個活動的用券總金額和所有活動的用券總金額 原SQL語句如下(表明比較敏感,不便展示): select active_code,SUM(rp_amount) totalReward from xxx_xxx_xxx_xxx group by active_cod

mysql效能調(四)——聚簇索引、索引覆蓋

1、聚簇索引      這裡說的,聚簇索引是相對InnoDB資料庫引擎來說的,講的是聚簇索引隨機主鍵值的效率      對於InnoDB來說,主鍵儘量用整型,並且是遞增的比較好,因為新增的時候,如果是隨機主鍵插入,會存在節點分裂

mysql效能調(三)——列選取原則

1、列型別選擇       1)整型 > data、time > char、varchar > blob            整型、date、time運算快 &nb

mysql效能調(二)——查詢mysql程序狀態

除了可以檢視資料庫狀態,還可以觀察mysql程序狀態 用show processlist 或者開啟慢查詢,獲取有問題的sql(而用profiling以及explain分析sql語句我們暫時以後再說) mysql -uroot -e 'show processlist' 看資料庫狀

mysql效能調(一)——查詢資料庫狀態

所謂效能調優,首先要發現問題,才能知道怎麼進行效能調優噻,所以我們先從發現問題開始 1、show status  查詢資料庫狀態      其中監控伺服器狀態比較重要的幾個引數是: Queries 進行多少次查

mysql效能調筆記(二)--查詢優化和索引

一、Mysql執行查詢流程                                                                           mysql執行查詢的流程 mysql執行查詢內部路程:1.客服端傳送一條查詢給伺服器

MySQL效能調

1、修改伺服器BIOS設定 1.1.選擇performance Per watt Optimized(DAPC)模式、發揮CPU最大效能。 1.2.Memory Frequency(記憶體頻率) 選擇Maximum performance(最近效能)。 1.3.

MySQL效能調my.cnf詳解

提供一個MySQL 5.6版本適合在1GB記憶體VPS上的my.cnf配置檔案: [client] port =3306 socket =/tmp/mysql.sock [mysqld] port =3306 socket =/tmp/mysql.sock basedi

主從同步、讀寫分離、mysql效能調(軟優化)

 配置mysql主從同步1 主從同步的作用:讓slave身份的資料庫伺服器自動同步 master身份的資料庫伺服器上的資料。 一、主資料庫伺服器的配置192.168.4.121 使用者授權mysql> grant replication slave on *.* to [email

MYSQL效能調: 對聚簇索引和非聚簇索引的認識

聚簇索引是對磁碟上實際資料重新組織以按指定的一個或多個列的值排序的演算法。特點是儲存資料的順序和索引順序一致。 一般情況下主鍵會預設建立聚簇索引,且一張表只允許存在一個聚簇索引。 在《資料庫原理》一書中是這麼解釋聚簇索引和非聚簇索引的區別的: 聚簇索引的葉子節點就

IOS效能調系列:使用Instruments動態分析記憶體洩漏,調instruments

第一篇介紹了Analyze對App做靜態分析,可以發現應用中的記憶體洩漏問題,對於有些記憶體洩漏情況通過靜態分析無法解決的,可以通過動態分析來發現,分析起來更有針對性。 從本篇開始介紹XCode提供的強大的分析工具Instruments,記憶體分析只是Instruments中的一個功能,其他功能後續介紹

JVM 垃圾回收機制GC效能調

一、GC概要: JVM堆相關知識     為什麼先說JVM堆?     JVM的堆是Java物件的活動空間,程式中的類的物件從中分配空間,其儲存著正在執行著的應用程式用到的所有物件。這些物件的建立方式就是那些new一類的操作,當物件

Golang 的 協程排程機制 GOMAXPROCS 效能調

作者:林冠巨集 / 指尖下的幽靈 前序 正確地認識 G , M , P 三者的關係,能夠對協程的排程機制有更深入的理解! 本文將會完整介紹完 go 協程的排程機制,包含: 排程物件的主要組成 各物件的關係 與 分工 gorutine 協程是如何被執行的 核心執行緒 sysmon 對 goru