MySQL配置優化(超詳細看了就是賺到)

Mysql 參數優化對於不同的網站,及其在線量,訪問量,帖子數量,網絡情況,以及機器硬件配置都有
關係,優化不可能一次性完成,需要不斷的觀察以及調試,纔有可能得到最佳效果。
下面列出了對性能優化影響較大的主要變量,主要分爲連接請求的變量和緩衝區變量。
連接請求的變量
1、max_connections
MySQL 的最大連接數,如果服務器的併發連接請求量比較大,建議調高此值,以增加並行連接數量,
當然這建立在機器能支撐的情況下,因爲如果連接數越多, MySQL會爲每個連接提供連接緩衝區,就
會開銷越多的內存,所以要適當調整該值,不能盲目提高設值。數值過小會經常出現 ERROR 1040: Too
many connections 錯誤,可以過mysql> show status like
‘connections’;查看當前狀態的連接數量(試圖連接到MySQL(不管是否連接成功)的連接數),以定奪該值
的大小。
如果 max_used_connections跟max_connections相同那麼就是max_connections 設置過低或者超過
服務器負載上限了,低於10%則設置過大。
如何設置 max_connections?
2、back_log
MySQL 能暫存的連接數量。當主要MySQL線程在一個很短時間內得到非常多的連接請求,它就會起作
用。如果MySQL的連接數據達到max_connections 時,新來的請求將會被存在堆棧中,以等待某一連
接釋放資源,該堆棧的數量即 back_log,如果等待連接的數量超過back_log,將不被授予連接資源。

#最大連接數
mysql> show variables like ‘%max_connections%’;
±-----------------------±------+
| Variable_name | Value |
±-----------------------±------+
| max_connections | 1024 |
| mysqlx_max_connections | 100 |
±-----------------------±------+
2 rows in set (0.00 sec)
#響應的連接數
mysql> show status like ‘%max_used_connections%’;
±--------------------------±--------------------+
| Variable_name | Value |
±--------------------------±--------------------+
| Max_used_connections | 1 |
| Max_used_connections_time | 2019-10-06 16:14:21 |
±--------------------------±--------------------+
2 rows in set (0.00 sec)

如果 max_used_connections跟max_connections相同那麼就是max_connections 設置過低或者超過
服務器負載上限了,低於10%則設置過大。
如何設置 max_connections?
[root@www ~]# vim /etc/my.cnf
[mysqld]
max_connections = 1024

2、back_log
MySQL 能暫存的連接數量。當主要MySQL線程在一個很短時間內得到非常多的連接請求,它就會起作
用。如果MySQL的連接數據達到max_connections 時,新來的請求將會被存在堆棧中,以等待某一連
接釋放資源,該堆棧的數量即 back_log,如果等待連接的數量超過back_log,將不被授予連接資源。
back_log 值指出在MySQL暫時停止回答新請求之前的短時間內有多少個請求可以被存在堆棧中。只有
如果期望在一個短時間內有很多連接,你需要增加它。
當觀察你主機進程列表(mysql> show full processlist),發現大量
xxxxx | unauthenticated user | xxx.xxx.xxx.xxx | NULL | Connect | NULL | login | NULL 的待連接
進程時,就要加大back_log的值了或加大 max_connections 的值。
mysql> show variables like ‘%back_log%’;
±--------------±------+
| Variable_name | Value |
±--------------±------+
| back_log | 1024 |
±--------------±------+
1 row in set (0.00 sec)
設置方法:
[root@www ~]# vim /etc/my.cnf
[mysqld]
back_log = 1024

