《高性能MySQL》-MySQL架構

1、Mysql的邏輯架構
    a.大體將Mysql分爲3層:
        1.mysql客戶端,提供一些基本服務,好比鏈接處理、受權、安全等.
        2.第二層爲mysql提供的一些核心處理內容,好比查詢解析、分析、優化等.
        3.第三層則包含了mysql的存儲引擎,用於存儲和提取存放在mysql中的內容,服務器經過存儲引擎API和存儲引擎進行通訊,存儲引擎不會進行SQL解析(InnoDB是個例外,它會解析外鍵定義,由於MySQL服務器自身沒有實現它),也不會互相通訊,只是簡單的響應服務器的請求.
    b.鏈接管理和安全
        每一個客戶鏈接在服務器上都有本身的線程,每一個鏈接所屬的查詢都會在指定的某個單獨線程中完成,這些線程輪流的運行在某個cpu上,服務器負責緩存線程,所以沒必要爲每一個新鏈接重建或撤銷線程.
        當客戶端鏈接到服務器時,服務器要對其進行認證,認證基於用戶名、主機、口令,一旦鏈接成功,客戶端就會驗證該客戶端是否具備執行某個具體查詢.
    c.優化與執行
        MySQL會解析查詢,並建立一個內部數據結構(解析書),而後進行各類優化.其中包括從新查詢、決定查詢的讀寫順序、以及選擇使用的索引等.用戶能夠經過特殊的關鍵字給以優化器提示,影響它的決策過程.另外還能夠請求服務器給出優化的各類說明,使用戶能夠知道服務器是如何進行決策的.
        優化器並不關心某個表使用哪一種存儲引擎,但存儲引擎會對服務器的查詢優化有影響.優化器會請求存儲引擎爲某種具體操做×××能與開銷方面的信息以及表內部的統計信息.
        在解析查詢之前,服務器會詢問查詢緩存,它只能保持selelct語句和相應的結果,若是能在緩存中找到要執行的查詢,服務器就沒必要重新解析、優化、查詢.
2、併發控制
    不管什麼時候,只要不止一個查詢同時修改數據庫,都會產生併發控制的問題.
    a.讀鎖和寫鎖
        讀鎖和寫鎖又分別叫作共享鎖和排他鎖.
        某一資源上的讀鎖是共享的或者互不阻塞的,在同一時間裏多個用戶能夠讀取同一資源而互不干擾;寫鎖是排他的,一個寫鎖會阻塞其餘的讀鎖和寫鎖.
    b.鎖粒度
        任什麼時候間裏,在給定的資源上,被加鎖數據量越小就容許更多的併發操做,只要相互之間互不衝突便可.問題是加鎖也會消耗系統資源,每一種鎖操做,如得到鎖、檢查鎖是否已解除、解除鎖都會增長系統的開銷.
        鎖策略就是在鎖開銷和數據安全之間尋求一種平衡,這種平衡也能影響系統性能,每種MySQL存儲引擎均可以實現獨有的鎖策略和鎖粒度。如下是兩種重要的鎖策略
        表鎖:表鎖是MySQL開銷最小的鎖策略,它將整個表加鎖,當有一個用戶進行寫操做時,用戶會得到一個寫鎖,寫鎖會禁止其餘用戶任何的讀寫操做,只有無人作寫操做時用戶才能得到讀鎖,讀鎖之間互不衝突.寫鎖比讀鎖據用更高的優先級,即便有讀操做用戶排列在隊列中,新申請的寫操鎖仍然會排在隊列的前面(寫鎖會被安置在讀鎖以前,而讀鎖不能排在寫鎖以前).
        行級鎖:行級鎖支持最大的併發處理,同時也帶來最大的性能開銷,行級鎖由存儲引擎實現而不是MySQL服務器實現
