高效能mysql學習筆記

2022-06-07 01:18:11 字數 3865 閱讀 3457

此文已由作者朱笑天授權網易雲社群發布。

筆者在工作之餘閱讀了一下高效能mysql,以下的內容對mysql的介紹以及書中涉及一些概念的總結歸納。

1.mysql架構

1.最上層負責鏈結處理、認證授權、安全等

2.中間一層涵蓋了mysql的大多數核心功能。包括查詢解析、分析、優化、快取、內建函式;所有的誇儲存引擎的功能都在這一層實現(儲存過程、觸發器、檢視等)

3.第三層包含了儲存引擎,儲存引擎與上層使用api進行通訊,引擎之間不會有互動。

1.1連線層

當mysql啟動,等待客戶端連線,每乙個客戶端連線請求,伺服器都會新建乙個執行緒處理,每個執行緒獨立,擁有各自的記憶體處理空間。

a.連線處理流程

b.認證流程

連線到伺服器,伺服器需要對其進行驗證,也就是使用者名稱、ip、密碼驗證,一旦連線成功,還要驗證是否具有執行某個特定查詢的許可權。

1.2sql處理層

這一層主要功能有:sql語句的解析、優化,快取的查詢,mysql內建函式的實現,跨儲存引擎功能,例如:儲存過程、觸發器、檢視等。

a.執行過程:

1.如果是查詢語句(select語句),首先會查詢快取是否已有相應結果,有則返回結果,無則進行下一步(如果不是查詢語句,同樣調到下一步); 

2.解析查詢,建立乙個內部資料結構(解析樹),這個解析樹主要用來sql語句的語義與語法解析;

3.優化:優化sql語句,例如重寫查詢,決定表的讀取順序,以及選擇需要的索引等。這一階段使用者是可以查詢的,查詢伺服器優化器是如何進行優化的,便於使用者重構查詢和修改相關配置,達到最優化。這一階段還涉及到儲存引擎,優化器會詢問儲存引擎,比如某個操作的開銷資訊、是否對特定索引有查詢優化等。

1.3 儲存引擎

儲存引擎,主要用來儲存資料的,不同的儲存引擎採用不同的技術(儲存機制、索引機制、鎖定機制)儲存資料,這主要是為了滿足資料儲存要求,比如有的資料不需要大量的改動,只用來查詢,而有的資料則需要常常修改(資料插入、刪除、更新),針對各種業務情況,為了更好的資料處理效率採用不同的資料儲存技術(即不同儲存引擎)。 

mysql的儲存引擎是外掛程式式的,也就是說,使用者可以隨時切換mysql的儲存引擎:針對表或針對庫都可(通過sql語句命令)。這種靈活性也是為什麼mysql受到歡迎的乙個重要原因。mysql集合了多種引擎:myisam、innodb、bdb、merge、memory等,預設的是innodb(mysql5.5開始,以前是myisam)。

2.併發控制

mysql是多執行緒應用,並且共享儲存資料,很顯然,當兩個及以上執行緒對同一塊資料進行寫將會發生資料不一致等各種問題,比如,同時對乙個表增加一條記錄,後乙個增加的記錄可能會覆蓋前一條,造成資料丟失。若僅僅是讀不會發生錯誤,但是當讀寫一同,就有可能發生讀錯誤,所以,對讀也是需要必要的控制。

以上問題就需要併發控制來解決,所謂的併發,就是每一次只允許乙個執行緒對某一塊資料(可以是某個資料庫,或某張表,或表裡某條記錄)寫,實現併發控制有多種方式,mysql採用的是鎖以及mvcc(多版本控制)。 

a.讀寫鎖

mysql提供了兩種鎖實現併發控制:讀鎖和寫鎖。讀鎖是共享的,也叫共享鎖(也叫s鎖),相互不會阻塞,多個讀鎖(多個執行緒使用者)可以同一時刻讀取統一資源;寫鎖則是排他的,也叫排他鎖(也叫x鎖),同一時間乙個資源只能有乙個寫鎖,也就是說,寫鎖會阻塞其他寫鎖和讀鎖。即讀鎖上面可以加讀鎖,但不能加寫鎖,而寫鎖則不能加任何鎖。 

每次運算元據先判斷該資料是否加鎖,加了什麼鎖,然後以此判斷是否允許本次操作執行,但這樣是不是覺得很麻煩?很耗效能?所以才有了資料庫事務隔離級別,統一設定乙個隔離級別,資料庫系統會根據隔離級別隱式的給資料加鎖,然後根據這個級別來判斷本次操作執行許可權。

b.樂觀鎖悲觀鎖