3、wait_timeout和interactive_timeout
wait_timeout – 指的是MySQL在關閉一個非交互的連接之前所要等待的秒數
interactive_time --指的是mysql在關閉一個交互的連接之前所要等待的秒數,比如我們在終端上進入
mysql管理,使用的即使交互的連接,這時候,如果沒有操作的時間超過了interactive_time設置的時間
就會自動斷開。默認數值是 28800,可調優爲 7200。
對性能的影響
wait_timeout
如果設置大小,那麼連接關閉的很快,從而使一些持久的連接不起作用
如果設置太大,容易造成連接打開時間過長,在 show processlist 時,能看到太多的 sleep
狀態的連接,從而造成 too many connections 錯誤
一般希望 wait_timeout 儘可能地低
interactive_timeout 的設置將要對你的 web application 沒有多大的影響
mysql> show variables like ‘%wait_timeout%’;
±-------------------------±---------+
| Variable_name | Value |
±-------------------------±---------+
| innodb_lock_wait_timeout | 50 |
| lock_wait_timeout | 31536000 |
| mysqlx_wait_timeout | 28800 |
| wait_timeout | 28800 |
±-------------------------±---------+
4 rows in set (0.00 sec)
mysql> show variables like ‘%interactive_timeout%’;
±---------------------------±------+
| Variable_name | Value |
±---------------------------±------+
| interactive_timeout | 28800 |
| mysqlx_interactive_timeout | 28800 |
±---------------------------±------+
2 rows in set (0.00 sec)
如何設置
[root@www ~]# vim /etc/my.cnf
[mysqld]
wait_timeout = 7200
interactive_timeout = 7200

緩衝區變量
4、key_buffer_size
key_buffer_size指定索引緩衝區的大小,它決定索引處理的速度,尤其是索引讀的速度。通過檢查狀態
值 Key_read_requests 和 Key_reads,可以知道 key_buffer_size 設置是否合理。比例 key_reads /
key_read_requests應該儘可能的低,至少是1:100,1:1000 更好(上述狀態值可以使用 SHOW
STATUS LIKE ‘key_read%’獲得)。
mysql> show variables like ‘%key_buffer_size%’;
±----------------±--------+
| Variable_name | Value |
±----------------±--------+
| key_buffer_size | 8388608 |
±----------------±--------+
1 row in set (0.02 sec)
mysql> show status like ‘%key_read%’;
±------------------±------+
| Variable_name | Value |
±------------------±------+
| Key_read_requests | 0 |
| Key_reads | 0 |
±------------------±------+
2 rows in set (0.00 sec)

key_buffer_size 只對 MyISAM 表起作用。即使你不使用 MyISAM 表,但是內部的臨時磁盤表是
MyISAM表,也要使用該值。可以使用檢查狀態值 created_tmp_disk_tables 得知詳情。

mysql> show status like ‘%created_tmp%’;
±------------------------±------+
| Variable_name | Value |
±------------------------±------+
| Created_tmp_disk_tables | 0 |
| Created_tmp_files | 6 |
| Created_tmp_tables | 1 |
±------------------------±------+
3 rows in set (0.00 sec)
默認配置數值是 8388608(8M),主機有 4GB 內存,可以調優值爲 268435456(256MB)。
修改/etc/my.cnf 文件,在[mysqld]下面添加如下內容
key_buffer_size=268435456 或 key_buffer_size=256M
重啓 MySQL Server 進入後,查看設置已經生效。

5、max_connect_errors
是一個 MySQL 中與安全有關的計數器值,它負責阻止過多嘗試失敗的客戶端以防止暴力破解密碼的情況,當超過指定次數,MYSQL服務器將禁止host的連接請求,直到mysql服務器重啓或通過flush hosts 命令清空此host的相關信息。max_connect_errors 的值與性能並無太大關係。

修改/etc/my.cnf 文件,在[mysqld]下面添加如下內容:
max_connect_errors=20

6、sort_buffer_size
每個需要進行排序的線程分配該大小的一個緩衝區。增加這值加速 ORDER BY 或 GROUP BY操作。
Sort_Buffer_Size 是一個 connection 級參數,在每個 connection(session)第一次需要使用這個
buffer的時候,一次性分配設置的內存。
Sort_Buffer_Size並不是越大越好,由於是connection級的參數,過大的設置+高併發可能會耗盡系統內存資源。例如:500 個連接將會消耗 500*sort_buffer_size(2M)=1G 內存
mysql> show variables like ‘%sort_buffer_size%’;
±------------------------±--------+
| Variable_name | Value |
±------------------------±--------+
| innodb_sort_buffer_size | 1048576 |
| myisam_sort_buffer_size | 8388608 |
| sort_buffer_size | 262144 |
±------------------------±--------+
3 rows in set (0.01 sec)

設置sort_buffer_size,修改/etc/my.cnf文件,在[mysqld]下面添加如下內容:
sort_buffer_size = 2M

