1 MySQL總體架構(gòu)介紹
1.1 MySQL總體架構(gòu)介紹
引言
MySQL是一個(gè)關(guān)系型數(shù)據(jù)庫(kù)
應(yīng)用十分廣泛
在學(xué)習(xí)任何一門知識(shí)之前
對(duì)其架構(gòu)有一個(gè)概括性的了解是非常重要的
比如索引、sql是在哪個(gè)地方執(zhí)行的
流程是什么樣的
今天我們就先來(lái)學(xué)習(xí)一下MySQL的總體架構(gòu)
總的來(lái)說(shuō):MySQL架構(gòu)是一個(gè)客戶端-服務(wù)器系統(tǒng)。
MySQL主要包括以下幾部分:
Server 層:主要包括連接器、查詢緩存、分析器、優(yōu)化器、執(zhí)行器等,所有跨存儲(chǔ)引擎的功能都在這一層實(shí)現(xiàn),比如存儲(chǔ)過(guò)程、觸發(fā)器、視圖,函數(shù)等,還有一個(gè)通用的日志模塊 binglog 日志模塊。
存儲(chǔ)引擎: 主要負(fù)責(zé)數(shù)據(jù)的存儲(chǔ)和讀取,采用可以替換的插件式架構(gòu),支持 InnoDB、MyISAM、Memory 等多個(gè)存儲(chǔ)引擎,其中 InnoDB 引擎有自己的日志模塊 redolog 模塊。現(xiàn)在最常用的存儲(chǔ)引擎是 InnoDB,它從 MySQL 5.5.5 版本開(kāi)始就被當(dāng)做默認(rèn)存儲(chǔ)引擎了
連接器: 身份認(rèn)證和權(quán)限相關(guān)(登錄 MySQL 的時(shí)候)。
查詢緩存: 執(zhí)行查詢語(yǔ)句的時(shí)候,會(huì)先查詢緩存(MySQL 8.0 版本后移除,因?yàn)檫@個(gè)功能不太實(shí)用)mysql的server層增加一層緩存模塊,類似一個(gè)內(nèi)存的kv層,k是sql,value是結(jié)果
分析器: 沒(méi)有命中緩存的話,SQL 語(yǔ)句就會(huì)經(jīng)過(guò)分析器,分析器說(shuō)白了就是要先看你的 SQL 語(yǔ)句要干嘛,再檢查你的 SQL 語(yǔ)句語(yǔ)法是否正確。
優(yōu)化器: 按照 MySQL 認(rèn)為最優(yōu)的方案去執(zhí)行。
執(zhí)行器: 執(zhí)行語(yǔ)句,然后從存儲(chǔ)引擎返回?cái)?shù)據(jù)。
1.2 MySQL存儲(chǔ)引擎介紹
引言
和大多數(shù)的數(shù)據(jù)庫(kù)不同, MySQL中有一個(gè)存儲(chǔ)引擎的概念
針對(duì)不同的存儲(chǔ)需求可以選擇最優(yōu)的存儲(chǔ)引擎。
存儲(chǔ)引擎就是存儲(chǔ)數(shù)據(jù),建立索引,更新查詢數(shù)據(jù)等等技術(shù)的實(shí)現(xiàn)方式 。
存儲(chǔ)引擎是基于表的,而不是基于庫(kù)的
所以存儲(chǔ)引擎也可被稱為表類型。
MySQL提供了插件式的存儲(chǔ)引擎架構(gòu)。所以MySQL存在多種存儲(chǔ)引擎,可以根據(jù)需要使用相應(yīng)引擎,或者編寫存儲(chǔ)引擎。
MySQL5.0支持的存儲(chǔ)引擎包含 : InnoDB 、MyISAM 、BDB、MEMORY、MERGE、EXAMPLE、NDB Cluster、ARCHIVE、CSV、BLACKHOLE、FEDERATED等
可以通過(guò)指定 show engines , 來(lái)查詢當(dāng)前數(shù)據(jù)庫(kù)支持的存儲(chǔ)引擎 :
SHOW ENGINES;
表含義:
- support : 指服務(wù)器是否支持該存儲(chǔ)引擎
- transactions : 指存儲(chǔ)引擎是否支持事務(wù)
- XA : 指存儲(chǔ)引擎是否支持分布式事務(wù)處理
- Savepoints : 指存儲(chǔ)引擎是否支持保存點(diǎn)(實(shí)現(xiàn)回滾到指定保存點(diǎn))
-
查看MySQL數(shù)據(jù)庫(kù)存儲(chǔ)引擎配置
SHOW VARIABLES LIKE '%storage_engine%';
1.2.1 如何更改數(shù)據(jù)庫(kù)表引擎
- 建表語(yǔ)句后面加入引擎賦值即可 ,命令舉例如下 ,
CREATE TABLE t1(
id INT ,
name VARCHAR(20)
) ENGINE = MyISAM;
- 修改已有的表引擎 , 命令舉例如下 ,
ALTER TABLE t1 ENGINE = InnoDB;
1.2.2 常用引擎及其特性對(duì)比
-
常見(jiàn)的存儲(chǔ)引擎 :
MyISAM存儲(chǔ)引擎 : 訪問(wèn)快,不支持事務(wù)和外鍵。表結(jié)構(gòu)保存在.frm文件中,表數(shù)據(jù)保存在.MYD文件中,索引保存在.MYI文件中。
[root@linux-141 itcast]# ll -rw-r-----. 1 mysql mysql 8630 9月 10 16:01 t_account_myisam.frm -rw-r-----. 1 mysql mysql 52 9月 10 16:06 t_account_myisam.MYD -rw-r-----. 1 mysql mysql 2048 9月 10 17:56 t_account_myisam.MYI [root@linux-141 itcast]#
innoDB存儲(chǔ)引擎(5.5版本開(kāi)始默認(rèn)) : 支持事務(wù) ,占用磁盤空間大 ,支持并發(fā)控制。表結(jié)構(gòu)保存在.frm文件中,如果是共享表空間,數(shù)據(jù)和索引保存在 innodb_data_home_dir 和 innodb_data_file_path定義的表空間中,可以是多個(gè)文件。如果是多表空間存儲(chǔ),每個(gè)表的數(shù)據(jù)和索引單獨(dú)保存在 .ibd 中。
[root@linux-141 itcast]# ll
-rw-r-----. 1 mysql mysql 8630 9月 10 16:02 t_account_innodb.frm
-rw-r-----. 1 mysql mysql 98304 9月 14 15:50 t_account_innodb.ibd
[root@linux-141 itcast]#
MEMORY存儲(chǔ)引擎 : 內(nèi)存存儲(chǔ) , 速度快 ,不安全 ,適合小量快速訪問(wèn)的數(shù)據(jù)。表結(jié)構(gòu)保存在.frm中。
!特性對(duì)比 :
特點(diǎn) | InnoDB | MyISAM | MEMORY | MERGE | NDB |
---|---|---|---|---|---|
存儲(chǔ)限制 | 64TB | 有 | 有 | 沒(méi)有 | 有 |
事務(wù)安全 | ==支持== | ||||
鎖機(jī)制 | ==行鎖(適合高并發(fā))== | ==表鎖== | 表鎖 | 表鎖 | 行鎖 |
B樹(shù)索引 | 支持 | 支持 | 支持 | 支持 | 支持 |
哈希索引 | 支持 | ||||
全文索引 | 支持(5.6版本之后) | 支持 | |||
集群索引 | 支持 | ||||
數(shù)據(jù)索引 | 支持 | 支持 | 支持 | ||
索引緩存 | 支持 | 支持 | 支持 | 支持 | 支持 |
數(shù)據(jù)可壓縮 | 支持 | ||||
空間使用 | 高 | 低 | N/A | 低 | 低 |
內(nèi)存使用 | 高 | 低 | 中等 | 低 | 高 |
批量插入速度 | 低 | 高 | 高 | 高 | 高 |
支持外鍵 | ==支持== |
1.2.3 如何選擇不同類型的引擎
在選擇存儲(chǔ)引擎時(shí),應(yīng)該根據(jù)應(yīng)用系統(tǒng)的特點(diǎn)選擇合適的存儲(chǔ)引擎。對(duì)于復(fù)雜的應(yīng)用系統(tǒng),還可以根據(jù)實(shí)際情況選擇多種存儲(chǔ)引擎進(jìn)行組合。
以下是幾種常用的存儲(chǔ)引擎的使用環(huán)境。
- InnoDB : 是Mysql的默認(rèn)存儲(chǔ)引擎,用于事務(wù)處理應(yīng)用程序,支持外鍵。如果應(yīng)用對(duì)事務(wù)的完整性有比較高的要求,在并發(fā)條件下要求數(shù)據(jù)的一致性,數(shù)據(jù)操作除了插入和查詢以外,還包含更新、刪除操作,那么InnoDB存儲(chǔ)引擎是比較合適的選擇。InnoDB存儲(chǔ)引擎除了有效的降低由于刪除和更新導(dǎo)致的鎖定, 還可以確保事務(wù)的完整提交和回滾,對(duì)于類似于計(jì)費(fèi)系統(tǒng)或者財(cái)務(wù)系統(tǒng)等對(duì)數(shù)據(jù)準(zhǔn)確性要求比較高的系統(tǒng),InnoDB是最合適的選擇。
- MyISAM : 如果應(yīng)用是以讀操作和插入操作為主,只有很少的更新和刪除操作,并且對(duì)事務(wù)的完整性、并發(fā)性要求不是很高,那么選擇這個(gè)存儲(chǔ)引擎是非常合適的。
- MEMORY:將所有數(shù)據(jù)保存在RAM中,在需要快速定位記錄和其他類似數(shù)據(jù)環(huán)境下,可以提供極快的訪問(wèn)。MEMORY的缺陷就是對(duì)表的大小有限制,太大的表無(wú)法緩存在內(nèi)存中,其次是要確保表的數(shù)據(jù)可以恢復(fù),數(shù)據(jù)庫(kù)異常終止后表中的數(shù)據(jù)是可以恢復(fù)的。MEMORY表通常用于更新不太頻繁的小表,用以快速得到訪問(wèn)結(jié)果。
1.3 SQL的執(zhí)行流程是什么樣的
- 客戶端發(fā)送一條查詢給服務(wù)器。
- 服務(wù)器先檢查查詢緩存,如果命中了緩存,則立刻返回存儲(chǔ)在緩存中的結(jié)果。否則進(jìn)入下一階段。
- 服務(wù)器端進(jìn)行SQL解析、預(yù)處理,再由優(yōu)化器生成對(duì)應(yīng)的執(zhí)行計(jì)劃。
- MySQL根據(jù)優(yōu)化器生成的執(zhí)行計(jì)劃,再調(diào)用存儲(chǔ)引擎的API來(lái)執(zhí)行查詢。
- 將結(jié)果返回給客戶端。
2 MySQL存儲(chǔ)引擎調(diào)優(yōu)
2.1 MySQL服務(wù)器硬件優(yōu)化
tips
硬件(cpu、內(nèi)存等)相關(guān)
了解即可
關(guān)于提升硬件設(shè)備性能:
例如選擇盡量高頻率的內(nèi)存(頻率不能高于主板的支持)、提升網(wǎng)絡(luò)帶寬、使用SSD高速磁盤、提升CPU性能等。
CPU的選擇:
- 對(duì)于數(shù)據(jù)庫(kù)并發(fā)比較高的場(chǎng)景,CPU的數(shù)量比頻率重要。
- 對(duì)于CPU密集型場(chǎng)景和頻繁執(zhí)行復(fù)雜SQL的場(chǎng)景,CPU的頻率越高越好
磁盤的選擇
影響數(shù)據(jù)庫(kù)最大的性能問(wèn)題就是磁盤I/O
為提高數(shù)據(jù)庫(kù)的IOPS性能,可使用SSD或PCIE-SSD高速磁盤設(shè)備
磁盤IO的優(yōu)化
可以用RAID來(lái)進(jìn)行優(yōu)化
常用RAID(磁盤陣列)級(jí)別:
RAID0:也稱為條帶,就是把多個(gè)磁盤鏈接成一個(gè)硬盤使用,這個(gè)級(jí)別IO最好
RAID1:也稱為鏡像,要求至少有兩個(gè)磁盤,每組磁盤存儲(chǔ)的數(shù)據(jù)相同
RAID5:也是把多個(gè)(最少3個(gè))硬盤合并成一個(gè)邏輯盤使用,數(shù)據(jù)讀寫時(shí)會(huì)建立奇偶校驗(yàn)信息,并且奇偶校驗(yàn)信息和相對(duì)應(yīng)的數(shù)據(jù)分別存儲(chǔ)在不同的磁盤上。當(dāng)RAID5的一個(gè)磁盤數(shù)據(jù)發(fā)生損壞后,利用剩下的數(shù)據(jù)和響應(yīng)的奇偶校驗(yàn)信息去恢復(fù)被損壞的數(shù)據(jù)
RAID1+0(建議使用):就是RAID0和RAID1的組合。同時(shí)具備兩個(gè)級(jí)別的優(yōu)缺點(diǎn),一般建議數(shù)據(jù)庫(kù)使用這個(gè)級(jí)別。
2.2 MySQL數(shù)據(jù)庫(kù)配置優(yōu)化
tips:
以下為生產(chǎn)環(huán)境中最常用的DB參數(shù)配置
- 表示緩沖池字節(jié)大小,大的緩沖池可以減少磁盤IO次數(shù)。
innodb_buffer_pool_size = 推薦值為物理內(nèi)存的50%~80%。
-
用來(lái)控制redo log buffer刷新到磁盤的策略。
innodb_flush_log_at_trx_commit=1select @@innodb_flush_log_at_trx_commit;
0 : 提交事務(wù)的時(shí)候,不立即把 redo log buffer 里的數(shù)據(jù)刷入磁盤文件中,而是依靠 InnoDB 的主線程每秒執(zhí)行一次刷新到磁盤。此時(shí)可能你提交事務(wù)了,結(jié)果 mysql 宕機(jī)了,然后此時(shí)內(nèi)存里的數(shù)據(jù)全部丟失。 1 : 提交事務(wù)的時(shí)候,立即把 redo log buffer 里的數(shù)據(jù)刷入磁盤文件中,只要事務(wù)提交成功,那么數(shù)據(jù)就必然在磁盤里了。 2 : 提交事務(wù)的時(shí)候,把 redo log buffer日志寫入磁盤文件對(duì)應(yīng)的系統(tǒng)緩存,而不是直接進(jìn)入磁盤文件,這時(shí)可能1秒后才會(huì)把系統(tǒng)緩存里的數(shù)據(jù)寫入到磁盤文件。
-
每提交1次事務(wù)就同步寫到磁盤中,可以設(shè)置為1。
sync_binlog=10:默認(rèn)值。事務(wù)提交后,將二進(jìn)制日志從緩沖寫入操作系統(tǒng)緩沖,但是不進(jìn)行刷新操作(fsync()),此時(shí)只是寫入了操作系統(tǒng)緩沖而沒(méi)有刷新到磁盤,若操作系統(tǒng)宕機(jī)則會(huì)丟失部分二進(jìn)制日志。 1:事務(wù)提交后,將二進(jìn)制文件寫入磁盤并立即執(zhí)行刷新操作,相當(dāng)于是同步寫入磁盤,不經(jīng)過(guò)操作系統(tǒng)的緩存。 N:每寫N次操作系統(tǒng)緩沖就執(zhí)行一次刷新操作。
-
臟頁(yè)占innodb_buffer_pool_size的比例,觸發(fā)刷臟頁(yè)到磁盤。 推薦值為25%~50%。
innodb_max_dirty_pages_pct=30臟頁(yè):內(nèi)存數(shù)據(jù)頁(yè)和磁盤數(shù)據(jù)頁(yè)上的內(nèi)容不一致
-
后臺(tái)進(jìn)程最大IO性能指標(biāo)。
默認(rèn)200,如果SSD,調(diào)整為5000~20000PCIE-SSD可調(diào)整為5w左右
默認(rèn):innodb_io_capacity=200
-
指定innodb共享表空間文件的大小。
innodb_data_file_path = ibdata:1G:autoextend:默認(rèn)10M,一般設(shè)置為1GB
-
慢查詢?nèi)罩镜拈撝翟O(shè)置,單位秒。
long_query_time=0.3合理設(shè)置區(qū)間0.1s~0.5s,
-
mysql復(fù)制的形式,row為MySQL8.0的默認(rèn)形式。
binlog_format=row建議binlog的記錄格式為row模式
STATEMENT模式:每一條會(huì)修改數(shù)據(jù)的sql語(yǔ)句都會(huì)記錄到binlog中。 ROW模式:不記錄每條sql語(yǔ)句的上下文信息,僅需記錄哪條數(shù)據(jù)被修改了,修改成什么樣了。 MIXED模式:以上兩種模式的混合使用。
-
降低interactive_timeout、wait_timeout的值。
交互等待時(shí)間和非交互等待時(shí)間,值一致,建議300~500s,默認(rèn)8小時(shí)
在用mysql客戶端對(duì)數(shù)據(jù)庫(kù)進(jìn)行操作時(shí),打開(kāi)終端窗口,如果一段時(shí)間(8小時(shí))沒(méi)有操作,再次操作時(shí),會(huì)報(bào)錯(cuò):當(dāng)前的連接已經(jīng)斷開(kāi),需要重新建立連接
- 數(shù)據(jù)庫(kù)最大連接數(shù)max_connections=200
-
過(guò)大,實(shí)例恢復(fù)時(shí)間長(zhǎng);過(guò)小,造成日志切換頻繁。
innodb_log_file_size=默認(rèn)redo log空間大小
-
全量日志建議關(guān)閉。
默認(rèn)關(guān)閉general_log=0開(kāi)啟 general log 將所有到達(dá)MySQL Server的SQL語(yǔ)句記錄下來(lái),general_Log文件就會(huì)產(chǎn)生很大的文件,建議關(guān)閉
2.3 Mysql中查詢緩存優(yōu)化
tips:
在MySQL 8.0之后廢棄這個(gè)功能
原理:復(fù)雜、實(shí)用性不高
作為了解即可
1) 查詢緩存概述
開(kāi)啟Mysql的查詢緩存,當(dāng)執(zhí)行完全相同的SQL語(yǔ)句的時(shí)候,服務(wù)器就會(huì)直接從緩存中讀取結(jié)果,當(dāng)數(shù)據(jù)被修改,之前的緩存會(huì)失效,修改比較頻繁的表不適合做查詢緩存。
2) 操作流程
回顧
- 客戶端發(fā)送一條查詢給服務(wù)器;
- 服務(wù)器先會(huì)檢查查詢緩存,如果命中了緩存,則立即返回存儲(chǔ)在緩存中的結(jié)果。否則進(jìn)入下一階段;
- 服務(wù)器端進(jìn)行SQL解析、預(yù)處理,再由優(yōu)化器生成對(duì)應(yīng)的執(zhí)行計(jì)劃;
- MySQL根據(jù)優(yōu)化器生成的執(zhí)行計(jì)劃,調(diào)用存儲(chǔ)引擎的API來(lái)執(zhí)行查詢;
- 將結(jié)果返回給客戶端。
3) 查詢緩存配置
-
查看當(dāng)前的MySQL數(shù)據(jù)庫(kù)是否支持查詢緩存:
SHOW VARIABLES LIKE 'have_query_cache';
-
查看當(dāng)前MySQL是否開(kāi)啟了查詢緩存 :
SHOW VARIABLES LIKE 'query_cache_type';
-
查看查詢緩存的占用大小 :
SHOW VARIABLES LIKE 'query_cache_size';
-
查看查詢緩存的狀態(tài)變量:
SHOW STATUS LIKE 'Qcache%';
各個(gè)變量的含義如下:
參數(shù) | 含義 |
---|---|
Qcache_free_blocks | 查詢緩存中的可用內(nèi)存塊數(shù) |
Qcache_free_memory | 查詢緩存的可用內(nèi)存量 |
Qcache_hits | 查詢緩存命中數(shù) |
Qcache_inserts | 添加到查詢緩存的查詢數(shù) |
Qcache_lowmen_prunes | 由于內(nèi)存不足而從查詢緩存中刪除的查詢數(shù) |
Qcache_not_cached | 非緩存查詢的數(shù)量(由于 query_cache_type 設(shè)置而無(wú)法緩存或未緩存) |
Qcache_queries_in_cache | 查詢緩存中注冊(cè)的查詢數(shù) |
Qcache_total_blocks | 查詢緩存中的塊總數(shù) |
4) 開(kāi)啟查詢緩存
MySQL的查詢緩存默認(rèn)是關(guān)閉的,需要手動(dòng)配置參數(shù) query_cache_type , 來(lái)開(kāi)啟查詢緩存。query_cache_type 該參數(shù)的可取值有三個(gè) :
值 | 含義 |
---|---|
OFF 或 0 | 查詢緩存功能關(guān)閉 |
ON 或 1 | 查詢緩存功能打開(kāi),SELECT的結(jié)果符合緩存條件即會(huì)緩存,否則,不予緩存,顯式指定 SQL_NO_CACHE,不予緩存 |
DEMAND 或 2 | 查詢緩存功能按需進(jìn)行,顯式指定 SQL_CACHE 的SELECT語(yǔ)句才會(huì)緩存;其它均不予緩存 |
在 my.cnf 配置中,增加以下配置 :
#開(kāi)啟查詢緩存
query_cache_type=1
配置完畢之后,重啟服務(wù)既可生效 ;
然后就可以在命令行執(zhí)行SQL語(yǔ)句進(jìn)行驗(yàn)證 ,執(zhí)行一條比較耗時(shí)的SQL語(yǔ)句,然后再多執(zhí)行幾次,查看后面幾次的執(zhí)行時(shí)間;獲取通過(guò)查看查詢緩存的緩存命中數(shù),來(lái)判定是否走查詢緩存。
-- 執(zhí)行SQL語(yǔ)句進(jìn)行驗(yàn)證 查詢緩存
SELECT * FROM product_list WHERE store_name = '聯(lián)想北達(dá)興科專賣店';
-- 將SELECT修改為小寫,發(fā)現(xiàn)緩存失效
SELECT * FROM product_list WHERE store_name = '聯(lián)想北達(dá)興科專賣店';
5) 查詢緩存SELECT選項(xiàng)
可以在SELECT語(yǔ)句中指定兩個(gè)與查詢緩存相關(guān)的選項(xiàng) :
SQL_CACHE : 如果查詢結(jié)果是可緩存的,并且 query_cache_type 系統(tǒng)變量的值為ON或 DEMAND ,則緩存查詢結(jié)果 。
SQL_NO_CACHE : 服務(wù)器不使用查詢緩存。它既不檢查查詢緩存,也不檢查結(jié)果是否已緩存,也不緩存查詢結(jié)果。
例子:
SELECT SQL_CACHE id, name FROM xxx;
SELECT SQL_NO_CACHE id, name FROM xxx;
6) 查詢緩存失效的情況
tips
需要注意的問(wèn)題
1) SQL 語(yǔ)句不一致的情況, 要想命中查詢緩存,查詢的SQL語(yǔ)句必須一致。
SQL1 : select count(*) from xxx;
SQL2 : Select count(*) from xxx;
2) 當(dāng)查詢語(yǔ)句中有一些不確定的值,則不會(huì)緩存。如 : now() , current_date() , curdate() , curtime() , rand() , uuid() , user() , database() 。
SQL1 : select * from xxx where updatetime < now() limit 1;
SQL2 : select user();
SQL3 : select database();
3) 不使用任何表查詢語(yǔ)句。
select 'A';
4) 查詢 mysql, information_schema或 performance_schema 數(shù)據(jù)庫(kù)中的表時(shí),不會(huì)走查詢緩存。
select * from information_schema.engines;
5) 在存儲(chǔ)的函數(shù),觸發(fā)器或事件的主體內(nèi)執(zhí)行的查詢。
6) 如果表更改,則使用該表的所有高速緩存查詢都將變?yōu)闊o(wú)效并從高速緩存中刪除。這包括使用MERGE
映射到已更改表的表的查詢。一個(gè)表可以被許多類型的語(yǔ)句,如被改變 INSERT, UPDATE, DELETE, TRUNCATE TABLE, ALTER TABLE, DROP TABLE,或 DROP DATABASE 。
將查詢緩存關(guān)閉,因?yàn)楹竺孢€需要進(jìn)行索引的驗(yàn)證,所以不希望走查詢緩存
[root@linux-141 itcast]# vi /etc/my.cnf
[root@linux-141 itcast]# service mysql restart
Shutting down MySQL.... SUCCESS!
Starting MySQL. SUCCESS!
2.4. Mysql內(nèi)存管理及優(yōu)化
1)內(nèi)存優(yōu)化原則
1) 將盡量多的內(nèi)存分配給MySQL做緩存,但要給操作系統(tǒng)和其他程序預(yù)留足夠內(nèi)存。
2) MyISAM 存儲(chǔ)引擎的數(shù)據(jù)文件讀取依賴于操作系統(tǒng)自身的IO緩存,因此,如果有MyISAM表,就要預(yù)留更多的內(nèi)存給操作系統(tǒng)做IO緩存。
3) 排序區(qū)、連接區(qū)等緩存是分配給每個(gè)數(shù)據(jù)庫(kù)會(huì)話(session)專用的,其默認(rèn)值的設(shè)置要根據(jù)最大連接數(shù)合理分配,如果設(shè)置太大,不但浪費(fèi)資源,而且在并發(fā)連接較高時(shí)會(huì)導(dǎo)致物理內(nèi)存耗盡。
2) MyISAM 內(nèi)存優(yōu)化
MyISAM 存儲(chǔ)引擎使用 key_buffer 緩存索引塊,加速myisam索引的讀寫速度。對(duì)于myisam表的數(shù)據(jù)塊,mysql沒(méi)有特別的緩存機(jī)制,完全依賴于操作系統(tǒng)的IO緩存。
key_buffer_size
key_buffer_size決定MyISAM索引塊緩存區(qū)的大小,直接影響到MyISAM表的存取效率。可以在MySQL參數(shù)文件中設(shè)置key_buffer_size的值,對(duì)于一般MyISAM數(shù)據(jù)庫(kù),建議至少將1/4可用內(nèi)存分配給key_buffer_size。
在my.cnf 中做如下配置:
key_buffer_size=512M
read_buffer_size
如果需要經(jīng)常順序掃描MyISAM 表,可以通過(guò)增大read_buffer_size的值來(lái)改善性能。但需要注意的是read_buffer_size是每個(gè)session獨(dú)占的,如果默認(rèn)值設(shè)置太大,就會(huì)造成內(nèi)存浪費(fèi)。
read_rnd_buffer_size
對(duì)于需要做排序的MyISAM 表的查詢,如帶有order by子句的sql,適當(dāng)增加 read_rnd_buffer_size 的值,可以改善此類的sql性能。
但需要注意的是 read_rnd_buffer_size 是每個(gè)session獨(dú)占的,如果默認(rèn)值設(shè)置太大,就會(huì)造成內(nèi)存浪費(fèi)。
3) InnoDB 內(nèi)存優(yōu)化
innodb用一塊內(nèi)存區(qū)做IO緩存池,該緩存池不僅用來(lái)緩存innodb的索引塊,而且也用來(lái)緩存innodb的數(shù)據(jù)塊。
innodb_buffer_pool_size
該變量決定了 innodb 存儲(chǔ)引擎表數(shù)據(jù)和索引數(shù)據(jù)的最大緩存區(qū)大小。在保證操作系統(tǒng)及其他程序有足夠內(nèi)存可用的情況下,innodb_buffer_pool_size 的值越大,緩存命中率越高,訪問(wèn)InnoDB表需要的磁盤I/O 就越少,性能也就越高。
innodb_buffer_pool_size=512M
innodb_log_buffer_size
決定了innodb重做日志緩存的大小,對(duì)于可能產(chǎn)生大量更新記錄的大事務(wù),增加innodb_log_buffer_size的大小,可以避免innodb在事務(wù)提交前就執(zhí)行不必要的日志寫入磁盤操作。
innodb_log_buffer_size=10M
2.5. Mysql并發(fā)參數(shù)調(diào)整
從實(shí)現(xiàn)上來(lái)說(shuō),MySQL Server 是多線程結(jié)構(gòu),包括后臺(tái)線程和客戶服務(wù)線程。多線程可以有效利用服務(wù)器資源,提高數(shù)據(jù)庫(kù)的并發(fā)性能。在Mysql中,控制并發(fā)連接和線程的主要參數(shù)包括 max_connections、back_log、thread_cache_size、table_open_cahce。
1) max_connections
最大可支持的連接數(shù)
采用max_connections 控制允許連接到MySQL數(shù)據(jù)庫(kù)的最大數(shù)量,默認(rèn)值是 151。如果狀態(tài)變量 connection_errors_max_connections 不為零,并且一直增長(zhǎng),則說(shuō)明不斷有連接請(qǐng)求因數(shù)據(jù)庫(kù)連接數(shù)已達(dá)到允許最大值而失敗,這時(shí)可以考慮增大max_connections 的值。
Mysql 最大可支持的連接數(shù),取決于很多因素,包括給定操作系統(tǒng)平臺(tái)的線程庫(kù)的質(zhì)量、內(nèi)存大小、每個(gè)連接的負(fù)荷、CPU的處理速度,期望的響應(yīng)時(shí)間等。在Linux 平臺(tái)下,性能好的服務(wù)器,支持 500-1000 個(gè)連接不是難事,需要根據(jù)服務(wù)器性能進(jìn)行評(píng)估設(shè)定。
2) back_log
積壓請(qǐng)求棧大小
back_log 參數(shù)控制MySQL監(jiān)聽(tīng)TCP端口時(shí)設(shè)置的積壓請(qǐng)求棧大小。如果MySql的連接數(shù)達(dá)到max_connections時(shí),新來(lái)的請(qǐng)求將會(huì)被存在堆棧中,以等待某一連接釋放資源,該堆棧的數(shù)量即back_log,如果等待連接的數(shù)量超過(guò)back_log,將不被授予連接資源,將會(huì)報(bào)錯(cuò)。5.6.6 版本之前默認(rèn)值為 50 , 之后的版本默認(rèn)為 50 + (max_connections / 5), 但最大不超過(guò)900。
如果需要數(shù)據(jù)庫(kù)在較短的時(shí)間內(nèi)處理大量連接請(qǐng)求, 可以考慮適當(dāng)增大back_log 的值。
3) table_open_cache
執(zhí)行線程可打開(kāi)表緩存?zhèn)€數(shù)
該參數(shù)用來(lái)控制所有SQL語(yǔ)句執(zhí)行線程可打開(kāi)表緩存的數(shù)量, 而在執(zhí)行SQL語(yǔ)句時(shí),每一個(gè)SQL執(zhí)行線程至少要打開(kāi) 1 個(gè)表緩存。該參數(shù)的值應(yīng)該根據(jù)設(shè)置的最大連接數(shù) max_connections 以及每個(gè)連接執(zhí)行關(guān)聯(lián)查詢中涉及的表的最大數(shù)量來(lái)設(shè)定 :
max_connections x N ;
4) thread_cache_size
緩存客戶服務(wù)線程的數(shù)量
為了加快連接數(shù)據(jù)庫(kù)的速度,MySQL 會(huì)緩存一定數(shù)量的客戶服務(wù)線程以備重用,通過(guò)參數(shù) thread_cache_size 可控制 MySQL 緩存客戶服務(wù)線程的數(shù)量。
5)lock_wait_timeout
innodb_lock_wait_timeout
事務(wù)等待行鎖的時(shí)間
該參數(shù)是用來(lái)設(shè)置InnoDB 事務(wù)等待行鎖的時(shí)間,默認(rèn)值是50ms , 可以根據(jù)需要進(jìn)行動(dòng)態(tài)設(shè)置。對(duì)于需要快速反饋的業(yè)務(wù)系統(tǒng)來(lái)說(shuō),可以將行鎖的等待時(shí)間調(diào)小,以避免事務(wù)長(zhǎng)時(shí)間掛起; 對(duì)于后臺(tái)運(yùn)行的批量處理程序來(lái)說(shuō), 可以將行鎖的等待時(shí)間調(diào)大, 以避免發(fā)生大的回滾操作。
本文由育博學(xué)谷狂野架構(gòu)師發(fā)布
如果本文對(duì)您有幫助,歡迎關(guān)注和點(diǎn)贊;如果您有任何建議也可留言評(píng)論或私信,您的支持是我堅(jiān)持創(chuàng)作的動(dòng)力
轉(zhuǎn)載請(qǐng)注明出處!