MySQL-體系結構

 

一.MySQL體系架構

 

 

一、Mysql是由SQL接口,解析器,優化器,緩存,存儲引擎組成的(SQL Interface、Parser、Optimizer、Caches&Buffers、Pluggable Storage Engines)mysql

第一層:客戶端redis

  並非MySQL獨有的技術,它們都是服務於C/S程序或者是這些程序所須要的 :鏈接處理,身份驗證,安全性等等算法

(1) Connectors指的是不一樣語言中與SQL的交互 (並非MySQL獨有的技術,它們都是服務於C/S程序或者是這些程序所須要的 :鏈接處理,身份驗證,安全性等等)sql

第二層:SQL Layer。MySQL的核心部分數據庫

  這是MySQL的核心部分。一般叫作 SQL Layer。在 MySQL據庫系統處理底層數據以前的全部工做都是在這一層完成的,包括權限判斷, sql解析,行計劃優化, query cache 的處理以及全部內置的函數(如日期,時間,數學運算,加密)等等。各個存儲引擎提供的功能都集中在這一層,如存儲過程,觸發器,視 圖等。緩存

(2)Management Serveices & Utilities: 系統管理和控制工具,例如備份恢復、Mysql複製、集羣等 
(3)Connection Pool: 鏈接池:管理緩衝用戶鏈接、用戶名、密碼、權限校驗、線程處理等須要緩存的需求 
(4)SQL Interface: SQL接口:接受用戶的SQL命令,而且返回用戶須要查詢的結果。好比select from就是調用SQL Interface 
(5)Parser: 解析器,SQL命令傳遞到解析器的時候會被解析器驗證和解析。解析器是由Lex和YACC實現的,是一個很長的腳本, 主要功能: 
a . 將SQL語句分解成數據結構,並將這個結構傳遞到後續步驟,之後SQL語句的傳遞和處理就是基於這個結構的 
b. 若是在分解構成中遇到錯誤,那麼就說明這個sql語句是不合理的 
(6)Optimizer: 查詢優化器,SQL語句在查詢以前會使用查詢優化器對查詢進行優化。他使用的是「選取-投影-聯接」策略進行查詢。 
用一個例子就能夠理解: select uid,name from user where gender = 1; 
這個select 查詢先根據where 語句進行選取,而不是先將表所有查詢出來之後再進行gender過濾 
這個select查詢先根據uid和name進行屬性投影,而不是將屬性所有取出之後再進行過濾 
將這兩個查詢條件聯接起來生成最終查詢結果安全

(7) Cache和Buffer(高速緩存區): 查詢緩存,若是查詢緩存有命中的查詢結果,查詢語句就能夠直接去查詢緩存中取數據。 
經過LRU算法將數據的冷端溢出,將來得及時刷新到磁盤的數據頁,叫髒頁。 
這個緩存機制是由一系列小緩存組成的。好比表緩存,記錄緩存,key緩存,權限緩存等 服務器

第三層:存儲引擎層數據結構

  一般叫作StorEngine Layer ,也就是底層數據存取操做實現部分,由多種存儲引擎共同組成。它們負責存儲和獲取全部存儲在MySQL中的數據。就像Linux衆多的文件系統 同樣。每一個存儲引擎都有本身的優勢和缺陷。服務器是經過存儲引擎API來與它們交互的。這個接口隱藏 了各個存儲引擎不一樣的地方。對於查詢層儘量的透明。這個API包含了不少底層的操做。如開始一個事 物,或者取出有特定主鍵的行。存儲引擎不能解析SQL,互相之間也不能通訊。僅僅是簡單的響應服務器 的請求多線程