7、max_allowed_packet
MySQL根據配置文件會限制Server接受的數據包大小。有時候大的插入和更新會受
max_allowed_packet參數限制,導致寫入或者更新失敗。最大值是1GB,必須設置 1024 的倍數。
mysql> show variables like ‘%max_allowed_packet%’;
±--------------------------±-----------+
| Variable_name | Value |
±--------------------------±-----------+
| max_allowed_packet | 67108864 |
| mysqlx_max_allowed_packet | 67108864 |
| slave_max_allowed_packet | 1073741824 |
±--------------------------±-----------+
3 rows in set (0.00 sec)

8、join_buffer_size
用於表間關聯緩存的大小,和sort_buffer_size一樣,該參數對應的分配內存也是每個連接獨享。
mysql> show variables like ‘%join_buffer_size%’;
±-----------------±-------+
| Variable_name | Value |
±-----------------±-------+
| join_buffer_size | 262144 |
±-----------------±-------+
1 row in set (0.00 sec)

9、thread_cache_size
服務器線程緩存,這個值表示可以重新利用保存在緩存中線程的數量,當斷開連接時,那麼客戶端的線程
將被放到緩存中以響應下一個客戶而不是銷燬(前提是緩存數未達上限),如果線程重新被請求,那麼請求
將從緩存中讀取,如果緩存中是空的或者是新的請求,那麼這個線程將被重新創建,如果有很多新的線
程,增加這個值可以改善系統性能。
mysql> show variables like ‘%thread_cache_size%’;
±------------------±------+
| Variable_name | Value |
±------------------±------+
| thread_cache_size | 18 |
±------------------±------+
1 row in set (0.00 sec)
通過比較 Connections和Threads_created狀態的變量,可以看到這個變量的作用。設置規則如下:
1GB 內存配置爲 8,2GB 配置爲 16,3GB 配置爲 32,4GB 或更高內存,可配置更大。
mysql> show status like ‘connections’;
±--------------±------+
| Variable_name | Value |
±--------------±------+
| Connections | 8 |
±--------------±------+
1 row in set (0.00 sec)
mysql> show status like ‘threads_%’;
±------------------±------+
| Variable_name | Value |
±------------------±------+
| Threads_cached | 0 |
| Threads_connected | 1 |
| Threads_created | 1 |
| Threads_running | 2 |
±------------------±------+
4 rows in set (0.00 sec)

Threads_cached :代表當前此時此刻線程緩存中有多少空閒線程。
Threads_connected :代表當前已建立連接的數量,因爲一個連接就需要一個線程,所以也可以看成當前被使用的線程數。
Threads_created :代表從最近一次服務啓動,已創建線程的數量,如果發現 Threads_created值過大的話,表明MySQL服務器一直在創建線程,這也是比較耗資源,可以適當增加配置文件中thread_cache_size 值。
Threads_running :代表當前激活的(非睡眠狀態)線程數。並不是代表正在使用的線程數,有時候連接已建立,但是連接處於sleep狀態。

配置InnoDB的幾個變量
10、innodb_buffer_pool_size
對於 InnoDB 表來說,innodb_buffer_pool_size 的作用就相當於 key_buffer_size對於MyISAM表的作
用一樣。InnoDB使用該參數指定大小的內存來緩衝數據和索引。對於單獨的MySQL數據庫服務器,最
大可以把該值設置成物理內存的 80%。根據 MySQL 手冊,對於 2G 內存的機器,推薦值是
1G(50%)。如果你的數據量不大,並且不會暴增,那麼無需把 innodb_buffer_pool_size 設置的太大
了。
mysql> show variables like ‘%innodb_buffer_pool_size%’;
±------------------------±-----------+
| Variable_name | Value |
±------------------------±-----------+
| innodb_buffer_pool_size | 2147483648 |
±------------------------±-----------+
1 row in set (0.00 sec)
設置 innodb_buffer_pool_size,修改/etc/my.cnf文件,在[mysqld]下面添加如下內容:
innodb_buffer_pool_size = 2048M

