MySQL 5.7 優化InnoDB配置

InnoDB給MySQL提供了具有提交,回滾和崩潰恢復能力的事務安全(ACID兼容)存儲引擎。InnoDB鎖定在行級並且也在SELECT語句提供一個Oracle風格一致的非鎖定讀。這些特色增加了多用戶部署和性能。沒有在InnoDB中擴大鎖定的需要,因爲在InnoDB中行級鎖定適合非常小的空間。InnoDB也支持FOREIGN KEY強制。在SQL查詢中,你可以自由地將InnoDB類型的表與其它MySQL的表的類型混合起來,甚至在同一個查詢中也可以混合。

在進行優化前,我們先確認目前數據庫的配置,命令如下:

mysql> show variables like "%innodb%";

這會把所有innodb相關的參數顯示出來,接下來我們對關鍵參數進行優化。

innodb_buffer_pool_size 
這個是Innodb最重要的參數,主要作用是緩存innodb表的索引,數據,插入數據時的緩衝,默認值爲128M。 
如果是一個專用DB服務器,那麼它可以佔到內存的70%-80%。 
並不是設置的越大越好。設置的過大,會導致system的swap空間被佔用,導致操作系統變慢,從而減低sql查詢的效率。 
如果你的數據比較小,那麼可分配是你的數據大小+10%左右做爲這個參數的值。例如:數據大小爲50M,那麼給這個值分配innodb_buffer_pool_size=64M就夠了 
設置方法:在my.cnf文件裏:

innodb_buffer_pool_size=4G

innodb_log_file_size 
這個參數指定在一個日誌組中,每個log的大小。innodb的logfile就是事務日誌,用來在mysql crash後的恢復.所以設置合理的大小對於mysql的性能非常重要,直接影響數據庫的寫入速度,事務大小,異常重啓後的恢復。在mysql 5.5和5.5以前innodb的logfile最大設置爲4GB,在5.6以後的版本中logfile最大的可以設爲512GB。一般取256M可以兼顧性能和recovery的速度。 
設置方法:在my.cnf文件裏:

innodb_log_file_size=256M

innodb_log_buffer_size 
事務在內存中的緩衝,也就是日誌緩衝區的大小, 默認設置即可,具有大量事務的可以考慮設置爲16M。

innodb_flush_log_at_trx_commit 
控制事務的提交方式,也就是控制log的刷新到磁盤的方式。 
這個參數只有3個值(0,1,2).默認爲1,性能更高的可以設置爲0或是2,這樣可以適當的減少磁盤IO(但會丟失一秒鐘的事務。),遊戲庫的MySQL建議設置爲0。主庫請不要更改了。 
其中: 
0:log buffer中的數據將以每秒一次的頻率寫入到log file中,且同時會進行文件系統到磁盤的同步操作,但是每個事務的commit並不會觸發任何log buffer 到log file的刷新或者文件系統到磁盤的刷新操作; 
1:(默認爲1)在每次事務提交的時候將logbuffer 中的數據都會寫入到log file,同時也會觸發文件系統到磁盤的同步; 
2:事務提交會觸發log buffer 到log file的刷新,但並不會觸發磁盤文件系統到磁盤的同步。此外,每秒會有一次文件系統到磁盤同步操作。 
說明: 
這個參數的設置對Innodb的性能有很大的影響,所以在這裏給多說明一下。 
當這個值爲1時:innodb 的事務LOG在每次提交後寫入日值文件,並對日值做刷新到磁盤。這個可以做到不丟任何一個事務。 
當這個值爲2時:在每個提交,日誌緩衝被寫到文件,但不對日誌文件做到磁盤操作的刷新,在對日誌文件的刷新在值爲2的情況也每秒發生一次。但需要注意的是,由於進程調用方面的問題,並不能保證每秒100%的發生。從而在性能上是最快的。但操作系統崩潰或掉電纔會刪除最後一秒的事務。 
當這個值爲0時:日誌緩衝每秒一次地被寫到日誌文件,並且對日誌文件做到磁盤操作的刷新,但是在一個事務提交不做任何操作。mysqld進程的崩潰會刪除崩潰前最後一秒的事務。 
從以上分析,當這個值不爲1時,可以取得較好的性能,但遇到異常會有損失,所以需要根據自已的情況去衡量。