(8)Engine :存儲引擎。存儲引擎是MySql中具體的與文件打交道的子系統。也是Mysql最具備特點的一個地方。 
Mysql的存儲引擎是插件式的。它根據MySql AB公司提供的文件訪問層的一個抽象接口來定製一種文件訪問機制(這種訪問機制就叫存儲引擎) 
如今有不少種存儲引擎,各個存儲引擎的優點各不同,最經常使用的MyISAM,InnoDB,BDB 
默認下MySql是使用MyISAM引擎,它查詢速度快,有較好的索引優化和數據壓縮技術。可是它不支持事務。 
InnoDB支持事務,而且提供行級的鎖定,應用也至關普遍。 
Mysql也支持本身定製存儲引擎,甚至一個庫中不一樣的表使用不一樣的存儲引擎,這些都是容許的 

 

一條SQL的執行過程

 MySQL是單進程,多線程

鏈接管理和安全

在服務器內部,每一個client鏈接都有本身的線程。這個鏈接的查詢都在一個單獨的線程中執行。這些線程輪流運行在某一個CPU內核(多核CPU)或者CPU中。服務器緩存了線程,所以不須要爲每一個client鏈接單首創建和銷燬線程 。

當clients(也就是應用程序)鏈接到了MySQL服務器。服務器須要對它進行認證(Authenticate)。認證是基於用戶名,主機,以及密碼。對於使用了SSL(安全套接字層)的鏈接,還使用了X.509證書。clients一鏈接上,服務器就驗證它的權限 (如是否容許客戶端能夠查詢world數據庫下的Country表的數據)。

優化和執行

MySQL會解析查詢,並建立了一個內部數據結構(解析樹)。而後對其進行各類優化。這些優化包括了,查詢語句的重寫,讀表的順序,索引的選擇等等。用戶能夠經過查詢語句的關鍵詞傳遞給優化器以便提示使用哪一種優化方式,這樣即影響了優化器的優化方式。另外,用戶也能夠請求服務器給出優化過程的各類說明,以獲知服務器的優化策略,爲用戶提供了參數基準,以便用戶能夠重寫查詢,架構和修改相關服務器配置,便於mysql更高效的運行。

優化器並是不關心表使用了哪一種存儲引擎,可是存儲引擎對服務器優化查詢的方式是有影響的。優化器須要知道存儲引擎的一些特性:具體操做的性能和開銷方面的信息,以及表內數據的統計信息。例如,存儲引擎支持哪些索引類型,這對於查詢是很是有用的。

在解析查詢以前,要查詢緩存,這個緩存只能保存查詢信息以及結果數據。若是請求一個查詢在緩存 中存在,就不須要解析,優化和執行查詢了。直接返回緩存中所存放的這個查詢的結果。

二.MySQL內存結構

Mysql 內存分配規則是:用多少給多少,最高到配置的值,不是當即分配。

實際上MySQL內存的組成和Oracle相似,也能夠分爲SGA(系統全局區)和PGA(程序緩存區)。

mysql>show variables like "%buffer%";

1、SGA

1.innodb_buffer_pool

用來緩存Innodb表的數據、索引、插入緩衝、自適應哈希索引,鎖信息,數據字典等信息。

2.innodb_log_buffer

事務在內存中的緩衝,即red log buffer的大小

3.query cache

高速查詢緩存,在生產環境中建議關閉。

4.key_buffer_size

用於MyISAM存儲引擎,緩存MyISAM存儲。

引擎表的索引文件(區別於innodb_buffer_poll數據和索引緩存)

5.innodb_additional_mem_pool_size

用來緩存數據字典信息和其它內部數據結構的內存池的大小。MySQL5.7.4中該參數取消。

 

2、PGA

1.sort_buffer_size(排序緩衝大小,提升排序效率)

主要用於SQL語句在內存中的臨時排序

2.join_buffer_size

錶鏈接使用,用於BKA,MySQL5.6以後開始支持。

3.read_buffer_size(順序讀緩衝大小,提升順序都效率)

表順序掃描的緩存,只能應用於MyISAM表存儲引擎。

4.read_rnd_buffer_size(隨機緩衝大小,提升隨機都效率)