11、innodb_flush_log_at_trx_commit
主要控制了InnoDB將 log buffer 中的數據寫入日誌文件並 flush 磁盤的時間點,取值分別爲0、1、2三
個。
0,表示當事務提交時,不做日誌寫入操作,而是每秒鐘將 log buffer 中的數據寫入日誌文件並flush磁盤一次;
1,則在每秒鐘或是每次事物的提交都會引起日誌文件寫入、flush 磁盤的操作,確保了事務的 ACID;
2,每次事務提交引起寫入日誌文件的動作,但每秒鐘完成一次 flush 磁盤操作。
實際測試發現,該值對插入數據的速度影響非常大,設置爲 2 時插入10000條記錄只需要2秒,設置爲0
時只需要1秒,而設置爲1時則需要 229 秒。因此,MySQL 手冊也建議儘量
將插入操作合併成一個事務,這樣可以大幅提高速度。
根據 MySQL 手冊,在允許丟失最近部分事務的危險的前提下,可以把該值設爲 0 或 2。
mysql> show variables like ‘%innodb_flush_log_at_trx_commit%’;
±-------------------------------±------+
| Variable_name | Value |
±-------------------------------±------+
| innodb_flush_log_at_trx_commit | 1 |
±-------------------------------±------+
1 row in set (0.00 sec)

12、innodb_thread_concurrency
此參數用來設置 innodb 線程的併發數量,默認值爲 0 表示不限制,若要設置則與服務器的CPU 核數相
同或是cpu的核數的 2 倍,建議用默認設置,一般爲 8。
mysql> show variables like ‘%innodb_thread_con%’;
±--------------------------±------+
| Variable_name | Value |
±--------------------------±------+
| innodb_thread_concurrency | 0 |
±--------------------------±------+
1 row in set (0.00 sec)

13、innodb_log_buffer_size
此參數確定些日誌文件所用的內存大小。緩衝區更大能提高性能,對於較大的事務,可以增大緩存大
小。
mysql> show variables like ‘%innodb_log_buffer_size%’;
±-----------------------±---------+
| Variable_name | Value |
±-----------------------±---------+
| innodb_log_buffer_size | 16777216 |
±-----------------------±---------+
1 row in set (0.00 sec)

14、innodb_log_file_size
此參數確定數據日誌文件的大小,更大的設置可以提高性能。
mysql> show variables like ‘%innodb_log_file_size%’;
±---------------------±---------+
| Variable_name | Value |
±---------------------±---------+
| innodb_log_file_size | 50331648 |
±---------------------±---------+
1 row in set (0.00 sec)

15、innodb_log_files_in_group
爲提高性能,MySQL可以以循環方式將日誌文件寫到多個文件。推薦設置爲 3。
mysql> show variables like ‘%innodb_log_files_in_group%’;
±--------------------------±------+
| Variable_name | Value |
±--------------------------±------+
| innodb_log_files_in_group | 2 |
±--------------------------±------+
1 row in set (0.00 sec)

16、read_buffer_size
MySql 讀入緩衝區大小。對錶進行順序掃描的請求將分配一個讀入緩衝區,MySql 會爲它分配一段內存
緩衝區。如果對錶的順序掃描請求非常頻繁,並且你認爲頻繁掃描進行得太慢,可以通過增加該變量值
以及內存緩衝區大小提高其性能。和 sort_buffer_size 一樣,該參數對應的分配內存也是每個連接獨
享。
mysql> show variables like ‘%read_buffer_size%’;
±-----------------±-------+
| Variable_name | Value |
±-----------------±-------+
| read_buffer_size | 131072 |
±-----------------±-------+
1 row in set (0.00 sec)

17、read_rnd_buffer_size
MySql 的隨機讀(查詢操作)緩衝區大小。當按任意順序讀取行時(例如,按照排序順序),將分配一個
隨機讀緩存區。進行排序查詢時,MySql 會首先掃描一遍該緩衝,以避免磁盤搜索,提高查詢速度,如
果需要排序大量數據,可適當調高該值。但MySql會爲每個客戶連接發放該緩衝空間,所以應儘量適當
設置該值,以避免內存開銷過大。
注:順序讀是指根據索引的葉節點數據就能順序地讀取所需要的行數據。隨機讀是指一般需要根據輔助
索引葉節點中的主鍵尋找實際行數據,而輔助索引和主鍵所在的數據段不同,因此訪問方式是隨機的。
mysql> show variables like ‘%read_rnd_buffer_size%’;
±---------------------±-------+
| Variable_name | Value |
±---------------------±-------+
| read_rnd_buffer_size | 262144 |
±---------------------±-------+
1 row in set (0.00 sec)

