http://hongge.blog.51cto.com/html
MySQL Server 系統架構mysql
在前一節中咱們學習了mysql的邏輯模塊組成,接下來咱們來學習mysql存儲引擎。sql
1、mysql存儲引擎介紹:數據庫
MySQL在5.1(不包括)以前的版本中,存儲引擎是須要在MySQL 安裝的時候就必須和MySQL 一塊兒被編譯並同時被安裝的。windows
可是從MySQL5.1 開始,MySQL AB 對其結構體系作了較大的改造,並引入了一個新的概念:插件式存儲引擎體系結構。MySQL AB 在架構改造的時候,讓存儲引擎層和sql layer各自更爲獨立,耦合更小,甚至能夠作到在線加載新的存儲引擎,也就是徹底能夠將一個新的存儲引擎加載到一個正在運行的MySQL 中,而不影響MySQL 的正常運行。插件式存儲引擎的性能優化
架構,爲存儲引擎的加載和移出更爲靈活方便,也使自行開發存儲引擎更爲方便簡單。bash
MySQL的插件式存儲引擎主要包括MyISAM,Innodb,NDB Cluster,Maria,Falcon,Memory,Archive等,其中最著名並且使用最爲普遍的MyISAM 和Innodb兩種存儲引擎。MyISAM 是MySQL 最先的ISAM 存儲引擎的升級版本,也是MySQL 默認的存儲引擎。而Innodb 實際上並非MySQ 公司的,而是第三方軟件公司Innobase(在2005 年被Oracle 公司所收購)所開發,其最大的特色是提供了事務控制等特性, 因此使用者也很是普遍。服務器
其餘的一些存儲引擎相對來講使用場景要稍微少一些,都是應用於某些特定的場景,如NDB Cluster雖然也支持事務,可是主要是用於分佈式高可用集羣環境。Maria是MySQL最新開發的對MyISAM的升級版存儲引擎,Falcon 是MySQL 公司自行研發的爲了替代當前的Innodb 存儲引擎的一款帶有事務等高級特性的數據庫存儲引擎。Memory 存儲引擎全部數據和索引均存儲於內存中,僅保存.frm文件在硬盤,因此主要是用於一些臨時表,或者對性能要求極高,可是容許在Crash 的時候丟失數據的特定場景下,會消耗內存較大。Archive 是一個數據通過高比例壓縮存放的存儲引擎,僅支持insert,select,不支持update和delete,主要用於存放過時並且不多訪問的歷史信息,不支持索引。數據結構
MyISAM 存儲引擎簡介:架構
一、mysql5.1以前默認存儲引擎。
二、MyISAM 存儲引擎的表在數據庫中,每個表都被存放爲三個以表名命名的物理文件。首先確定會有任何存儲引擎都不可缺乏的存放表結構定義信息的.frm 文件,另外還有.MYD和.MYI 文件,分別存放了表的數據(.MYD)和索引數據(.MYI)。每一個表都有且僅有這樣三個文件作爲MyISAM 存儲類型的表的存儲,也就是說無論這個表有多少個索引,都是存放在同一個.MYI 文件中。
三、MyISAM 支持如下三種類型的索引:
B-Tree 索引
B-Tree 索引,就是全部的索引節點都按照balance tree 的數據結構來存儲,全部的索引數據節點都在葉節點。
R-Tree 索引
R-Tree 索引的存儲方式和b-tree 索引有一些區別,主要設計用於爲存儲空間和多維數據的字段作索引,因此目前的MySQL 版原本說,也僅支持geometry 類型的字段做索引。
Full-text 索引
Full-text 索引就是全文索引,他的存儲結構也是b-tree。主要是爲了解決在咱們須要用like 查詢的低效問題。
MyISAM 上面三種索引類型中,最常用的就是B-Tree 索引了,偶爾會使用到Fulltext,可是R-Tree 索引通常系統中都是不多用到的。另外MyISAM 的B-Tree 索引有一個較大的限制,那就是參與一個索引的全部字段的長度之和不能超過1000 字節。
三、不支持事務
四、只有表鎖
五、以下狀況會形成表損壞:
Mysqld正在寫入該表時,被kill掉
主機宕機(Crash)
磁盤硬件故障
MyISAM存儲引擎的bug
六、雖然每個MyISAM的表都是存放在一個相同後綴名的.MYD 文件中,可是每一個文件的存放格式實際上可能並非徹底同樣的,由於MyISAM 的數據存放格式是分爲靜態(FIXED)固定長度、動態(DYNAMIC)可變長度以及壓縮(COMPRESSED)這三種格式。固然三種格式中是否壓縮是徹底能夠任由本身選擇的,能夠在建立表的時候經過ROW_FORMAT 來指定{COMPRESSED | DEFAULT},也能夠經過myisampack 工具來進行壓縮,默認是不壓縮的。而在非壓縮的狀況下,是靜態仍是動態,就和咱們表中個字段的定義相關了。只要表中有可變長度類型的字段存在,那麼該表就確定是DYNAMIC 格式的,若是沒有任何可變長度的字段,則爲FIXED 格式,固然,你也能夠經過alter table 命令,強行將一個帶有VARCHAR 類型字段的DYNAMIC 的錶轉換爲FIXED,可是所帶來的結果是原VARCHAR 字段類型會被自動轉換成CHAR 類型。相反若是將FIXED 轉換爲DYNAMIC,也會將CHAR 類型字段轉換爲VARCHAR 類型,
知識點擴展:如何根據表的記錄數量估算佔用的磁盤空間
首先先算一個表中一行有多少個字節。
而後根據數據庫中的表天天增長多少行記錄,就可以算出天天要增長多少硬盤空間,這樣就可根據數據量估算規劃多大的空間。
例如在數據庫test中建立一張tb1表
執行mysql>desc test1.tb1查看tb1的表結構
10個字節+20個字節+2個字節+20字節+8字節+8字節+100個字節=168字節
Tb1表的一個行有118個字節
若是天天增長10000條記錄,大約須要10000x168/1024/1024=1.6MB
這樣就能夠根據天天增長的記錄數,合理規劃好磁盤空間了
MyISAM 存儲引擎的某個表文件出錯以後,僅影響到該表,而不會影響到其餘表,更不會影響到其餘的數據庫。若是咱們的數據庫正在運行過程當中發現某個MyISAM 表出現問題了,則能夠在線經過check table 命令來嘗試校驗他,並能夠經過repair table 命令來嘗試修復。在數據庫關閉狀態下,咱們也能夠經過myisamchk 工具來對數據庫中某個(或某些)表進行檢測或者修復。不過強烈建議不到萬不得已不要輕易對錶進行修復操做,修復以前儘可能作好可能的備份工做,以避免帶來沒必要要的後果。
Innodb 存儲引擎簡介:
Innodb 之因此能如此受寵,主要是在於其功能方面的較多特色:
一、支持事務
Innodb 在功能方面最重要的一點就是對事務的支持,這無疑是讓Innodb 成爲MySQL最爲流行的存儲引擎之一的一個很是重要緣由。
二、鎖定機制的改進
Innodb 改變了MyISAM 的鎖機制,實現了行鎖。
三、實現外鍵
Innodb 實現了外鍵引用這一數據庫的重要特性。
四、Innodb 存儲引擎也和MyISAM 不太同樣,雖然也有.frm 文件來存放表結構定義相關的元數據,可是表數據和索引數據是存放在一塊兒的。至因而每一個表單獨存放仍是全部表存放在一塊兒,徹底由用戶來決定。
Innodb 的物理結構分爲兩大部分:
一、數據文件(表數據和索引數據)
存放數據表中的數據和全部的索引數據,包括主鍵和其餘普通索引。在Innodb 中,存在了表空間(tablespace)這樣一個概念,可是他和Oracle 的表空間又有較大的不一樣。首先,Innodb 的表空間分爲兩種形式。一種是共享表空間,也就是全部表和索引數據被存放在同一個表空間(一個或多個數據文件)中,經過innodb_data_file_path 來指定,增長數據文件須要停機重啓。另一種是獨享表空間,也就是每一個表的數據和索引被存放在一個單獨的.ibd 文件中。
雖然咱們能夠自行設定使用共享表空間仍是獨享表空間來存放咱們的表,可是共享表空間都是必須存在的,由於Innodb 的undo 信息和其餘一些元數據信息都是存放在共享表空間裏面的。共享表空間的數據文件是能夠設置爲固定大小和可自動擴展大小兩種形式的。
當咱們的文件表空間快要用完的時候,咱們必需要爲其增長數據文件,固然,只有共享表空間有此操做。共享表空間增長數據文件的操做比較簡單, 只須要在innodb_data_file_path 參數後面按照標準格式設置好文件路徑和相關屬性便可,不過這裏有一點須要注意的,就是Innodb 在建立新數據文件的時候是不會建立目錄的,若是指定目錄不存在,則會報錯並沒有法啓動。
二、日誌文件
Innodb 的日誌文件和Oracle 的redo 日誌比較相似,一樣能夠設置多個日誌組(最少2
個),一樣採用輪循策略來順序的寫入。
因爲Innodb 是事務的存儲引擎,因此係統Crash(宕機)對他來講並不能形成很是嚴重的損失,因爲有redo日誌(即事物日誌)的存在,有checkpoint 機制的保護,Innodb 徹底能夠經過redo 日誌將數據庫Crash 時刻已經完成但尚未來得及將數據寫入磁盤的事務恢復,也可以將全部部分完成並已經寫入磁盤的未完成事務回滾並將數據還原。
Innodb 不只在功能特性方面和MyISAM 存儲引擎有較大區別,在配置上面也是單獨處理的。在MySQL 啓動參數文件(/etc/my.cnf)設置中,Innodb 的全部參數基本上都帶有前綴「innodb_」,不管是innodb 數據和日誌相關,仍是其餘一些性能,事務等等相關的參數都是同樣。和全部Innodb 相關的系統變量同樣,全部的Innodb 相關的系統狀態值也一樣所有以「Innodb_」前綴。
一、 MyISAM不支持事務,而InnoDB支持。InnoDB的AUTOCOMMIT默認是打開的,即每條SQL語句會默認被封裝成一個事務,自動提交,這樣會影響速度,因此最好是把多條SQL語句顯示放在begin和commit之間,組成一個事務去提交。
mysql> use test_db;
mysql> show tables;
mysql> desc tb1;
mysql> begin;
mysql> insert into tb1 values('lisi',1);
mysql> insert into tb1 values('zhangsan',2);
mysql> commit;
二、InnoDB支持數據行鎖定,MyISAM不支持行鎖定,只支持鎖定整個表。即MyISAM同一個表上的讀鎖和寫鎖是互斥的,MyISAM併發讀寫時若是等待隊列中既有讀請求又有寫請求,默認寫請求的優先級高,即便讀請求先到,因此MyISAM不適合於有大量查詢和修改並存的狀況,那樣查詢進程會長時間阻塞。由於MyISAM是鎖表。
三、InnoDB支持外鍵,MyISAM不支持。
四、InnoDB不支持全文索引,而MyISAM支持。
2、Mysqlslap性能測試MySQL二種存儲引擎
mysqlslap是mysql自帶的基準測試工具,優勢:查詢數據,語法簡單,靈活容易使用.該工具能夠模擬多個客戶端同時併發的向服務器發出查詢更新,給出了性能測試數據並且提供了多種引擎的性能比較.msqlslap爲mysql性能優化先後提供了直觀的驗證依據,建議系統運維和DBA人員應該掌握一些常見的壓力測試工具,才能準確的掌握線上數據庫支撐的用戶流量上限及其抗壓性等問題。
如今看一下這個壓力測試工具mysqlslap,關於他的選項手冊上以及--help介紹的很詳細。
這裏解釋一下一些經常使用的選項。
--concurrency表明併發數量,多個能夠用逗號隔開。例如:concurrency=50,100,200
--engines表明要測試的引擎,能夠有多個,用分隔符隔開。
--iterations表明要運行這些測試多少次,即運行多少次後,獲得結果。
--auto-generate-sql 表明用系統本身生成的SQL腳原本測試。
--auto-generate-sql-load-type 表明要測試的是讀仍是寫仍是二者混合的(read,write,update,mixed)
--number-of-queries 表明總共要運行多少次查詢。每一個客戶運行的查詢數量能夠用查詢總數/併發數來計算。好比倒數第二個結果2=200/100。
--debug-info 表明要額外輸出CPU以及內存的相關信息(注:只有在MySQL用--with-debug編譯時可)。
--number-int-cols 表明測試表中的INTEGER類型的屬性有幾個。
--number-char-cols表明測試表的char類型字段的數量。
--create-schema 表明本身定義的模式(在MySQL中也就是庫即建立測試的數據庫)。
--query 表明本身的SQL腳本。
--only-print 若是隻想打印看看SQL語句是什麼,能夠用這個選項。
--csv=name 生產CSV格式數據文件
查看Mysql數據庫默認最大鏈接數
能夠看到mysql5.7.13默認是151,注:不一樣版本默認最大鏈接數不差異。通常生產環境是不夠的,在my.cnf [mysqld]下添加 max_connections=1024 增長到1024,重啓Mysql。
修改my.cnf文件並重起mysqld服務
查看修改後的最大鏈接數
查看Mysql默認使用存儲引擎,以下查看:
mysql> show engines;
如今咱們來看一下具體測試的例子
[root@localhost ~]# mysqlslap --defaults-file=/etc/my.cnf --concurrency=100,200 --iterations=1 --number-int-cols=20 --number-char-cols=30 --auto-generate-sql --auto-generate-sql-add-autoincrement --auto-generate-sql-load-type=mixed --engine=myisam,innodb --number-of-queries=2000 -uroot -p123456 –verbose
顯示結果:
測試說明:模擬測試兩次讀寫併發,第一次100,第二次200,自動生成SQL腳本,測試表包含20個init字段,30個char字段,每次執行2000查詢請求。測試引擎分別是myisam,innodb。
測試結果說明:
Myisam第一次100客戶端同時發起增查用0.413/s,第二次200客戶端同時發起增查用0.509/s
Innodb第一次100客戶端同時發起增查用0.692/s,第二次200客戶端同時發起增查用0.617/s
因而可知MyISAM存儲引擎處理性能是最好的,也是最經常使用的,但不支持事務。InonDB存儲引擎提供了事務型數據引擎(ACID),在事務型引擎裏使用最多的。具備事務回滾,系統修復等特色。
Mysqlslap測試工具生產CSV格式數據文件並轉換成圖表形式:
[root@localhost ~]# mysqlslap --defaults-file=/etc/my.cnf --concurrency=100,200 --iterations=1 --number-int-cols=20 --number-char-cols=30 --auto-generate-sql --auto-generate-sql-add-autoincrement --auto-generate-sql-load-type=mixed --engine=myisam,innodb --number-of-queries=2000 -uroot -p123456 --csv=/root/a.csv
執行結果:
將a.csv拷貝到windows主機上,打開並生成圖表
用咱們本身定義的SQL 腳本或語句來測試
首先準備好要測試的數據庫表,這裏咱們編寫一個生成表的腳本去完成
腳本內容以下:
[root@localhost ~]# cat /root/mysql3.sh
#!/bin/bash
HOSTNAME="localhost"
PORT="3306"
USERNAME="root"
PASSWORD="123.abc"
DBNAME="test1"
TABLENAME="tb1"
#create database
mysql -h ${HOSTNAME} -P ${PORT} -u${USERNAME} -p${PASSWORD} -e "drop database if exists ${DBNAME}"
create_db_sql="create database ifnot exists ${DBNAME}"
mysql -h ${HOSTNAME} -P ${PORT} -u${USERNAME} -p${PASSWORD} -e "${create_db_sql}"
#create table
create_table_sql="create table ifnot exists ${TABLENAME}(stuid int not null primary key,stuname varchar(20) notnull,stusex char(1) not null,cardid varchar(20) not null,birthdaydatetime,entertime datetime,address varchar(100) default null)"
mysql -h ${HOSTNAME} -P ${PORT} -u${USERNAME} -p${PASSWORD} ${DBNAME} -e "${create_table_sql}"
#insert data to table
i=1
while [ $i -le 20000 ]
do
insert_sql="insert into${TABLENAME} values($i,'zhangsan','1','1234567890123456','1999-10-10','2016-9-3','zhongguobeijingshi changpinqu')"
mysql -h ${HOSTNAME} -P ${PORT} -u${USERNAME} -p${PASSWORD} ${DBNAME} -e "${insert_sql}"
let i++
done
#select data
select_sql="select count(*) from${TABLENAME}"
mysql -h ${HOSTNAME} -P ${PORT} -u${USERNAME} -p${PASSWORD} ${DBNAME} -e "${select_sql}"
受權腳本x執行權限
[root@localhost ~]# chmod +x/root/mysql3.sh
執行腳本mysql3.sh生成mysqlslap工具須要的測試表
[root@localhost ~]# /root/mysql3.sh
執行mysqlslap工具進行測試
[root@localhost ~]# mysqlslap --defaults-file=/etc/my.cnf--concurrency=10,20 --iterations=1 --create-schema='test1' --query='select *from test1.tb1' --engine=myisam,innodb --number-of-queries=2000 -uroot -p123456–verbose
顯示結果:
mysqlslap: [Warning] Using a password onthe command line interface can be insecure.
Benchmark
Runningfor engine myisam
Averagenumber of seconds to run all queries: 14.128 seconds
Minimumnumber of seconds to run all queries: 14.128 seconds
Maximumnumber of seconds to run all queries: 14.128 seconds
Numberof clients running queries: 10
Averagenumber of queries per client: 200
Benchmark
Runningfor engine myisam
Averagenumber of seconds to run all queries: 13.646 seconds
Minimumnumber of seconds to run all queries: 13.646 seconds
Maximumnumber of seconds to run all queries: 13.646 seconds
Numberof clients running queries: 20
Averagenumber of queries per client: 100
Benchmark
Runningfor engine innodb
Averagenumber of seconds to run all queries: 13.837 seconds
Minimumnumber of seconds to run all queries: 13.837 seconds
Maximumnumber of seconds to run all queries: 13.837 seconds
Numberof clients running queries: 10
Averagenumber of queries per client: 200
Benchmark
Runningfor engine innodb
Averagenumber of seconds to run all queries: 13.768 seconds
Minimumnumber of seconds to run all queries: 13.768 seconds
Maximumnumber of seconds to run all queries: 13.768 seconds
Numberof clients running queries: 20
Averagenumber of queries per client: 100
注:經過mysqlslap工具對mysql server進行壓力測試,能夠經過--concurrency、--number-of-queries等選項的值查看每次測試的結果,經過反覆測試、優化得出mysql server的最大併發數。
若是mysqlslap工具輸出結果爲Segmentation fault (core dumped)基本表示走超出mysql server的負載。