MySQL5.6基本優化配置

隨着 大量默認選項的改進, MySQL 5.6比之前版本須要調優的選項大爲減小. 在本文中我將講述須要優化的配置項.mysql

InnoDB設置sql

1.innodb_buffer_pool_size  —— 默認值爲 128M. 這是最主要的優化選項,由於它指定 InnoDB 使用多少內存來加載數據和索引(data+indexes). 針對專用MySQL服務器,建議指定爲物理內存的 50-80%這個範圍. 例如,擁有64GB物理內存的機器,緩存池應該設置爲50GB左右. 
若是將該值設置得更大可能會存在風險,好比沒有足夠的空閒內存留給操做系統和依賴文件系統緩存的某些MySQL子系統(subsystem),包括二進制日誌(binary logs),InnoDB事務日誌(transaction logs)等.數據庫

2.innodb_log_file_size —— 默認值爲 48M. 有很高寫入吞吐量的系統須要增長該值以容許後臺檢查點活動在更長的時間週期內平滑寫入,得以改進性能. 將此值設置爲4G如下是很安全的. 過去的實踐代表,日誌文件太大的缺點是增長了崩潰時所需的修復時間,但這在5.5和5.6中已獲得重大改進.緩存

3.innodb_flush_method  —— 默認值爲 fdatasync. 若是使用 硬件RAID磁盤控制器, 可能須要設置爲 O_DIRECT. 這在讀取InnoDB緩衝池時可防止「雙緩衝(double buffering)」效應,不然會在文件系統緩存與InnoDB緩存間造成2個副本(copy). 
若是不使用硬件RAID控制器,或者使用SAN存儲時, O_DIRECT 可能會致使性能降低.MySQL用戶手冊 和 Bug #54306  詳細地說明了這一點.安全

4.innodb_flush_neighbors —— 默認值爲 1. 在SSD存儲上應設置爲0(禁用) ,由於使用順序IO沒有任何性能收益. 在使用RAID的某些硬件上也應該禁用此設置,由於邏輯上連續的塊在物理磁盤上並不能保證也是連續的.服務器

5.innodb_io_capacity and innodb_io_capacity_max —— 這些設置會影響InnoDB每秒在後臺執行多少操做. 若是你深度瞭解硬件性能(如每秒能夠執行多少次IO操做),則使用這些功能是很可取的,而不是讓它閒着.async


有一個很好的類比示例:  假如某次航班一張票也沒有賣出去 —— 那麼讓稍後航班的一些人乘坐該次航班,有多是很好的策略,以防後面遇到惡劣的天氣. 即有機會就將後臺操做順便處理了,以減小同稍後可能的實時操做產生競爭.

 有一個很簡單的計算:  若是每一個磁盤每秒讀寫(IOPS)能夠達到 200次, 則擁有10個磁盤的 RAID10 磁盤陣列IOPS理論上 =(10/2)* 200 = 1000. 我說它「很簡單」,是由於RAID控制器一般可以提供額外的合併,並有效提升IOPS能力. 對於SSD磁盤,IOPS能夠輕鬆達到好幾千.

 將這兩個值設置得太大可能會存在某些風險,你確定不但願後臺操做妨礙了前臺任務IO操做的性能. 過去的經驗代表,將這兩個值設置的過高,InnoDB持有的內部鎖會致使性能下降(按我瞭解到的信息,在MySQL5.6中這獲得了很大的改進).性能

innodb_lru_scan_depth - 默認值爲 1024. 這是mysql 5.6中引入的一個新選項. Mark Callaghan  提供了 一些配置建議. 簡單來講,若是增大了 innodb_io_capacity 值, 應該同時增長 innodb_lru_scan_depth.優化


複製(Replication)this

假如服務器要支持主從複製,或按時間點恢復,在這種狀況下,咱們須要:

1.log-bin —— 啓用二進制日誌. 默認狀況下二進制日誌不是事故安全的(not crash safe),但如同我 之前的文章所說, 我建議大多數用戶應該以穩定性爲目標. 在這種狀況下,你還須要啓用: sync_binlog=1, sync_relay_log=1, relay-log-info-repository=TABLE and master-info-repository=TABLE.