18、bulk_insert_buffer_size
批量插入數據緩存大小,可以有效提高插入效率,默認爲 8M
mysql> show variables like ‘%bulk_insert_buffer_size%’;
±------------------------±--------+
| Variable_name | Value |
±------------------------±--------+
| bulk_insert_buffer_size | 8388608 |
±------------------------±--------+
1 row in set (0.01 sec)

19、binlog相關參數
mysql> show variables like ‘log_bin%’;
±--------------------------------±----------------------------------+
| Variable_name | Value |
±--------------------------------±----------------------------------+
| log_bin | ON |
| log_bin_basename | /data/mysql/binlogs/server1 |
| log_bin_index | /data/mysql/binlogs/server1.index |
| log_bin_trust_function_creators | OFF |
| log_bin_use_v1_row_events | OFF |
±--------------------------------±----------------------------------+
5 rows in set (0.00 sec)

binlog_cache_size: 爲每個session分配的內存,在事務過程中用來存儲二進制日誌的緩存,提高記錄bin-log的效率。沒有什麼大事務,DML也不是很頻繁的情況下可以設置小一點,如果事務大而且多,DML操作也頻繁,則可以適當的調大一點。前者建議是1M,後者建議是:2-4M;
max_binlog_cache_size: 表示的是 binlog 能夠使用的最大 cache 內存大小;
max_binlog_size: 指定binlog日誌文件的大小,如果當前的日誌大小達到max_binlog_size,還會自動創建新的二進制日誌。你不能將該變量設置爲大於 1GB 或小於4096 字節。默認值是1GB。在導入大容量的sql文件時,建議關閉 sql_log_bin,否則硬盤扛不住,而且建議定期做刪除。
expire_logs_days: 定義了mysql清除過期日誌的時間。二進制日誌自動刪除的天數。默認值爲 0,
表示“沒有自動刪除”。mysqladmin flush-logs 也可以重新開始新的binary log。

相關優化參數總結:
[mysqld]
slow_query_log = 1
slow_query_log_file = /usr/local/mysql/data/slow-query.log
long_query_time = 1
log-queries-not-using-indexes
max_connections = 1024
back_log = 128
wait_timeout = 60
interactive_timeout = 7200
key_buffer_size=256M
max_connect_errors=20
sort_buffer_size = 2M
max_allowed_packet=32M
join_buffer_size=2M
thread_cache_size=200
innodb_buffer_pool_size = 2048M
innodb_flush_log_at_trx_commit = 1
innodb_log_buffer_size=32M
innodb_log_file_size=128M
innodb_log_files_in_group=3
log-bin=mysql-bin
binlog_cache_size=2M
max_binlog_cache_size=8M
max_binlog_size=512M
expire_logs_days=7
read_buffer_size=1M
read_rnd_buffer_size=16M
bulk_insert_buffer_size=64M
log-error = /usr/local/mysql/data/mysqld.err

優化總結
基本思路如下:
性能瓶頸定位
show 命令
可以通過 show 命令查看 MySQL 狀態及變量,找到系統的瓶頸:
查看 MySQL服務器配置信息mysql> show variables;
查看 MySQL服務器運行的各種狀態值 mysql> show global status;
mysqladmin variables -u username -ppassword——顯示系統變量
mysqladmin extended-status -u username -ppassword——顯示狀態信息
慢查詢日誌
explain 分析查詢
profiling 分析查詢
索引及查詢優化
配置優化
MySQL 數據庫是常見的兩個瓶頸是CPU和I/O的瓶頸,CPU在飽和的時候一般發生在數據裝入內存或從磁盤上讀取數據時候。磁盤I/O瓶頸發生在裝入數據遠大於內存容量的時候,如果應用分佈在網絡上,那麼查詢量相當大的時候那麼平瓶頸就會出現在網絡上,我們可以用mpstat, iostat, sar 和 vmstat 來查看系統的性能狀態。
除了服務器硬件的性能瓶頸,對於MySQL系統本身,我們可以使用工具來優化數據庫的性能,通常有三種:使用索引,使用EXPLAIN分析查詢以及調整MySQL的內部配置。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章