悲觀鎖:操作前,悲觀地認為所運算元據在操作期間會被其他事務修改,所以,在操作前我要先給我操作的資料加鎖才放心。至於加的是讀鎖還是寫鎖則看具體應用場景。 

樂觀鎖:操作前,樂觀地認為所運算元據在操作期間不會被其他事務修改,只在最後更新的時候(如果操作是更新的話)檢視原始資料是否被修改,如果沒修改,更新資料,否則失敗。至於如何知道原始資料被修改,這就是涉及到具體實現方式了,最常用的就是mvcc。

理論上,盡量鎖定需要修改的部分,而不是所有的資料,鎖定的資料單元越小,系統的併發控制度越高,比如行級鎖,修改的時候只鎖定這一行記錄,這個時候其他執行緒對該錶的其他記錄修改不影響。但是,加鎖也是需要消耗資源的,鎖的各種操作:獲得鎖、檢查鎖狀態、釋放鎖等都會增加開銷,越細粒度的鎖開銷越大,過多的所操作所帶來的是效能急劇下降。 

所以我們要採用一種鎖策略來平衡併發度和系統效能,mysql由於儲存引擎的外掛程式式,每個儲存引擎可以實現自己的鎖策略,所以不需要通用的鎖策略,只需要在相應應用場景下選擇相應的儲存引擎即可。 

表鎖:mysql最基本的鎖策略,顧名思義,對整張表加讀鎖和寫鎖。一般由mysql伺服器層實現,如果這個時候儲存引擎層還有鎖,優先表鎖。

行級鎖:

更大細粒度的鎖,只鎖住一行記錄,即對不同行記錄可併發操作。行級鎖只由儲存引擎層實現,mysql伺服器層沒有實現。

3.事務

乙個實現了事務處理系統(保證事務的acid)的資料庫,相比沒有實現的,需要更強的cpu處理能力、更大的記憶體和更多的儲存空間,但是有些場景是不太需要事務處理能力的,也就不需要具有事務處理能力的資料庫(因為他們需要更大的資源)。 

mysql中innodb、ndb cluster儲存引擎實現了事務功能,當然還有其他第三方儲存引擎也實現了,預設下採用自動提交模式,即若不顯式開始乙個事務,每乙個操作當做乙個事務進行操作,可以通過設定autocommit變數來啟用或禁用自動提交模式,如果禁用了則需顯式執行commit或rollback結束事務。

下面針對connection_type值的不同做的一些實驗:

create table test(a int, primary key (a))engine=innodb;

set @@completion_type=1; 

begin;

insert into test select 1;

commit work;

insert into test select 2;

insert into test select 2;

rollback;

得到如下結果:

測試中,將completion_type設定成1,第一次通過commit work來insert這條記錄。之後insert 2的時候並沒有啟用begin(start transaction)來開啟乙個事務,之後再插入一條重複的記錄2,這時會丟擲異常rollback後,最後發現只有1這樣一條記錄,2並沒有被insert進去。因為completion_type為1的時候,commit work會開啟另外乙個事務,因此2個insert語句是在同乙個事務裡面的,所以回滾後就沒有insert進去。

通過上面的測試發現,completion_type設定成2時,commit work之後,再通過select獲取db伺服器版本資訊的時候出現2006的error,說明以及斷開了與db的連線。

引數completion_type為2時,commit work等同於commit and release。當事務提交時候會自動斷開與db的連線。

待續。。。

免費體驗雲安全(易盾)內容安全、驗證碼等服務

更多網易技術、產品、運營經驗分享請點選。

《高效能mysql》學習

整型型別 tinyint,smallint,mediumint,int,bigint 有可選的unsigned屬性 表示不允許負值 例 tinyint unsigned 儲存的範圍是0 255,tinyint則表示 128 127 實數型別 float和double型別支援使用標準的浮點運算進行近似...

高效能MySQL學習筆記一 MySQL架構

mysql最與眾不同的特性是 它的儲存引擎架構,這種架構的設計將查詢處理以及其他系統任務和資料的儲存 提取相分離。這種處理和儲存相分離的設計可以在使用時根據效能 特性,以及其他需求來選擇資料儲存的方式。mysql預設採用自動提交模式。設定是否自動提交 1為自動提交,0禁用,禁用後,使用commit或...

高效能Mysql學習筆記 1 總覽

高效能mysql 這本經典之作,是個程式設計師就會買買買,但真正看完的確實不易。本篇部落格記錄的,也只是本人第一遍快速閱讀完之後的乙個簡易總結和記錄,尚未未深入學習,但已經感受到此書的 神力 似乎沒有這本書解決不了的問題 前提是要對本書的每乙個字都要深入研究 看似700多頁的一本書,實際學習起來,恐...