1、mysql基本介紹
mysql支持多線程高並發的關系型數據庫;
數據庫存儲引擎InnoDB、MyISAM;
mysql快速崛起的原因就是他是開源的;
性能一直是mysql自豪的一大特點;
2、mysql架構組成
麻雀雖小五臟俱全,mysql雖然簡單但其內部結構並不簡單;
mysql物理文件組成之日志文件:
錯誤日志error log這里記錄mysql運行時嚴重的警告和錯誤,以及mysql啟動和關閉的日志信息
二進制日志 binary log 記錄mysql運行時所有的query和query執行的時間保存為二進制信息
查詢日志 query log 記錄所有query 包括select語句 體積較大開啟后對性能有所影響
慢查詢日志 slow query log 記錄慢查詢的日志信息
mysql物理文件組成之數據文件:
每一個數據庫都會在定義好的數據目錄下存在一個以數據庫名字命名的文件夾,用來存放某個數據庫各個表的數據信息;
不同的數據存儲引擎有着不同的數據文件;
.frm拓展名的文件:不論是存儲引擎,每個表都會有一個以表名.frm的文件,存放的是表結構的定義
.MYD拓展名的文件:MyISAM存儲引擎專用,存放表數據,每一個表都會存在一個以表名.MYD的文件
.MYI拓展名的文件:MyISAM存儲引擎專用,存放表索引數據,每個表都會存在一個以表名.MYI的文件
.ibd、.ibdata文件:InnoDB存儲引擎專用,存放表數據和表索引,區別在於.ibd是獨立存儲每個表信息,每個表都有一個表名.idb文件這點和MyISAM一樣,而ibdata文件是共享表空間存儲數據信息;
mysql server系統架構之邏輯模塊組成:
mysql可以看成是二層架構,第一層是sql layer,在mysql數據庫系統處理底層數據之前的所有工作都在這一層完成,包括權限判斷、sql解析、執行計划優化、query cache等工作,第二層是存儲引擎層也就是數據存儲實現的部份,有多種存儲引擎組成;
雖然只有兩個層但是每個層都有很多模塊組成,也是相當的復雜;
sql layer層包含:(optimizer 優化程序)
初始化、核心Api、網絡交互、client & server交互協議、用戶模塊、訪問控制模塊、
連接管理連接線程管理、query解析和轉化、query cache、query優化器、表變更管理、
表維護、系統狀態管理、表管理、日志記錄、復制、存儲引擎接口管理
mysql自帶工具使用介紹:
mysql提供大量的客戶端工具程序mysql、mysqladmin、mysqldump...
3、mysql存儲引擎
mysql存儲引擎概述:
MyISAM儲存引擎是mysql默認的存儲引擎;
Innodb存儲引擎是第三方插件式存儲引擎,是innobase公司開發,其最大特點是提供事務控制等功能;
MyISMA儲存引擎簡介:
MyISMA存儲引擎的表在數據庫中每一個表都被存放到三個以表名命名的物理文件中,分別是存放表結構定義的表名.frm文件、表數據表名.MYD文件、表索引表名.MYI文件;
MyISAM索引類型有三種:B-Tree、R-Tree、full-text,常用B-Tree類型索引;
MyISAM存儲引擎有靜態固定長度存儲FIXED、動態可變長度存儲DYNAMIC、壓縮存儲COMPRESS;
MyISAM儲存引擎中某個表數據文件出錯后不會影響到其他表或其他數據信息;
Innodb存儲引擎簡介:
mysql中除了MyISAM存儲引擎之外適用作廣泛就是Innodb存儲引擎,他和MyISAM一樣遵循開源license協議;
Innodb的優點就是提供了事務控制功能;
Innodb提升了MyISAM鎖的機制,實現了行鎖功能;
Innodb的數據存儲和MyISAM也不一樣,雖然也有表結構定義信息表名.frm文件,表數據和表索引是在一個文件里面存儲.ibd單獨的存儲、.ibdata共享存儲;
Innodb的物理結構可以分成兩大類:
數據文件(存放表數據和表索引數據).ibd單獨的存儲、.ibdata共享存儲兩種類型;
日志文件:請不要全部刪除Innodb的日志文件這樣會讓數據庫crash(崩潰),或提示數據丟失;
Memory存儲引擎:
Memory存儲引擎就是把數據存儲在內存里面的一種引擎;
Memory存儲引擎不會把數據存儲在磁盤,存入磁盤的只是表名.frm結構,因此如果數據庫crash或者宕機都會導致數據丟失;
小結:多存儲引擎是mysql有別於其他數據庫的一大特性;后續對常用的存儲引擎會進行詳情介紹;
4、mysql安全管理
對企業來說數據庫保存的數據的安全性是非常重要的;
數據失去了安全性就等於失去了一切;
數據庫系統安全相關因素:
外圍網絡安全:mysql是基於網路環境的,而網絡本身就存在一種入侵的威脅;要從最外層預防;
盡量讓mysql存在有保護的局域網環境中;
主機防御:外圍網絡預防得到了保護,那么還是會存在入侵的可能,那就是局域網入侵;
主要是阻止沒有授權的設備連接mysql;
入侵數據庫危害盜取數據、刪除數據、制造漏洞;
數據庫防御:通過第二道防線我們可以預防一部分威脅,可是允許使用主機登錄的設備是否
完全擁有權限呢?是否是可信任的對象呢?
數據庫防線是mysql自身系統的訪問控制授權模塊,這道防線是mysql入侵的最后一道防線了;
設置登錄用戶名和密碼和端口號並並設置權限;
代碼防御:sql語句相關安全因素、sql注入攻擊、程序代碼相關安全因素
DDL、DML、DCL
數據庫定義語言(CREATE ALTER DROP TRUNCATE)
數據庫操作語言(SELECT INSERT UPDATE DELETE EXPLAN)
數據庫控制語言(COMMIT ROLLBACK)
mysql訪問控制實現原理:
mysql訪問控制其實有2部分組成:一是用戶模塊管理、一是訪問控制模塊管理(權限);
用戶模塊決定是否能進入,訪問控制模塊(權限)決定能有哪些操作;
例如:客戶端請求(提供host,用戶名,密碼)-->用戶模塊驗證(通過mysql.user表驗證)-->
客戶端請求query(DML、DDL)-->解析query執行權限-->權限匹配查找(grant tables中查找)
-->發往后端繼續執行
mysql訪問授權策略:
不是每個用戶的權限都一樣無限大;
每個用戶的權限做到越小越好,滿足使用就好;
首先了解來訪主機、了解用戶需求、最后為工作分類,這樣確保絕對必要擁有者擁有grant(准許)權限;
備注:安全無小事,數據是一個企業的財富;
5、mysql數據的備份與恢復
數據庫備份使用的場景:
數據丟失應用場景:人為誤操作、軟件bug、硬件故障、安全漏洞
非數據丟失場景:特殊場景下數據恢復、開發測試數據庫搭建、數據庫或數據遷移
備注:數據庫數據備份解決問題不是萬能的;
6、影響mysql server性能的相關因素
大多都認為數據庫應用系統的性能瓶頸是數據庫管理軟件和數據庫主機自身造成的,其實不然;
下面以mysql數據庫web場景為例來分析影響性能的瓶頸;
商業需求對性能的影響:
不是所有功能都能實現,有些不合理的功能反而最后成了累贅,消耗資源;
不合理的需求造成資源投入產出比過低;
無用功能堆積使系統過度復雜影響整體性能;(無用的功能大多不會下線,因為考慮風險,所以系統越來越龐大復雜,不僅維護困難,系統性能也越來越差)
系統架構及實現對性能的影響:
一個web應用自然離不開應用程序(web application)和web應用程序服務器(web server),web server我們控制調優的不多都是很成熟的產品,web application我們可以優化很多方面;
以下幾類數據不適合存放到數據庫中:
二進制多媒體數據(消耗內存、消耗cpu);
流水隊列數據(不斷的進行insert update delete因為每次操作都會寫入日志文件影響性能);
超大文本數據(占用空間浪費資源)
是否合理利用應用層cache機制:mysql memory存儲引擎
通過cache機制成功的案例很多很多,可是失敗的案例也很多;
下面整理哪些可以使用cache機制:
系統各種配置和規則的數據;
活躍用戶的基本信息(緩存用戶的基本信息可以大大提升性能);
時間段的統計數據;
訪問平凡更新較少的數據;
過度依賴數據庫sql語句的功能造成數據庫操作效率低下:
盡量不要在循環中多次執行sql,有時可以使用2個sql,這樣不占用IO和解析資源;
如果一條sql查詢的列不是全部使用時請拆分成2個sql,減少不適用列的查詢;
避免重復執行相同的sql浪費資源(這里可能和上面兩條像違背,分不同邏輯考慮取舍)
架構設計不當帶來性能問題和資源浪費問題:
cache命中率低,增加數據庫的訪問壓力,浪費cache資源利用率;
過度依賴面向對象,對可拓展性的過度追求;
對數據庫的過度依賴,一些不符合存入數據庫的應該存入文件系統中;
過度的在乎用戶體驗,比如不用實時更新的數據實時更新了浪費資源;
query語句對性能的影響:
當mysql的連接線程接收到client請求的sql時,會經過解析和分析,然后通過執行計划調用存儲過程接口,最后把數據返回給client顯示;
執行sql主要是IO消耗和cpu消耗(這里可以通過explain進行測試);
備注:有時間測試下兩個表先連接查詢和先查詢一個表信息在和另一個表連接分析哪個好?
schema(方案)的設計對系統性能的影響:
數據庫設計對性能的提升;
適當的使用好范式是對設計最大的調優;
硬件環境對性能的影響:
考慮並發訪問比較頻繁的時候要考慮服務器IO和CPU處理能力;
7、mysql數據庫鎖定機制
為了保證數據的完整性任何一種數據庫都有鎖定的機制;
一個數據庫鎖定技術的優劣直接影響數據庫高並發處理和性能;
mysql常用存儲引擎Innodb、MyISAM
mysql鎖定機制簡介:
行級鎖定:
行級鎖定最大的特點就是對象的顆粒度很小,是最常用的一種形式;
由於鎖定顆粒下取鎖和鎖定處理的事情比較多,耗內存,也最容易發生死鎖;
表級鎖定:
表級鎖定與行級鎖定的特點正好相反,是鎖定mysql存儲引擎中最大的顆粒;
表鎖定邏輯簡單、處理快、耗能小、不容易死鎖;
頁級鎖定:
頁級鎖定是mysql一個比較獨特的鎖定機制,鎖定介於行鎖和表鎖之間;
頁級鎖定和行級鎖定一樣,很容易被死鎖;
備注:行級鎖定不是mysql自己的鎖定機制,而是第三方Innodb存儲引擎的鎖定機制;
Innodb如果產生死鎖時會通過檢測死鎖機制來判斷要回滾那個事務sql,這里會根據影響數據的大小來判斷,讓影響數據大的事務sql執行成功,回滾影響小的事務sql;或者通過死鎖機制過期時間來回滾事務sql;
Innodb行級鎖的優點:
在很多線程請求不同記錄時減少沖突;
事務回滾時減少改變的數據;
使長時間對單獨的一行記錄加鎖成為可能;
Innodb行鎖的缺點:
比表級別鎖和頁級別鎖消耗更多的內存;
合理的利用鎖機制優化mysql:
MyISAM的表鎖優化建議:
MyISAM的表鎖比行鎖和頁鎖減小了資源,但是一定程度上影響了並發的性能,
因此優化表鎖的建議就是如何提高並發的性能;
縮短鎖定時間;
唯一的辦法讓sql執行時間盡可能的短;
龐大復雜的sql建議分成多個小sql分布式執行;
盡可能的建立高效的索引和字段類型限制;
分離能並行的操作;
合理利用讀寫優先級;
Innodb行鎖的優化建議:
Innodb的行鎖機制雖然比MyISAM的表鎖機制消耗很大的資源但是高並發卻遠遠超於后者;
Innodb的行鎖也有瓶頸的一面:
查詢盡量使用索引提高查詢速度;
合理的設計索引;
查詢的范圍不應過大;
系統鎖定情況查詢:
表鎖定情況查詢:
SHOW STATUS LIKE '%table%';
Table_locks_immediate 表鎖定的次數
Table_locks_waited 表鎖定等待的次數
Table_locks_waited如果數值變大了說明表爭用比較嚴重,需要優化;
Innodb行鎖的情況查詢:
SHOW STATUS LIKE '%innodb_row_lock%';
Innodb_row_lock_current_waits //當前正在等待鎖定的數量
Innodb_row_lock_time //從系統啟動到現在鎖定總時間長度
Innodb_row_lock_time_avg //每次等待所花費的平均時間
Innodb_row_lock_time_max //某次等待最長的時間
Innodb_row_lock_waits //從系統啟動到現在請求的次數
上述分析:重要的是1 3 5這幾個值
Innodb存儲引擎的整體性能要高於MyISAM存儲引擎
8、mysql數據庫中query的優化
mysql query optimizer:
mysql query optimizer 是query查詢優化器模塊,提供最優的執行計划;
query語句優化的思路和原則:
優化更需要優化的query;
定位優化對象的性能瓶頸;//是IO還是CPU還是內存
明確的優化目標;
多使用show profiles;
從explain sql入手; //因為它可以展示執行計划詳細信息
最可能的在索引中排序;
只取出自己需要的columns;
使用最有效的過濾條件;
盡可能避免復雜的join和子查詢;
優化更需要優化的query:
兩個query每小時執行的IO數是一樣的,一個是每小時執行10000次每次消耗20個IO,
一個是每小時執行10次每次消耗20000個IO那么試問該優化哪個query呢?
解答:第一個query把IO從20降到18就減少了2個,那么就2*10000 = 20000個IO
第二個query如果能減少20000個IO那么20000/10 = 2000個IO那么每次需減少2000個IO
因此我們覺得那個更好優化呢,哪個能減少更少的IO呢,第一個query;
執行高並發的query比執行低並發的危險性要高的多,高並發的query很容易讓系統crash掉,
等我們重新啟動后系統負荷就會直線飆升接近crash,讓我們都不能查詢問題出現在哪里,
而低並發的query雖然也產生負荷至少還在可控范圍內;
join時的原則就是‘小結果集驅動大結果集的’:
A表1000數據,B表10萬條數據 SELECT A.*, B.name FROM A LEFT JOIN B ON A.id=B.a_id
//這里就是以A表作為驅動表循環連接B表信息;減少了循環次數;B表示被驅動表;
explain sql語句詳細分析:
注意key_len的值,越小越好;
//也就是說往往一個where條件可以查詢到的就不要再用第二個沒有意義的條件了哦,因為消耗內存;
mysql中索引的限制:
MyISAM存儲引擎的索引鍵值長度總和不能超過1000字節;
mysql目前不支持函數索引;
mysql查詢條件!= 、<>的時候不能使用索引;
使用like查詢 like'%abc'這樣無法使用索引;
join的原理和優化思路:
SELECT A.*
FROM USER_GROUP A LEFT JOIN GROUP_MESSAGE B ON A.group_id = B.group_id
LEFT JOIN GROUP_MESSAGE_CONTENT C ON B.id = C.message_id
WHERE A.user_id = 1;
//這里是把USER_GROUP表作為驅動表, 先A表通過索引查詢出group_id集合作為驅動表,
//對GROUP_MESSAGE表進行循環查詢出id,最后在通過索引message_id查詢出最終結果集合;
盡可能的減少join語句的循環次數;
連接的字段必須建索引;
GROUP BY/ ORDER BY盡量使用索引;
9、mysql數據庫schema(圖標)的設計和調優
高效的模型設計:
首先考慮符合第一第二第三范式;
適當沉余讓query盡量減少join;
舉例:user表,message表中可以添加個author_name字段;
大字段垂直分隔;
blog表中有個content字段text類型可以分隔成blog_detail表;
統計表准實時更新;
統計的數據不建議實時更新,這里就是商業需求影響性能,可以使用定時實時更新;
合適的數據類型:
盡量使用小的數據類型來減少磁盤的空間;
通過合適的數據類型進行數值比較;
規范的對象命名:
數據庫和表命名應盡可能的和所屬產品描述相符合;
字段名也應和該列信息描述相符合;
索引名稱盡量包含字段名稱或字段縮寫;
備注:數據庫性能的提升不是優化出來的而是設計出來的;
10、mysql性能優化
mysql安裝優化:
安裝適合的數據庫版本;
mysql日志性能優化:
錯誤日志(error log);
更新日志(update log);
二進制日志(binlog);
查詢日志(query log);
慢查詢日志(slow query sql);
mysql query cache的優化:
mysql query cache產生可以讓mysql性能產生質的飛越;
mysql server的其他優化:
網絡允許的最大連接數;max_connections處理並發能力
用戶允許的組大連接數;max_user_connextions針對於單個用戶的連接限制;
網絡包傳輸中,傳輸信息之前net_buffer的初始化大小;net_buffer_length;
網絡傳輸中一次傳輸信息的最大值;max_allowed_packet;
mysql連接等待中的最大數量;back_log;
11、常用存儲引擎優化
mysql中MyISAM存儲引擎優化;
mysql中Innodb存儲引擎優化;
12、mysql可拓展設計的基本原則
13、可拓展性設計之mysql replication(復制)
14、可拓展性設計之數據切分
何為數據切割:
按照不同的表來切分到不同的數據庫上這個是垂直(縱向)切割模式;
把同一個表按照某種邏輯關系分別拆分存放到不同的數據庫上這個是水平切割模式;
備注:垂直分隔的特點就是簡單,低耦合的表可以進行垂直分隔;
如果我們做了垂直分隔后還任然不能提高性能時我們還的進行水平分隔;
數據的垂直分隔:
數據庫中的表都是有多個功能模塊組成,每個功能模塊之前的耦合度越小越容易進行垂直分隔;
垂直分隔優點:
數據庫拆分簡單明了,拆分規則明確;
應用程序模塊清晰明確,整合容易;
數據維護方便容易定位;
垂直分隔缺點:
部分表關聯無法在數據庫中完成;
切分成一定程度之后拓展性降低;
數據水平分隔:
數據的水平分隔是高並發查詢的表通過某個字段的規則吧數據分別存放不同的表中進行查詢,
這樣每張表的數據集合就沒有之前一張表大,從而來提示查詢速度,常見的方案是通過userid
對5取模然后分別存放到5個表中,顯示查詢則通過userid對5取模,余數就知道此userid存在哪里;
備注:通過數據分隔技術將一個大的數據mysql server分隔成多個小數據的mysql server,這樣提高了
查詢和寫入性能, 最佳方案是先進行垂直分隔再進行水平分隔;
15、可拓展性設置cache和search的利用
分布式緩存cache解決方案memcached;
利用search實現高效的全文索引;
備注:數據庫只是存儲數據的工具,他的特點就是持久化,除了數據庫我們還有很多其他方式的數據存儲;
16、mysql cluster(集群)
mysql cluster是一個基於NDB cluster存儲引擎的完整的分布式數據庫系統;