主要補充了一些事務隔離級別會帶來的問題以及可以避免什麼問題,還有就是mysql內部優化語法樹的規則。
目錄
一、mysql知識普及
二、mysql邏輯架構
三、併發控制和鎖的概念
四、事務
五、mysql儲存引擎及應用方案
mysql是乙個開放源**的關聯式資料庫管理系統。
mysql架構可以在多種不同場景中應用並發揮良好作用。主要體現在儲存引擎的架構上,外掛程式式的儲存引擎架構將查詢處理和其它的系統任務以及資料的儲存提取相分離。
mysql首先是乙個網路程式,其在tcp之上定義了自己的應用層協議。所以要使用mysql,我們可以編寫**,跟mysql server建立tcp連線,之後按照其定義好的協議進行互動。當然這樣比較麻煩,比較方便的辦法是呼叫sdk,比如native c api、jdbc、php等各語言mysql connector,或者通過odbc。但通過sdk來訪問mysql,本質上還是在tcp連線上通過mysql協議跟mysql進行互動。
2.connection management
每乙個基於tcp的網路服務都需要管理客戶端鏈結,mysql也不例外。mysql會為每乙個連線繫結乙個執行緒,之後這個連線上的所有查詢都在這個執行緒中執行。為了避免頻繁建立和銷毀執行緒帶來開銷,mysql通常會快取執行緒或者使用執行緒池,從而避免頻繁的建立和銷毀執行緒。
客戶端連線到mysql後,在使用mysql的功能之前,需要進行認證,認證基於使用者名稱、主機名、密碼。如果用了ssl或者tls的方式進行連線,還會進行證書認證。
3.sql inte***ce
mysql支援dml(資料操作語言)、ddl(資料定義語言)、儲存過程、檢視、觸發器、自定義函式等多種sql語言介面。
4.parser
mysql會解析sql查詢,並為其建立語法樹,並根據資料字典豐富查詢語法樹,會驗證該客戶端是否具有執行該查詢的許可權。建立好語法樹後,mysql還會對sql查詢進行語法上的優化,進行查詢重寫。
關於mysql如何對語法樹進行優化,可以參考這篇文章(mysql內部如何優化sql語句),在查詢優化器中,分別講述了邏輯優化和物理優化的規則,包括mysql遇見關鍵字like、group by、函式等優化的規則,下面是一些例子:
語法解析和查詢重寫之後,mysql會根據語法樹和資料的統計資訊對sql進行優化,包括決定表的讀取順序、選擇合適的索引等,最終生成sql的具體執行步驟。這些具體的執行步驟裡真正的資料操作都是通過預先定義好的儲存引擎api來進行的,與具體的儲存引擎實現無關。
6.caches & buffers
mysql內部維持著一些cache和buffer,比如query cache用來快取一條select語句的執行結果,如果能夠在其中找到對應的查詢結果,那麼就不必再進行查詢解析、優化和執行的整個過程了。
7.pluggable storage engine
儲存引擎的具體實現,這些儲存引擎都實現了mysql定義好的儲存引擎api的部分或者全部。mysql可以動態安裝或移除儲存引擎,可以有多種儲存引擎同時存在,可以為每個table設定不同的儲存引擎。儲存引擎負責在檔案系統之上,管理表的資料、索引的實際內容,同時也會管理執行時的cache、buffer、事務、log等資料和功能。
當資料庫中有多個操作需要修改同一資料時,不可避免的會產生資料的髒讀。這時就需要資料庫具有良好的併發控制能力,這一切在mysql中都是由伺服器和儲存引擎來實現的。
解決併發問題最有效的方案是引入了鎖的機制,鎖在功能上分為共享鎖(shared lock)和排它鎖(exclusive lock)即通常說的讀鎖和寫鎖。當乙個select語句在執行時可以施加讀鎖,這樣就可以允許其它的select操作進行,因為在這個過程中資料資訊是不會被改變的這樣就能夠提高資料庫的執行效率。當需要對資料更新時,就需要施加寫鎖了,不在允許其它的操作進行,以免產生資料的髒讀和幻讀。鎖同樣有粒度大小,有表級鎖(table lock)和行級鎖(row lock),分別在資料操作的過程中完成行的鎖定和表的鎖定。這些根據不同的儲存引擎所具有的特性也是不一樣的。
死鎖:兩個或多個事務在同一資源上相互占用並請求鎖定對方占用的資源,從而導致惡性迴圈的現象。
對於死鎖的處理:mysql的部分儲存引擎能夠檢測到死鎖的迴圈依賴並產生相應的錯誤。innodb引擎解決的死鎖的方案是將持有最少寫鎖的事務進行回滾。
為了提供回滾或者撤銷未提交的變化的能力,許多資料來源採用日誌機制。例如:sql server使用乙個預寫事務日誌,在將資料應用於(或提交到)實際資料頁面前,先寫在事務日誌上。但是,其他一些資料來源不是關係型資料庫管理系統,他們管理未提交事務的方式完全不同。只要事務回滾時,資料來源可以撤銷所有未提交的改變,那麼這種技術可用於事務管理。
mysql大多數事務型的儲存引擎都不只是簡單的行級鎖,基於效能的考慮,他們一般在行級鎖基礎上實現了多版本併發控制(mvcc)。這一方案也被oracle等主流的關聯式資料庫採用。它是通過儲存資料中某個時間點的快照來實現的,這樣就保證了每個事務看到的資料都是一致的。詳細的實現原理可以參考《高效能mysql》第三版。
1.事務具有acid的特性:
1)原子性:
事務中的所有操作要麼全部提交成功,要麼全部失敗回滾
比如你從取款機取錢,這個事務可以分成兩個步驟:1劃卡,2出錢.不可能劃了卡,而錢卻沒出來.這兩步必須同時完成.要麼就不完成.
2)一致性:
資料庫總是從乙個一致性的狀態轉換到另乙個一致性的狀態
例如,完整性約束了a+b=10,乙個事務改變了a,那麼b也應該隨之改變.不管資料怎麼改變。一定是符合約束
3)隔離性:
乙個事務所做的修改在提交之前對其它事務是不可見的
兩個以上的事務不會出現交錯執行的狀態.因為這樣可能會導致資料不一致.
4)永續性:
一旦事務提交,其所做的修改便會永久儲存在資料庫中。
如果不考慮隔離性,就會引發一些 讀和寫 的問題,以讀為例:
髒讀 :乙個事務讀到另乙個事務未提交的資料
不可重複讀 :乙個事務讀到了另乙個事務已經提交的update資料,導致多次查詢結果不一致
幻讀): 乙個事務讀到了另乙個事務已經提交的insert資料,導致多次查詢的結果不一樣
2.事務的隔離級別:
1)read uncommitted(讀未提交):
事務中的修改即使未提交也是對其它事務可見,可能發生髒讀、不可重複讀、幻讀。
2)read committed(讀提交):
事務提交後所做的修改才會被另乙個事務看見,可能產生乙個事務中兩次查詢的結果不同。可能發生不可重複讀、幻讀。
3)repeatable read(可重讀):
只有當前事務提交才能看見另乙個事務的修改結果。解決了乙個事務中兩次查詢的結果不同的問題。可能發生幻讀。
4)serializable(序列化):
只有乙個事務提交之後才會執行另乙個事務。髒讀、不可重複讀以及幻讀都可避免。
mysql採用外掛程式式的儲存引擎的架構,可以根據不同的需求為不同的表設定不同的儲存引擎
常用mysql儲存引擎介紹:
innodb引擎:將資料儲存在表空間中,表空間由一系列的資料檔案組成,由innodb管理。支援每個表的資料和索引存放在單獨檔案中(innodb_file_per_table);支援事務,採用mvcc來控制併發,並實現標準的4個事務隔離級別,支援外來鍵。索引基於聚簇索引建立,對主鍵查詢有較高效能。資料檔案的平台無關性,支援資料在不同的架構平台移植。能夠通過一些工具支援真正的熱備,如xtrabackup等;內部進行自身優化如採取可**性預讀,能夠自動在記憶體中建立bash索引等。
myisam引擎:mysql5.1預設,不支援事務和行級鎖,提供大量的特性如全文索引、空間函式、壓縮、延遲更新等。資料庫故障後,安全恢復性,對於唯讀資料可以忍受故障恢復,myisam依然非常適用 ,日誌伺服器的場景也比較適用,只需插入和資料讀取操作,不支援單錶乙個檔案,會將所有的資料和索引內容分別存放在兩個檔案中,myisam對整張表加鎖而不是對行,所以不適用寫操作比較多的場景,支援索引快取不支援資料快取。
MySQL執行機制
建立連線 connectors connection pool 通過客戶端 伺服器通訊協議與mysql建立連線。mysql 客戶端與服務端的通訊方式是 半雙工 對於每乙個 mysql 的連線,時刻都有乙個執行緒狀態來標識這個連線正在做什麼。id 執行緒id,可以使用kill xx user 啟動這個...
Mysql 一 mysql執行機制
全面了解mysql的執行機制,從而了解當前系統的瓶頸,找到優化方案。借用一張圖 從上圖可以清晰看出mysql的內部架構,可以清楚的看到mysql是由連線池connection pool,sql介面,解析器,優化器,快取,儲存引擎組成的。connectors 指的是不同語言中與sql的互動 manag...
PHP之執行機制與原理
php通過sapi與apache相連。php總共有三大模組 核心 處理網路請求 檔案流 錯誤處理等相關操作 zend引擎 將原始檔轉化成機器語言後在虛擬機器上執行它,虛擬機器就是zend引擎,簡稱ze 拓展層 函式 類庫 流 當ze執行程式時可能會需要連線多個拓展層,這時ze將控制權交給拓展,等待處...