innodb_flush_method 
這個參數控制着innodb數據文件及redo log的打開、刷寫模式。 
有三個值:fdatasync(默認),O_DSYNC,O_DIRECT 
默認是fdatasync,調用fsync()去刷數據文件與redo log的buffer 
爲O_DSYNC時,innodb會使用O_SYNC方式打開和刷寫redo log,使用fsync()刷寫數據文件 
爲O_DIRECT時,innodb使用O_DIRECT打開數據文件,使用fsync()刷寫數據文件跟redo log。 
在類unix操作系統中,文件的打開方式爲O_DIRECT會最小化緩衝對io的影響,該文件的io是直接在用戶空間的buffer上操作的,並且io操作是同步的,因此不管是read()系統調用還是write()系統調用,數據都保證是從磁盤上讀取的

innodb_flush_method=O_DIRECT

MySQL 5.7 提供了更加合適的默認值,一般情況下只要調整下面 3 個選項就可以了,其餘參數根據實際情況再進行配置。

####innodb配置#################
innodb_buffer_pool_size=8G
innodb_log_file_size=256M
innodb_flush_method=O_DIRECT

linux服務器,內存是32G的,因爲還部署了其他應用,所有這裏buffer_pool_size就設置了8G。


 

其他配置參數註解:

複製代碼
[mysqld]
pid-file    = /var/run/mysqld/mysqld.pid
socket      = /var/run/mysqld/mysqld.sock
datadir     = /var/lib/mysql
#log-error  = /var/log/mysql/error.log
# By default we only accept connections from localhost
#bind-address   = 127.0.0.1