3、事務
     事務是一組原子性的SQL查詢語句,也能夠看着一個工做單元.事務內的語句要麼所有執行要麼所有不執行.
     ACID:
     原子性(Atomicity):一個事務必須被視做一個單獨的內部不可分的工做單元,以確保一個事務要麼所有執行要麼所有回滾.
     一致性(Consistency):數據庫老是從一種一致性狀態轉換到另外一種一致性狀態,即任何事務處理過程當中做的數據改變都不會影響到數據庫的內容.
     隔離性(Isolation):某個事務的處理結果只有在完成以後纔對其餘事務可見.
     持久性(Durabilit):一旦一個事務提交,事務所作的數據改變將是永久的.
     a.隔離級
        SQL標準定義了4類隔離級,包括了一些具體規則,用來限定事務內外哪些改變是可見的哪些是不可見的.低級別的隔離級通常支持更高的併發處理,並擁有更低的系統開銷.
        1.READ UNCOMMITED(讀取未提交內容):不多實際應用
        2.READ COMMITED(讀取提交內容):大多數系統默認的隔離級,但不是MySQL默認的
        3.REPEATEABLE READ(可重讀):MySQL的默認隔離級
        4.SERIALIZABLE(可串行化):
     b.死鎖
      死鎖是指兩個或多個事務在同一資源上互相佔有並請求加鎖致使的惡性循環,多個事務以不一樣的順序加鎖同一資源是就會產生死鎖 .
      爲了解決這種問題,數據庫實現了多種死鎖檢測和死鎖超時機制.對於更復雜的系統,例如InnoDB存儲引擎可以預知循環相關性,並馬上返回錯誤(比較好),其餘的解決方法是讓查詢達到一個鎖等待超時時間,而後再放棄爭用(不夠好),目前InnooDB的處理死鎖的方法是回滾具備最少排他行級鎖的事務(一種對最易回滾事務的估算).
     c.事務日誌
     事務日誌可使事務處理更加高效.和每次數據一改變就更新數據表的數據不一樣,存儲引擎能夠先更新數據在內存中的拷貝,這很是快,而後存儲引擎會將數據改變記錄到事務日誌,事務日誌位於磁盤上,所以具備持久性,這相對較快,由於追加日誌致使的寫操做只涉及到了磁盤上很小的順序IO,而替代了寫磁盤中表所須要的大量隨機IO.最後系統會在某個時間把數據更新到磁盤上的表中.大多存儲引擎使用了此技術,也就是一般所說的預寫式日誌,利用2此磁盤操做將數據寫入磁盤.
     
     d.MySQL中的事務
        MySQL中默認操做是AUTOCOMMIT型的,這意味着除非顯示的開始一個事務,不然它將每個查詢視做一個單獨的事務自動執行.能夠經過設置變量啓用和禁用AUTOCOMMIT
        SHOW VARIABLES LIKE 'AUTOCOMMIT';//查看autocommit的值
        SET AUTOCOMMIT = 1;//修改autocommti的值
        MySQL容許用戶經過命令 SET SESSION TRANSATION ISOLATION    LEVEL設置隔離級,新的隔離級將在下一個事物開始時生效.用戶也能夠在配置文件中爲整個服務器設置隔離級;使用下列命令只會爲當前事務設置隔離級
        SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITED;
       
        在事務中混合使用事務性表和非事務性表,若是事務回滾,那麼在非事務性表上所作的修改將沒法取消.
       
        一個事務在任什麼時候候均可以得到鎖,但只有在commit或rollback的時候纔會釋放鎖,它會同時釋放掉全部鎖,通常狀況下InnoDB的鎖定都是隱式鎖,InnoDB會根據用戶的隔離級別自動出來鎖定.InnoDB也支持顯示鎖定,以下所示:
        SELECT ... LOCK IN SHARE MODE
        SELECT ... FOR UPDATE
       
        MySQL也支持LOCK TABLES 和 UNLOCK TABLES命令,這些命令由MySQL服務器實現,而不是存儲引擎.LOCK TABLE命令和事務處理之間的交互是比較複雜的,在某些服務器版本上可能出現一些不可預料的行爲,所以,除非是在一個事務中使用LOCK TABLES,同時AUTOCOMMIT模式是被禁止的,不然不管使用何種存儲引擎都不要使用LOCK TABLES 命令.
       
四.多版本併發控制
    大多數MySQL的事務性存儲引擎,不是簡單的使用行加鎖機制,而是選用一種叫作多版本併發控制(MVCC)的技術,和行加鎖機制關聯使用,以應對更多的併發處理問題.如下簡單描述InnoDB的簡化版的行爲方式來講明MVCC的工做原理:
    InnoDB經過爲每一個數據行添加兩個隱含值的方式來實現MVCC,這兩個隱含值記錄了行數據的建立時間和過時時間,每一行都存儲了事件發生時的系統版本號用來替代事件發生時的實際時間.每一次開始一個事務,系統版本號會自動增長.每一個事務都會保存它在開始時的"當前系統版本"的記錄,而每一個查詢都會根據事務的版本號,檢查每行數據的版本號.下面是事務隔離級別設置在REPEATABLE READ時,MVCC的實際操做:
    SELECT
        InnoDB檢查每行數據,確保它們符合兩個標準:1.InnoDB只查找版本早於(<=)當前事務版本號的數據,這確保了當前事務讀取的數據都是在事務開始前已經存在的,或者是由當前事務建立或修改的;2.數據行的刪除版本必須是未定義的,或是大於事務版本的,這保證了事務讀取的行在事務開始時是未被刪除的.只用經過了上述兩個測試纔會被當作查詢結果返回.
    INSERT
        InnoDB爲每一個行記錄當前版本號
    DELETE
        InnoDB爲每一個刪除行記錄刪除版本號,做爲刪除標識.
    UPDATE
        InnoDB爲每一個須要更新的行創建一個新的行拷貝,而且爲新的行拷貝記錄當前的系統版本號,同時也爲更新前的舊行記錄系統的版本號做爲舊的刪除版本標識.
    MVCC只工做在REPEATABLE READ和READ COMMITED兩個隔離級

