保留個原文鏈接,避免被爬蟲爬了過去,以便后續更正補充:https://www.cnblogs.com/wy123/p/11273023.html
MySQL參數繁多,是一個需要根據具體業務、軟硬件環境、負載壓力、性能需求、數據異常的容忍程度等等信息綜合考量的結果,不是一成不變的(當然,某些參數保持默認值就夠了)。
想管好數據庫,必須理解數據庫的一些配置選項,以及其背景因素。
陸陸續續收集整理了好多MySQL相關的參數,總是覺得串不起來,總結歸類之后,立馬就清晰了很多,提到一個參數,首先會往分門別類,類別是什么,作用是什么,有哪些相關的知識點,需要注意什么。
這里根據個人的思路,用xmind做了一個歸類總結以及說明,后續會修正,補充、增加。

對於這些參數的理解與說明,來自於網絡、書籍以及自己的理解整理而成,不一定完全正確,隨時補充、更正、糾錯,這里參考了許多博客,並有大段的引用解釋,詳細情況會一一注明
General參數
server_id = XXX
In MySQL 5.7, the
--server-id
option must be specified if binary logging is enabled, otherwise the server is not allowed to start.
mysql同步的數據中是包含server_id的,用於標識該語句最初是從哪個server寫入的,因此server_id一定要有的,根據需求修改,不能重復
user
=
mysql
Mysql使用的用戶
datadir = /usr/local/mysql57/data
數據文件路徑
tmpdir = /usr/local/mysql57/tmp
臨時文件路徑
character-set-server = utf8mb4
默認server字符集
collation-server = utf8mb4_general_ci
字符序,某種字符集下,也即character-set-server已知的情況下,存在多種排序規則,指定其中一種排序規則,其實叫做排序規則更容易理解。
port = 3306
數據庫服務端口號
default_storage_engine =InnoDB
默認為InnoDB引擎
socket = /usr/local/mysql57/mysql.Sock
本機連接至MySQL服務可以使用sock方式連接,實際上是MySQL服務的進程Id
pid
-
file
=
/usr/local/mysql57/data
/
mysql
.
pid
Mysql的進程文存放位置
log_error = /usr/local/mysql57_data/mysql3306/log/mysql-error.log
啟動&錯誤日志信息
slow_query_log = on
慢查詢日志開關
long_query_time = n
界定慢查詢閾值,單位秒
log_output = file|table
慢查詢輸出位置,文件或者表,如果是文件的話,目標為slow_query_log_file ,如果是表的話,存儲在mysql.slowlog
slow_query_log_file = /usr/local/mysql57_data/mysql3306/log/slow_query_log .log
慢查詢日志文件
log_queries_not_using_indexes
捕獲沒有用到索引的查詢,同樣會記錄到慢查詢的目標中
log_bin_trust_function_creators = ON
performance_schema = ON
啟用performance_schema
######################################################################################
binlog相關參數
binlog_format = row|statment|mixed
Row level
日志中會記錄每一行數據被修改的情況,然后在slave端對相同的數據進行修改。
優點:能清楚的記錄每一行數據修改的細節
缺點:數據量太大
Statement level(默認)
每一條被修改數據的sql都會記錄到master的bin-log中,slave在復制的時候sql進程會解析成和原來master端執行過的相同的sql再次執行
優點:解決了 Row level下的缺點,不需要記錄每一行的數據變化,減少bin-log日志量,節約磁盤IO,提高新能
缺點:容易出現主從復制不一致
Mixed(混合模式)
結合了Row level和Statement level的優點,不建議使用
bin_log_cache_size
對於事務性的操作,是要事物完成的時候寫入二進制日志,事物提交之前,執行的寫入性操作會被緩存起來,直到整個事物完成,mysqld進程會將整個事物寫入二進制日志。
當事物開始的時候,會按照binlog_cache_size系統變量指定的值分配內容空間,如果指定的binlog_cache_size緩存空間不夠,執行的事務性操作回滾並提示失敗
默認是32kb
max_bin_log_cache_size
在32位的系統中是4G,64位的是16P(可以認為是也即為無窮大),max_binlog_cache_size語binlog_cache_size的區別在於前者是實例級別的cache,后者是Session級別的cache,如果並發量很大,就需要考慮將max_binlog_cache_size設置的稍微大一些。
log_bin
路徑和binlog的前綴名稱
expire_logs_days
binlog 過期清理時間閾值,單位為天,默認值為0,也即不過期,需要手動配置過期時間
sync_binlog = 0|1|n
二進制日志記錄可以使同步的,也即事物提交之后就寫入二進制日志,也可以是異步的,由操作系統的磁盤緩存覺得什么時候寫入磁盤。
由參數sync_binlog= n來控制,設置sync_binlog = 1的話,表示最高安全級別的寫入(但也不能保證不丟失任何事物日志),相當於是一種安全寫入模式,不過對性能有一定的影響。
GTID相關參數
gtid_mode = on|off
gtid模式的開關,默認是關閉的
enforce_gtid_consistency = 1
強事物一致性,開啟之后事物中不能創建臨時表
binlog_gtid_simple_recovery = 1
5.7.6以后默認是開啟,開啟之后,以更優化的方式從binlog中讀取GTID
1. 這個變量用於在
MySQL重啟或啟動的時候尋找GTIDs過程中,控制binlog 如何遍歷的算法?
2. 當binlog_gtid_simple_recovery=FALSE 時:
為了初始化 gtid_executed,算法是: 從newest_binlog -> oldest_binlog 方向遍歷讀取,如果發現有Previous_gtids_log_event , 那么就停止遍歷
為了初始化 gtid_purged,算法是: 從oldest_binlog -> newest_binlog 方向遍歷讀取, 如果發現有Previous_gtids_log_event(not empty)或者 至少有一個Gtid_log_event的文件,那么就停止遍歷
3. 當binlog_gtid_simple_recovery=TRUE 時:
為了初始化 gtid_executed , 算法是: 只需要讀取newest_binlog
為了初始化 gtid_purged, 算法是: 只需要讀取oldest_binlog
4. 當設置binlog_gtid_simple_recovery=TRUE , 如果MySQL版本低於5.7.7 , 可能會有gitd計算出錯的可能,具體參考官方文檔詳細描述
- 在線GTID升級的時候,binlog_gtid_simple_recovery = TRUE 必須打開,否則在binlog 刪除的時候,會發生阻塞狀況
- 在線GTID升級的時候,盡量將非GTID的binlog備份好,然后刪除掉,以免出現莫名其妙的錯誤
binlog_ignore相關參數
binlog-ignore-db = db1|db2
binlog會忽略配置的數據庫
replicate_wild_do_table = table_m|table_n
replicate-wild-ignore-table = table_x|table_y
對於binlog-ignore-db種,強制記錄表級別的binlog
######################################################################################
InnoDB相關參數
innodb_flush_log_at_trx_commit = 0|1|2
MySQL最經典的參數之一
如果innodb_flush_log_at_trx_commit設置為0,log buffer將每秒一次地寫入log file中,並且log file的flush(刷到磁盤)操作同時進行.該模式下,在事務提交的時候,不會主動觸發寫入磁盤的操作。
如果innodb_flush_log_at_trx_commit設置為1,每次事務提交時MySQL都會把log buffer的數據寫入log file,並且flush(刷到磁盤)中去.
如果innodb_flush_log_at_trx_commit設置為2,每次事務提交時MySQL都會把log buffer的數據寫入log file.但是flush(刷到磁盤)操作並不會同時進行。該模式下,MySQL會每秒執行一次 flush(刷到磁盤)操作。
innodb_doublewrite = 0|1
物理級保護數據安全,在將內存中的臟頁寫入磁盤之前,先將內存中的臟頁復制到內存的doublewrite buffer中(2MB),然后將doublewrite buffer的數據寫入共享表空間的頁中(128個page,2MB大小),然后再寫磁盤。
innodb_flush_method = fdatasync|O_DSYNC|O_DIRECT
控制着innodb數據文件及redo log的打開、刷寫模式,參考:https://blog.csdn.net/smooth00/article/details/72725941
redo LOG BUFFER 和redo LOG 以及數據文件的不同刷新模式
O_DIRECT繞過操作系統緩存,直接從innodb BUFFER寫磁盤,減少磁盤IO和內存的使用,會最小化緩沖對io的影響
innodb_file_per_table = 1
共享表空間或者獨立表空間,1表示每個表對應一個(組)物理文件。默認值。
innodb_buffer相關參數
buffer pool 物理內存的70%~80%,其實這個說法是一個很粗的表述,如果是128GB的物理內存,純DB服務器,配置為80%,則還剩下大概25GB左右,其實是一個很大的浪費。
innodb_buffer_pool_instances
當innodb_buffer_pool_size不大於1GB的時候,默認是1,大於1GB的時候,默認是8,也就是有8個緩沖池實例。
MySQL允許有多個緩沖池實例,每個頁根據哈希值平均分配到不同的緩沖池實例,這樣做可以減少數據庫內部的資源競爭,增加數據庫的並發能力。
innodb_additional_mem_pool_size
該參數用來存儲數據字典和其他內部數據結構。表越多,需要在這里分配的內存越多,
如果InnoDB用光了和這個池的內存,InnoDB開始從操作系統分配內存,並且往MySQL錯誤日志中寫警告信息,默認值是8MB,當發現
錯誤日志中有相關的警告信息時,就應該適當地增加該參數的大小,一般設置為16MB即可。
innodb_data相關參數
innodb_data_home_dir
這是InnoDB表的目錄共用設置。如果沒有在 my.cnf 進行設置,InnoDB 將使用MySQL的 datadir 目錄為缺省目錄
innodb_data_file_path
單獨指定數據文件的路徑與大小。數據文件的完整路徑由 innodb_data_home_dir 與這里所設定值的組合。
innodb_log相關參數,更確切地說是redo log:
innodb_log_group_home_dir
InnoDB 日志文件的路徑。默認是當前實例的數據目錄
innodb_log_files_in_group
日志組中的日志文件數目,默認是的文件個數為2,也就是兩個文件(ib_logfile0和ib_logfile1)。InnoDB 以環型方式(circular fashion)寫入文件。
innodb_log_file_size
默認是48MB,在頻繁的數據寫入的實例中為了防止redolog頻繁在兩個文件中間切換,應該配置為一個較大的值,比如500MB
。
默認值是16MB,未提交事務的緩沖區大小,如果單個事物和事物並發量不大,可以保留默認值。
innodb_thread相關參數:
Innodb_thread_concurrency
innodb_thread_sleep_delay
調整當 並發 thread 到達 innodb_thread_concurrency時需要sleep的時間
innodb_concurrency_tickets
innodb_commit_concurrency
backend Thread相關參數:
innodb_max_dirty_pages_pct
innodb_purge_threads
innodb_flush_neighbors
innodb_fast_shutdown
innodb_file:
innodb_file_format = Antelope|Barracuda
innodb_file_format_check
innodb_file_format_max
InnoDB IO相關參數
innodb_read_io_threads
在Linux平台上就可以根據CPU核數來更改相應的參數值了,默認是4。
innodb_write_io_threads
同innodb_read_io_threads
innodb_io_capacity
按照該值的百分比來控制刷新到磁盤頁的數量
1. 在合並插入緩沖時, 合並插入緩沖的數量是該值的5%
2. 在從緩沖中刷新臟頁時, 刷新的臟頁數量等於該值.
若用戶使用了ssd類的磁盤或做了磁盤陣列, 可將該值適當調大.
innodb other parameter
innodb_lock_wait_timeout
innodb_lock_wait_timeout指的是事務等待獲取資源等待的最長時間,超過這個時間還未分配到資源則會返回應用失敗;參數的時間單位是秒,最小可設置為1s
innodb_print_all_deadlocks = 0|1
是否打開記錄死鎖日志到error log中,如果要分析死鎖,設置為1,即打開
innodb_strict_mode
MySQL5.7 默認打開,嚴格語法檢查,有錯誤直接拋出,而不是給出警告。
######################################################################################
Cache 相關參數
read_buffer_size
該參數用於表的順序掃描,表示每個線程分配的緩沖區大小。比如,在進行全表掃描時,MySQL會按照數據的存儲順序依次讀取數據塊,
每次讀取的數據塊首先會暫存在read_buffer_size中,當buffer的空間被寫滿或者全部數據讀取結束后,再講buffer的數據返回給上層調用 者,以提高效率。
默認為128kb,這個參數不要設置過大,一般在128~256即可。
sort_buffer_size
在表進行order by和group by排序操作時,由於排序字段沒有索引,會出現using filesort,為了提高性能,可用此參數增加每個線程分配
的緩沖區大小。默認為2MB。這個參數不要設置的過大,一般在128~256kb即可。另外,一般出現using filesort的時候,要通過增加索引來解決。
join_buffer_size
表進行連接操作時,如果關聯的字段沒有索引,會出現using join buffer,為了提高性能,可用此參數增加每個線程分配的緩沖區大小。
默認是128kb,這個參數不要設置的過大,一般在128~256kb即可,一般出現using join buffer的時候,要通過增加索引來解決。
read_rnd_buffer_size
該參數用於表的隨機讀取,表示每個線程分配的緩沖區大小。
兩個表join的時候,加入連接字段為非聚集索引,並不是每次通過輔助索引讀取到數據就回表去取記錄,而是將其rowid給緩存起來,
然后對 rowid進行排序后,再去訪問記錄,這樣就能將隨機I/O轉化為順序I/O,從而大幅地提升性能。
tmp_table_size:
global級別內部內存臨時表的最大值,如果必須使用臨時表 且同時執行大量sql 生成大量臨時表時適當增加 tmp_table_size
如果生成的臨時表數據量大於 tmp_table_size 則會將臨時表存儲與磁盤而不是內存,默認是128MB
可以通過
Created_tmp_disk_tables
和
Created_tmp_tables
狀態來分析是否需要增加
tmp_table_size
max_heap_table_size
同tmp_table_size
, 它規定了內部內存臨時表的最大值,每個線程都要分配。(實際起限制作用的是tmp_table_size和max_heap_table_size的最小值。)
thread_cache_size:
線程池緩存大小 ( 當客戶端斷開連接后 將當前線程緩存起來 當在接到新的連接請求時快速響應 無需創建新的線程 )
connect相關參數
max_connections
最大連接數
wait_timeout
服務器關閉非交互連接之前等待活動的秒數。
Interactive_timeout
服務器關閉交互式連接前等待活動的秒數。交互式客戶端定義為在mysql_real_connect()中使用CLIENT_INTERACTIVE選項的客戶端。
connect_timeout
MySQL服務端進程mysqld等待連接建立完成的時間,單位為秒。如果超過connect_timeout時間范圍內,仍然無法完成協議握手話,MySQL客戶端會收到異常,
異常消息類似於:
Lost connection to MySQL server at 'XXX', system error:
errno,該變量默認是10秒。
max_connect_errors = N
默認值是100,不是防止暴力破解超過N次后禁止連接的,而是
計算協議握手錯誤次數之后禁用主機,並且僅用於通過驗證的主機(HOST_VALIDATED = YES)。
為了防止網絡中斷造成的連接失敗,從而造成客戶端無法連接,相反,這個值需要配置成一個較大的值,比如10000甚至更多。
相關信息記錄在select * from performance_schema.host_cache;使用 flush hosts;清理。
table_definition_cache:
table_definition_cache,該參數值的代表MySQL可以緩存的表定義的數量。和前面的table cache不同的是,表定義的緩存占用空間很小,
而且不需要使用文件描述符,也就是只要打開.frm文件,緩存表定義,然后就可以關閉.frm文件。
table_open_cache:
table_open_cache指定表高速緩存的大小。每當MySQL訪問一個表時,如果在表緩沖區中還有空間,該表就被打開並放入其中,這樣可以更快地訪問表內容。
通過檢查峰值時間的狀態值Open_tables和 Opened_tables,可以決定是否需要增加table_open_cache的值。
如果你發現open_tables等於table_open_cache,並且opened_tables在不斷增長,那么你就需要增加table_open_cache的值了(上述狀態值可:SHOW STATUS LIKE ‘Open%tables’獲得)。
query_cache
查詢緩存,不建議使用
query-cache-type:
是否打開查詢緩存
query-cache-size:
查詢緩存的大小
open_files_limit:
open_files_limit = table_open_cache*2 + innodb表
######################################################################################
Master-Slave主從復制相關參數
半同步Master端參數:
rpl_semi_sync_master_enabled
on 開啟半同步復制
rpl_semi_sync_master_timeout
參數控制,單位是毫秒,默認為10000,即10s,master等待slave超時時間,超時之后關閉半同步,轉為異步復制
rpl_semi_sync_master_wait_no_slave
ON默認值,當狀態變量Rpl_semi_sync_master_clients中的值小於rpl_semi_sync_master_wait_for_slave_count時,Rpl_semi_sync_master_status依舊顯示為ON。
OFF當狀態變量Rpl_semi_sync_master_clients中的值於rpl_semi_sync_master_wait_for_slave_count時,Rpl_semi_sync_master_status立即顯示為OFF,即異步復制。
說得直白一點,如果我的架構是1主2從,2個從都采用了半同步復制,且設置的是rpl_semi_sync_master_wait_for_slave_count=2,如果其中一個掛掉了,
對於rpl_semi_sync_master_wait_no_slave設置為ON的情況,此時顯示的仍然是半同步復制,如果rpl_semi_sync_master_wait_no_slave設置為OFF,則會立刻變成異步復制。
rpl_semi_sync_master_wait_point=wait_after_commit|wait_after_sync
參考:https://mp.weixin.qq.com/s/fvvEn6nSYzQs9NCa1eCOIQ
wait_after_commit:半同步;wait_after_sync:增強(無損)半同步
為什么要增強的半同步復制?因為傳統的半同步復制有潛在問題
wait_after_commit模式:主上客戶端發出提交指令,事務提交到了存儲引擎后,等待從傳遞過來ack,再向前端返回成功的狀態。
與無損復制的區別就是:如果在主上這個事務已經提交到了存儲引擎,而正在等待從的ack過程中---這個時候發生creash,則主上這個事務其實已經認為commit了,而從還沒commit,
在切換到從后,就會回滾最后的這個事務,這個時候主從的時候其實就不一致了
after_commit在主機事務提交后將日志傳送到從機,after_sync是先傳再提交
rpl_stop_slave_timeout ???
控制stop slave 命令的執行時間
控制stop slave 的執行時間,在重放一個大的事務的時候,突然執行stop slave,命令 stop slave會執行很久,這個時候可能產生死鎖或阻塞,嚴重影響性能,mysql
5.6可以通過rpl_stop_slave_timeout參數控制stop slave 的執行時間
######################################################################################
MySQL主從復制
Slave端參數
timeout參數
slave_net_timeout
connect_retry/master_connection_retry
master_Retry_Count
這幾個參數用一句話來解釋:
備庫過了slave_net_timeout秒之后,還沒有收到主庫來的數據,它就會開始第一次重試。
然后每過 connect_retry/master_connection_retry秒后,備庫會再次嘗試重連主庫。直到重試了 master_retry_count 次,它才會放棄重試。
performance and replication carsh safety相關參數:
master_info_repository = file|table
master_info持久化方式
sync_master_info = N
每N個事件寫入一次表/文件
relay_log_info_repository = file|table
relay_info持久化方式
sync_relay_log_info = N
每N個事件寫入一次表/文件
relay log信息如果配置為非Table模式,寫事物和寫文件(將已經應用的日志位置寫入文件)是無法保持一致的
MySQL 5.6版本通過將復制信息存放到表中來解決此問題.通過配置兩個參數 relay_log_info_repository=TABLE,master_info_repository=TABLE,
relay log info 會存放到 mysql.slave_relay_log_info表中,
master info 會存放mysql.slave_master_info表中。就是把SQL線程執行事務和更新mysql.slave_replay_log_info的語句看成一個事務處理,這樣就會一直同步的.
半同步復制Slave端相關參數
rpl-semi-sync-slave-enabled = on
Slave開啟半同步
rpl_semi_sync_master_trace_level
用於開啟半同步復制模式時的調試級別,默認是32
rpl_semi_sync_slave_trace_level
用於開啟半同步復制模式時的調試級別,默認是32
parallel replication多線程復制
slave_parallel_workers = N
slave上多個線程回放master上的binlog
slave_parallel_type = DATABASE | LOGICAL_CLOCK
DATABASE:默認值,基於庫的並行復制方式
LOGICAL_CLOCK:基於組提交的並行復制方式
slave_preserve_commit_order =0| 1
當slave_preserve_commit_order=0時
沒有辦法保證順序,在恢復的過程中會有問題,到時候你怎么start slave 呢?
start slave until SQL_AFTER_MTS_GAPS ; reset slave
Master執行順序: last_committed=0,sequence_number=1,2,3,4
slave執行順序: 有可能就是 last_committed=0,sequence_number=1,4,3,2
當slave_preserve_commit_order=1時
后一個sequence_number提交的時候,會等待前一個sequence_number完成。
Waiting for preceding transaction to commit
Slave Relay log
max_relay_log_size
標記relay log 允許的最大值,如果該值為0,則默認值為max_binlog_size(1G);如果不為0,則max_relay_log_size則為最大的relay_log文件大小;
relay_log
定義relay_log的位置和名稱,如果值為空,則默認位置在數據文件的目錄,文件名為host_name-relay-bin.nnnnnn(By default, relay log file names have the form host_name-relay-bin.nnnnnn in the data directory);
relay_log_index
同relay_log,定義relay_log的位置和名稱;
relay_log_info_repository = table|file
relay_log_info_file
設置relay-log.info的位置和名稱(relay-log.info記錄MASTER的binary_log的恢復位置和relay_log的位置),也可以配置記錄到mysql庫中的slave_relay_log_info表中;
relay-log-recovery = 1
這個參數的作用是:當slave從庫宕機后,假如relay-log損壞了,導致一部分中繼日志沒有處理,則自動放棄所有未執行的relay-log,並且重新從
master上獲取日志,這樣就保證了relay-log的完整性。默認情況下該功能是關閉的,將relay_log_recovery的值設置為 1時,可在slave從庫上開啟該功能,建議開啟。
relay-log-purge
是否自動清空不再需要中繼日志時。默認值為1(啟用)
slave沖突解決模式
slave_exec_mode = strict|idempotent|smart