MySQL隨機讀緩衝區大小,用於作mrr,mrr是MySQL5.6以後纔有的特性。

5.tmp_table_size

SQL語句在排序或分組時沒有用到索引,就會使用臨時表空間。

6.max_heap_table_size

管理heap,memory存儲引擎表。

 


一、全局內存(Global buffer)

(1)innodb_buffer_pool_size:

(1.1) innodb高速緩衝data和索引,簡稱IBP,這個是Innodb引擎中影響性能最大的參數。建議將IBP設置的大一些,單實例下,建議設置爲可用RAM的50%~80%。 (1.2)innodb不依賴OS,而是本身緩存了全部數據,包括索引數據、行數據等等,這個和myisam有差異。 (1.3)IBP有一塊buffer用於插入緩衝,在插入時,先寫入內存以後再合併後順序寫入磁盤;在合併到磁盤的時候會引起較大的IO操做,對實際操做形成影響。(看上去的表現是抖動,TPS變低) (1.4)show global status like ‘innodb_buffer_pool_%’ 查看IBP狀態,單位是page(16kb),其中,Innodb_buffer_pool_wait_free 若是較大,須要加大IBP設置 (1.5)InnoDB會定時(約每10秒)將髒頁刷新到磁盤,默認每次刷新10頁;要是髒頁超過了指定數量(innodb_max_dirty_pages_pct),InnoDB則會每秒刷100頁髒頁 (1.6)innodb_buffer_pool_instances能夠設置pool的數量 (1.7)show engine innodb status\G 能夠查看innodb引擎狀態

 

(2)innodb_additional_mem_pool_size:

(2.1)指定InnoDB用來存儲數據字典和其餘內部數據結構的內存池大小。缺省值是8M(8388608)。一般不用太大,只要夠用就行,應該與表結構的複雜度有關係。若是不夠用,MySQL會在錯誤日誌中寫入一條警告信息。5.7版本已經棄用這個參數

(3)innodb_log_buffer_size:

(3.1)innodb redo日誌緩衝,提升redo寫入效率。若是表操做中包含大量併發事務(或大規模事務),而且在事務提交前要求記錄日誌文件,請儘可能調高此項值,以提升日誌效率。
(3.2)show global status 查看 Innodb_log_waits 是否大於0,是的話,就須要提升 innodb_log_buffer_size,不然維持原樣。
(3.3)show global stauts 查看30~60秒鐘 Innodb_os_log_written 的間隔差別值,便可計算出 innodb_log_buffer_size 設置多大合適。

默認8M,通常設置爲16 ~ 64M足夠了。 
 
(4)key_buffer_size:

(4.1)myisam引擎中表的索引 的緩存大小,默認值=16M;單個key_buffer_size最大隻有4G(32-bit系統下最大4G,64-bit下能夠超過)
(4.2)若主要使用myisam存儲引擎,則設置最高不超過物理內存的20%~50%,
(4.4)即使全是innodb表,沒用MyISAM,也有必要設置key_buffer_size用於緩存臨時表的索引,推薦設置32MB
(4.5)關於臨時表,若是內存tmp_table_size(Created_tmp_tables)不夠的話,內部的臨時磁盤表是MyISAM表(Created_tmp_disk_tables)。show global status like 'Create%'; show variables like 'tmp%';

(5)query_cache_size :

查詢高速緩衝,緩存結果,減小硬解析(建議關閉,若是真須要查詢緩存能夠藉助redis等緩存),最好是關閉

(6)table_definition_cache:

(6.1)表定義文件描述緩存,提升表打開效率。是frm文件在內存中的映射。MySQL須要打開frm文件,並將其內容初始化爲Table Share 對象。這裏存放與存儲引擎無關的,獨立的表定義相關信息。

(7)table_open_cache:

(7.1)表空間文件描述緩衝,提升表打開效率。
(7.2)增長table_open_cache,會增長文件描述符(ulimit -a查看系統的文件描述符),當把table_open_cache設置的過大時,若是系統處理不了這麼多文件描述符,那麼就會出現客戶端失效、鏈接不上。
(7.3)table_open_cache,也就是平時說的table cache。存放當前已經打開的表句柄,與表建立時指定的存儲引擎相關。請注意和table_define_cache參數的區別。

爲何MySQL會出現table_open_cahce和table_define_cache這兩個概念? 
是由於:MySQL支持不一樣的存儲引擎,每種存儲引擎,數據存儲的格式都是不同的,所以須要指定一個存儲引擎相關的handler。這就有了table cache的做用(table_open_cache參數)。另外表的定義也須要存放內存中,而表的定義frm文件每一個存儲引擎是通用的,須要另外獨立開來,這就有了table definition cache。

(8)max_heap_table_size和tmp_table_size:

(8.1)max_heap_table_size 參數:定義了MEMORY、HEAP表的最大容量,若是內存不夠,則不容許寫入數據
(8.2)tmp_table_size參數:規定了內部內存臨時表的最大值,每一個線程都要分配。(實際起限制做用的是tmp_table_size和max_heap_table_size的最小值。)若是內存臨時表超出了限制,MySQL就會自動地把它轉化爲基於磁盤的MyISAM表,存儲在指定的tmpdir目錄下。
(8.3)優化查詢語句的時候,要避免使用臨時表,若是實在避免不了的話,要保證這些臨時表是存在內存中的,不然臨時表超過內存臨時表的限制,會自動轉化爲基於磁盤的Myisam表。

二、線程內存(Thread buffer)

(1)read_buffer_size:

是MySQL讀入緩衝區大小。對錶進行順序掃描的請求將分配一個讀入緩衝區,MySQL會爲它分配一段內存緩衝區。read_buffer_size變量控制這一緩衝區的大小。若是對錶的順序掃描請求很是頻繁,而且你認爲頻繁掃描進行得太慢,能夠經過增長該變量值以及內存緩衝區大小提升其性能。

(2)read_rnd_buffer_size:

是MySQL的隨機讀緩衝區大小。當按任意順序讀取行時(例如,按照排序順序),將分配一個隨機讀緩存區。進行排序查詢時,MySQL會首先掃描一遍該緩衝,以免磁盤搜索,提升查詢速度,若是須要排序大量數據,可適當調高該值。但MySQL會爲每一個客戶鏈接發放該緩衝空間,因此應儘可能適當設置該值,以免內存開銷過大。

(3)sort_buffer_size:

是MySQL執行排序使用的緩衝大小。若是想要增長ORDER BY的速度,首先看是否可讓MySQL使用索引而不是額外的排序階段。若是不能,能夠嘗試增長sort_buffer_size變量的大小。

(4)join_buffer_size:

應用程序常常會出現一些兩表(或多表)Join的操做需求,MySQL在完成某些 Join 需求的時候(all/index join),爲了減小參與Join的「被驅動表」的讀取次數以提升性能,須要使用到 Join Buffer 來協助完成 Join操做。當 Join Buffer 過小,MySQL 不會將該 Buffer 存入磁盤文件,而是先將Join Buffer中的結果集與須要 Join 的表進行 Join 操做,而後清空 Join Buffer 中的數據,繼續將剩餘的結果集寫入此 Buffer 中,如此往復。這勢必會形成被驅動表須要被屢次讀取,成倍增長 IO 訪問,下降效率。

(5)binlog_cache_size:

在事務過程當中容納二進制日誌SQL 語句的緩存大小。二進制日誌緩存是服務器支持事務存儲引擎而且服務器啓用了二進制日誌(—log-bin 選項)的前提下爲每一個客戶端分配的內存,注意,是每一個Client 均可以分配設置大小的binlog cache 空間。若是系統中常常會出現多語句事務的話,能夠嘗試增長該值的大小,以得到更好的性能。固然,咱們能夠經過MySQL 的如下兩個狀態變量來判斷當前的binlog_cache_size 的情況:Binlog_cache_use 和Binlog_cache_disk_use。「max_binlog_cache_size」:和"binlog_cache_size"相對應,可是所表明的是binlog 可以使用的最大cache 內存大小。當咱們執行多語句事務的時候,max_binlog_cache_size 若是不夠大的話,系統可能會報出「 Multi-statement transaction required more than 'max_binlog_cache_size' bytes ofstorage」的錯誤。
其中須要注意的是:table_cache表示的是全部線程打開的表的數目,和內存無關。

(6)tmp_table_size:

是MySQL的臨時表緩衝大小。全部聯表查詢在一個DML指令內完成,而且大多數聯合甚至能夠不用臨時表便可以完成。大多數臨時表是基於內存的(HEAP)表。具備大的記錄長度的臨時表 (全部列的長度的和)或包含BLOB列的表存儲在硬盤上。若是某個內部heap(堆積)表大小超過tmp_table_size,MySQL能夠根據須要自動將內存中的heap表改成基於硬盤的MyISAM表。還能夠經過設置tmp_table_size選項來增長臨時表的大小。也就是說,若是調高該值,MySQL同時將增長heap表的大小,可達到提升聯接查詢速度的效果。

(7)thread_stack :

主要用來存放每個線程自身的標識信息,如線程id,線程運行時基本信息等等,咱們能夠經過 thread_stack 參數來設置爲每個線程棧分配多大的內存。每一個鏈接線程被建立時,MySQL給它分配的內存大小。當MySQL建立一個新的鏈接線程時,須要給它分配必定大小的內存堆棧空間,以便存放客戶端的請求的Query及自身的各類狀態和處理信息。

(8)thread_cache_size:

若是咱們在MySQL服務器配置文件中設置了thread_cache_size,當客戶端斷開以後,服務器處理此客戶的線程將會緩存起來以響應下一個客戶而不是銷燬(前提是緩存數未達上限)。

(9)net_buffer_length:

客戶發出的SQL語句指望的長度。若是語句超過這個長度,緩衝區自動地被擴大,直到max_allowed_packet個字節。

(10)bulk_insert_buffer_size:

若是進行批量插入,能夠增長bulk_insert_buffer_size變量值的方法來提升速度,可是,這隻能對myisam表使用。

三、overhead

(1)自適應哈希索引(Adaptive index hash)

(1.1)哈希索引是一種很是快的等值查找方法(注意:必須是等值,哈希索引對非等值查找方法無能爲力),它查找的時間複雜度爲常量,InnoDB採用自適用哈希索引技術,它會實時監控表上索引的使用狀況,若是認爲創建哈希索引能夠提升查詢效率,則自動在內存中的「自適應哈希索引緩衝區」中創建哈希索引。
(1.2)之因此該技術稱爲「自適應」是由於徹底由InnoDB本身決定,不須要DBA人爲干預。它是經過緩衝池中的B+樹構造而來,且不須要對整個表創建哈希索引,所以它的數據很是快。
(1.3)InnoDB官方文檔顯示,啓用自適應哈希索引後,讀和寫性能能夠提升2倍,對於輔助索引的鏈接操做,性能能夠提升5被,所以默認狀況下爲開啓,能夠經過參數innodb_adaptive_hash_index來禁用此特性。
(1.4)哈希索引老是基於表上已存在的B樹索引來創建的。InnoDB會在爲該B樹定義的鍵的一個前綴上創建哈希索引,無論該鍵有多長。哈希索引能夠是部分的:它不要求整個B樹索引被緩存在緩衝池中。InnoDB根據須要對被常常訪問索引的那些頁面創建哈希索引。

(2)System dictionary hash (3)Locking system (4)Sync_array (5)Os_events

相關文章
相關標籤/搜索