五.MySQL的存儲引擎
    在文件系統中,MySQL會把每一個數據庫保存爲數據目錄下的一個子目錄.當建立一個數據表時,MySQL會在一個和表名同名的,以.frm爲後綴的文件中存儲表的定義.每種存儲引擎對錶的數據和索引的存儲方式有所不一樣,當表的定義是由MySQL服務器獨立處理.
    要獲知每張表適用何種存儲引擎,能夠適用命令SHOW TABLE STATUS
    SHOW TABLE STATUS LIKE 'table_name';
   
    a.MyISAM引擎
    MySQL的默認存儲引擎,在性能和可用特徵之間,MyISAM提供一種良好的平衡,這些特徵包括全文檢索、壓縮、空間函數.MyISAM不支持事務和行級鎖.
    存儲:
    通常來講,MyISAM將每一個表存儲成兩個文件:數據文件和索引文件.兩個文件的擴展名分別爲.MYD和.MYI,MyISAM的數據文件是平臺通用的.
    MyISAM表能夠包含動態行和靜態行(固定長度行),MySQL會根據表定義決定使用何種行數據.MyISAM表的可容納的行總數通常只限於數據庫服務器的磁盤空間大小,以及操做系統容許建立的最大文件大小.
    MyISAM特性:
    加鎖和併發:MyISAM對整張表進行加鎖,而不是行.讀取程序在讀取數據時在全部表上均可以得到共享鎖,而寫入程序能夠得到排他鎖.用戶在容許select查詢時能夠在同一張表中插入新行.
    自動修復:MySQL支持對MyISAM表的自動檢測和自動修復
    手工修復:用戶可使用命令CHECK TABLE table_name 和 REPAIR TABLE table_name 檢測表錯誤並修復表錯誤,當服務器離線時可使用命令行工具myisamchk檢測和修復表.
    索引特性:在MyISAM表中,用戶能夠基於BLOB或TEXT類型列的前500個字符建立相關索引.MyISAM支持全文索引,它能夠根據個別單詞爲複雜的的搜索選項建立相關索引.
    延遲更新索引:使用表建立選項DELAY_KEY_WRITE建立表時,在查詢結束後不會將索引的改變寫入磁盤,而是在內存中的鍵緩存區緩存索引改變數據,它只會在清理緩存數據或關閉表時纔將索引數據轉儲到磁盤.對於數據常常改變而且使用頻繁的表,這種模式大大提升了表的處理能力,不過若是服務器或系統崩潰索引必將損壞,並須要修復
    壓縮MyISAM表:某些表一旦被建立和填寫數據以後,數據將永不改變.這種類型的表很是適合選用壓縮的MyISAM表.使用myisampack實用工具能夠對錶進行壓縮,壓縮表佔有的空間很小使之能夠提升更好的處理性能.壓縮表也能夠擁有索引,但這些索引也是隻讀的.
   
    b.InnoDB存儲引擎
    InnoDB專爲事務處理設計的一款存儲引擎,特別是用於處理大量短時間事務,短時間事務是指通常能正常完成不需回滾的事務.
    InnoDB將數據存儲在一個或幾個數據文件之中,這種數據文件通常稱之爲表空間,表空間本質上是一種"黑盒",在"黑盒"內,InnoDB自我管理一切數據.
    InnoDB使用MVCC機制獲取高併發性能,而且實現了全部四個標準隔離級別,它的默認隔離級是REPEATABLE READ,在這個隔離級上,它使用了間隙鎖策略防止幻讀的產生,不只對查詢中讀取的行進行加鎖,並且還對索引結構中的間隙進行加鎖,防止幻影插入.
    InnoDB表是基於聚族索引創建的,InnoDB的索引結構很是不一樣於其餘大多數MySQL存儲引擎,所以它提供了一種很是快速的主鍵查找性能.不過它的非主鍵索引也會包含主鍵列,若是主鍵定義特別大,其餘索引也將和大,若是想在表上定義和多索引則儘可能將主鍵定義小一些,InnoDB不會壓縮處理
    InnoDB不會根據排序創建索引,而MyISAM支持,所以,當InnoDB加載數據和建立索引時會比MyISAM慢不少,任何改變InnoDB表結構的操做會致使整個表的重建包括重建全部索引.
    除了高併發處理能力以外,InnoDB另一個廣爲人知的特性是它的外鍵約束,這個特性是MySQL服務器自身都未能提供的
   
    c.錶轉換
    有幾種方法能夠將表從一種存儲引擎轉換成另一種.
    1.ALTER TABLE
    ALTER TABLE table_name ENGINE = InnoDB;
    這種語法適合全部存儲引擎,不過這裏有一個陷阱:這種轉換會耗費大量時間.MySQL要執行一箇舊表到新標的逐行復制.
    2.DUMP和IMPORT
    3.CREATE和SELECT
    mysql

相關文章
相關標籤/搜索