########basic settings########
server-id = 11 
port = 3306
user = mysql
#設置autocommit=0,則用戶將一直處於某個事務中,直到執行一條commit提交或rollback語句纔會結束當前事務重新開始一個新的事務。set autocommit=0的好處是在頻繁開啓事務的場景下,減少一次begin的交互。
autocommit = 1
#utf8mb4編碼是utf8編碼的超集,兼容utf8,並且能存儲4字節的表情字符。 
#採用utf8mb4編碼的好處是:存儲與獲取數據的時候,不用再考慮表情字符的編碼與解碼問題。
character_set_server=utf8mb4
skip_name_resolve = 1
max_connections = 800
# 對於同一主機,如果有超出該參數值個數的中斷錯誤連接,則該主機將被禁止連接。如需對該主機進行解禁,執行:FLUSH HOST。
max_connect_errors = 1000
#數據庫隔離級別
transaction_isolation = READ-COMMITTED
#MySQL在完成某些join(連接)需求的時候,爲了減少參與join的“被驅動表”的讀取次數以提高性能,需要使用到join buffer來協助完成join操作當join buffer 太小,MySQL不會將該buffer存入磁盤文件而是先將join buffer中的結果與需求join的表進行操作,然後清空join buffer中的數據,繼續將剩餘的結果集寫入次buffer中
join_buffer_size = 128M
tmp_table_size = 64M
tmpdir = /tmp
#該值設置過小將導致單個記錄超過限制後寫入數據庫失敗,且後續記錄寫入也將失敗
max_allowed_packet = 64M
#mysql在關閉一個交互的連接之前所要等待的秒數
interactive_timeout = 1200
#mysql在關閉一個非交互的連接之前所要等待的秒數
wait_timeout = 600
#MySQL讀入緩衝區的大小
read_buffer_size = 16M
#MySQL的隨機讀緩衝區大小
read_rnd_buffer_size = 8M
#MySQL的順序讀緩衝區大小
sort_buffer_size = 8M
########log settings########
log_error = /var/log/docker_log/mysql/error.log
#開啓慢查詢日誌
slow_query_log = 1
#超出次設定值的SQL即被記錄到慢查詢日誌
long_query_time = 6
slow_query_log_file = /var/log/docker_log/mysql/slow.log
#表示記錄下沒有使用索引的查詢
log_queries_not_using_indexes = 1
#記錄管理語句
log_slow_admin_statements = 1
#開啓複製從庫複製的慢查詢的日誌
log_slow_slave_statements = 1
#設置每分鐘增長的沒有使用索引查詢的日誌數量
log_throttle_queries_not_using_indexes = 10
expire_logs_days = 90
min_examined_row_limit = 100
########replication settings########
#將master.info和relay.info保存在表中
master_info_repository = TABLE
relay_log_info_repository = TABLE
log_bin = bin.log
#當每進行n次事務提交之後,MySQL將進行一次fsync之類的磁盤同步指令來將binlog_cache中的數據強制寫入磁盤。設置爲零是讓系統自行決定
sync_binlog = 5
#開啓全局事務ID,GTID能夠保證讓一個從服務器到其他的從服務器那裏實現數據複製而且能夠實現數據整合的
gtid_mode = on
#開啓gtid,必須主從全開
enforce_gtid_consistency = 1
#從服務器的更新是否寫入二進制日誌
log_slave_updates = 1
#三種模式 STATEMENT(有可能主從數據不一致,日質量小)、ROW(產生大量二進制日誌)、MIXED
binlog_format = mixed
#relay-log日誌記錄的是從服務器I/O線程將主服務器的二進制日誌讀取過來記錄到從服務器本地文件,然後SQL線程會讀取relay-log日誌的內容並應用到從服務器
relay_log = /var/log/docker_log/mysql/relay.log
relay_log_recovery = 1
#開啓簡單gtid,開啓此項會提升mysql執行恢復的性能
binlog_gtid_simple_recovery = 1
slave_skip_errors = ddl_exist_errors
########innodb settings########
#這個參數在一開始初始化時就要加入my.cnf裏,如果已經創建了表,再修改,啓動MySQL會報錯。最好爲8K
#innodb_page_size = 16K
innodb_page_size = 8K
#數據緩衝區buffer pool大小,建議使用物理內存的 75%
innodb_buffer_pool_size = 2G
#當buffer_pool的值較大的時候爲1,較小的設置爲8
innodb_buffer_pool_instances = 8
#運行時load緩衝池,快速預熱緩衝池,將buffer pool的內容(文件頁的索引)dump到文件中,然後快速load到buffer pool中。避免了數據庫的預熱過程,提高了應用訪問的性能
innodb_buffer_pool_load_at_startup = 1
#運行時dump緩衝池
innodb_buffer_pool_dump_at_shutdown = 1
#在innodb中處理用戶查詢後,其結果在內存空間的緩衝池已經發生變化,但是還未記錄到磁盤。這種頁面稱爲髒頁,將髒頁記錄到磁盤的過程稱爲刷髒
innodb_lru_scan_depth = 2000
innodb_io_capacity = 4000
innodb_io_capacity_max = 8000
#事務等待獲取資源等待的最長時間,超過這個時間還未分配到資源則會返回應用失敗,默認50s
innodb_lock_wait_timeout = 30
#日誌組所在的路徑,默認爲data的home目錄;
innodb_log_group_home_dir = /data/mysql/
#innodb_undo_directory = /data/mysql/undolog/
#這個參數控制着innodb數據文件及redo log的打開、刷寫模式,http://blog.csdn.net/gua___gua/article/details/44916207
#innodb_flush_method = O_DIRECT-不經過系統緩存直接存入磁盤,
innodb_file_format = Barracuda
innodb_file_format_max = Barracuda
innodb_strict_mode = 1
#innodb獨享表空間,有點很多,缺點會導致單個表文件過大
#innodb_file_per_table = 1
#undo日誌回滾段 默認爲128
innodb_undo_logs = 128
#傳統機械硬盤建議使用,而對於固態硬盤可以關閉
#innodb_flush_neighbors = 1
innodb_log_file_size = 1G
innodb_log_buffer_size = 64M
#控制是否使用獨立purge線程
innodb_purge_threads = 1
#改爲ON時,允許單列索引最大達到3072。否則最大爲767
innodb_large_prefix = 1
innodb_thread_concurrency = 8
#開啓後會將所有的死鎖記錄到error_log中
innodb_print_all_deadlocks = 1
innodb_sort_buffer_size = 16M 
########semi sync replication settings########
#半同步複製
plugin_load = "rpl_semi_sync_master=semisync_master.so;rpl_semi_sync_slave=semisync_slave.so"
loose_rpl_semi_sync_master_enabled = 1
loose_rpl_semi_sync_slave_enabled = 1
loose_rpl_semi_sync_master_timeout = 5000
#表示轉儲每個bp instance LRU上最熱的page的百分比。通過設置該參數可以減少轉儲的page數。
innodb_buffer_pool_dump_pct = 40
#刷髒的進程N-1
innodb_page_cleaners = 4
innodb_undo_log_truncate = 1
innodb_max_undo_log_size = 2G
#控制回收(收縮)undo log的頻率.undo log空間在它的回滾段沒有得到釋放之前不會收縮,
innodb_purge_rseg_truncate_frequency = 128
log_timestamps=system
#該參數基於MySQL5.7 Group Replication組複製的,沒有使用不要設置
#transaction_write_set_extraction=MURMUR32
#http://www.cnblogs.com/hzhida/archive/2012/08/08/2628826.html
show_compatibility_56=on
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章