2.expire-logs-days —— 默認舊日誌會一直保留. 我推薦設置爲 1-10 天. 保存更長的時間並無太多用處,由於從備份中恢復會快得多.

3.server-id —— 在一個主從複製體系(replication topology )中的全部服務器都必須設置惟一的 server-id.

4.binlog_format=ROW  —— 修改成基於行的複製. 我最近寫的另外一篇 基於行的複製 ,裏面敘述了我真的很喜歡它的緣由,由於它能夠經過減小資源鎖定提升性能. 此外還須要啓用兩個附加設置:  transaction-isolation=READ-COMMITTED and  innodb_autoinc_lock_mode = 2.

其餘配置(Misc)

1.timezone=GMT  將時區設置爲格林尼治時間. 愈來愈多的系統管理員建議將全部服務器都設置爲 格林尼治時間(GMT). 我我的很是喜歡這點,由於如今幾乎全部的業務都是全球化的. 設置爲你本地的時區彷佛是有點武斷的.

2.character-set-server=utf8mb4 and collation-server=utf8mb4_general_ci  如以前的 文章所講述的 ,utf8 編碼對新應用來講是更好的默認選項. 您還能夠設置 skip-character-set-client-handshake 以忽略應用程序想要設置的其餘字符集(character-set).

3.max_connect_errors —— Todd Farmer 寫道 :「[這個功能]提供了沒有實際意義的暴力訪問攻擊保護」. 事實上當設置skip-name-resolve 時, max_connect_errors 甚至不起做用(見上一段所述).

 防火牆是更合適的解決方案,一般我將3306端口屏蔽,不論是公網的仍是內網的端口,只有特定的應用程序能夠訪問和鏈接到MySQL. 
 我一般會設置 max_connect_errors=100000, 這樣我能夠避免任何「雙重配置」,保證它不會礙事.

4.max-connections ——默認值是151. 我看到不少用戶將他設置得比較大,大多在 300 ~ 1000之間.
 一般不可避免地這個值會被設置得更大,但讓我有點緊張的是, 16核的機器在IO阻塞的狀況下也只有大約 2x~10x 的鏈接執行能力. 
 你可能但願,許多打開的鏈接都是空閒並休眠的. 但若是他們都處於活躍狀態的話,可能會建立大量新的線程(thread-thrash).
 若是條件容許,能夠爲應用程序配置優化數據庫鏈接池(connection-pools)來解決這個問題,而不是打開並保持大量鏈接; 
 固然那些不使用鏈接池(non-pooled ), 迅速打開,執行任務後又儘量快地關閉鏈接的應用也是可行的. 
 從5.5開始的另外一種解決方案(在MySQL社區版和企業版之間有一些差別) 是使用 線程池插件.


總結(Conclusion)

假設MySQL服務器的配置爲:
1.64GB物理內存
2.硬件RAID控制器(假設每秒IO可達 2000 IOPS)
3.須要主從複製(Replication)
4.新的應用(eg. 非遺留系統)
5.有防火牆保護
6.不須要基於域名(hostnames,主機名)的受權
7.全球化應用,並不想固定在某一時區.
8.想要程序可靠穩定(durable).

則配置可能以下所示:

複製代碼代碼以下:


# InnoDB settings
innodb_buffer_pool_size=50G
innodb_log_file_size=2G
innodb_flush_method=O_DIRECT
innodb_io_capacity=2000
innodb_io_capacity_max=6000
innodb_lru_scan_depth=2000

# Binary log/replication
log-bin
sync_binlog=1
sync_relay_log=1
relay-log-info-repository=TABLE
master-info-repository=TABLE
expire_logs_days=10
binlog_format=ROW
transaction-isolation=READ-COMMITTED
innodb_autoinc_lock_mode = 2

# Other
timezone=GMT
character-set-server=utf8
collation-server=utf8_general_ci
max-connect-errors=100000
max-connections=500

# Unique to this machineserver-id=123

相關文章
相關標籤/搜索