前言:全文中一共有常用的(事實上你如果花1-2周閱讀、理解、自己動手設一下后是需要這么多參數(shù)的)76個參數(shù),筆者把近10年里3個億萬級項目的數(shù)據(jù)庫調(diào)優(yōu)用此篇濃縮到了可能讀者只需要2周時間就可以掌握,同時我是按照:
每一個參數(shù)干嗎?
在某些典型硬件配置下的db上參數(shù)該設多少?
設會怎么樣?
不設會怎么樣?
有什么坑如何填坑?
有些參數(shù)怎么算、算法又如何
這種style來寫的,相信此篇會對一些使用mysql的尤其是正在或者將要面臨萬級并發(fā)的項目、網(wǎng)站有所幫助。具體請看文檔!
一千個DBA就有一千種配置方式!
大家一定記得不要輕易去看網(wǎng)上,要看只看官網(wǎng)!網(wǎng)上很多博客都是錯的,連參數(shù)都列錯了,5.7很多參數(shù)和5.6是完全不一樣的。
可能你從未看到過這樣的一篇集中火力式的把mysql參數(shù)列了這么全的文章,很有興曾參與過超3萬并發(fā)的18~19年的數(shù)輪520、618、雙11、雙12保衛(wèi)戰(zhàn)。因此這一篇是匯集了最精華和實戰(zhàn)的內(nèi)容把mysql所有的參數(shù)列在這邊供大家參考。并且以(64c cpu,128gb內(nèi)存)的mysql cpu和內(nèi)存來進行了一輪配置。而此文的內(nèi)存相關參數(shù)部分可以延展至256gb~512gb。
另外有一點,建議在mysql的服務器上使用ssd。除非并發(fā)數(shù)永遠控制在500-1000內(nèi)那就沒必要使用ssd,普通高速磁盤就可以了。
你會發(fā)覺這篇文章是一篇寶藏,這些參數(shù)都能夠自己動手試驗一篇基本在外面是可以吊打mysql面試官了。
client域:
1.character_set_client
推薦設置:
utf8mb4
作用:
字符集設定,如果前臺有連social mobile application一類包括wechat,并且允許有使用emoji表情的,請開啟成utf8mb4
如果不配的后果:
mysql不支持前端app存表情等字符
配置實例:
character_set_client=utf8mb4
mysqld域:
1)server-id
推薦設置:
如果沒有做任何主從復制,此值可以不設。
作用:
遇有主從復制,必設該值,每個參與主從復制的mysql實例的server-id不能重復,必須為阿拉伯數(shù)字。
如果不配的后果:
如果你用的是主從復制,這個id不設那么整個mysql的主從復制會失幾。
配置實例:
server-id=1
2)port
推薦設置:
3306
作用:
mysql實例端口
如果不配的后果:
默認為3306
配置實例:
port=3306
3)bind_address
推薦設置:
0.0.0.0
作用:
除非有特殊需要,我們會限制只允許mysql實例被某一個ip方問,不支持多個,生產(chǎn)上都為:0.0.0.0然后使用防火墻策略來控制。
如果不配的后果:
默認不允許遠程登錄
配置實例:
bind_address=0.0.0.0
4)autocommit
推薦設置:
1
作用:
生產(chǎn)上開啟成1,如果你開啟的是0會有一個這樣的情況:
a運行一條insert語句,并未作commit;b去做查詢此時b是查詢不到的。這種操作一般用于在寫store procedure時用到。
如果不配的后果:
如果在系統(tǒng)的my.cnf層面把它設成了0,如果在使用時(99%情況是用的1)時,你想要用root在生產(chǎn)運行時把它設成set autocommit = 1都開啟不了。而如果你在一開始就沒它設置成1,那么當碰到某些特殊場景特別是寫store procedure時需要把它設成0時,你是可以手動臨時把某一個session給開在0的。
配置實例:
autocommit = 1
5)character_set_server
推薦設置:
utf8mb4
作用:
字符集設定,如果前臺有連social mobile application一類包括wechat,并且允許有使用emoji表情的,請開啟成utf8mb4
如果不配的后果:
mysql不支持前端app存表情等字符
配置實例:
character_set_server=utf8mb4
6)skip_name_resolve
推薦設置:
1
作用:
生產(chǎn)上建議開啟成1,這樣mysql server不會對客戶端連接使用反向dns解析,否則客戶端連上后有時在遇有生產(chǎn)高速運行時直接timeout,如果設成了1帶來的問題就是你不能在mysql中使用主機名來對客戶端權限進行劃分,而是需要使用ip。
如果要做成即允許mysql里允許使用主機名來分配客戶端連接權限,又要做到不要讓mysql去做dns解析,可以在mysql所在主機端的/etc/hosts文件中寫上客戶端的主機名,因為當客戶端連接連上來時,mysql反向查找客戶端連接時的域名解析的步驟是:首先查找 /etc/hosts 文件,搜索域名和IP的對應關系。但是這樣做也有一個問題,那就是如果你有多個客戶端多個mysql主從關系,哪到你要把mysql做成一個dns解析器嗎?因此推薦設成1
如果不配的后果:
mysql server每一次會對客戶端連接使用反向dns解析,經(jīng)常會出現(xiàn)客戶端連上后有timeout現(xiàn)象。
配置實例:
skip_name_resolve=1
7)max_connections
推薦設置:
20,000
作用:
最大連接數(shù),以微品會:前端3萬的tps并發(fā),假設redis命中失效50%(這是災難),那么后端mysql單個主或從開啟連接數(shù)為:20,000,我們公司在前端并發(fā)曾達到過6萬,80%被waf、vanish、緩存擋掉,落在db上的qps最高一次為20,000連接,再按照mysql官方,max_connections值受系統(tǒng)os最大打開連接數(shù)限制,因此我們需要做以下2步操作:
1)在 /etc/security/limits.conf 底部增加2行
mysql hard nofile65535mysql soft nofile65535
2)在/usr/lib/systemd/system/mysqld.service(視如何安裝mysql所決定,用編譯安裝和yum安裝會產(chǎn)生path路徑不同。)文件最后添加:
LimitNOFILE=65535
LimitNPROC=65535
$ systemctl daemon-reload
$ systemctl restart mysqld.service
如不生效重服務器。
如果不配的后果:
默認只有150
配置實例:
max_connections = 20,000
8)max_connect_errors
推薦設置:
生產(chǎn)上設10
開發(fā)測試上使用默認-100
作用:
生產(chǎn)上開啟成10次,開發(fā)測試上使用默認即不設。
max_connect_errors是一個MySQL中與安全有關的計數(shù)器值,它負責阻止過多嘗試失敗的客戶端以防止暴力破解密碼的情況。如果需要設置此數(shù)值,手動添加。當此值設置為10時,意味著如果某一客戶端嘗試連接此MySQL服務器,但是失?。ㄈ缑艽a錯誤等等)10次,則MySQL會無條件強制阻止此客戶端連接。相關的登錄錯誤信息會記錄到performance_schema.host_cache表中。如果希望重置此計數(shù)器的值,則必須重啟MySQL服務器或者執(zhí)行
Mysql> FLUSH HOSTS;
1 Mysql> FLUSH HOSTS;
當這一客戶端成功連接一次MySQL服務器后,針對此客戶端的max_connect_errors會清零??梢栽诜阑饓ι献霾呗韵拗颇承﹊p的遠程連接。
如果不配的后果:
默認為100
配置實例:
max_connect_errors =10
9)innodb_flush_log_at_trx_commit
推薦設置:
2
作用:
(核心交易系統(tǒng)設置為1,默認為1,其他2或者0),
0代表:log buffer將每秒一次地寫入log file中,并且log file的flush(刷到磁盤)操作同時進行。該模式下在事務提交的時候,不會主動觸發(fā)寫入磁盤的操作。
1代表:每次事務提交時MySQL都會把log buffer的數(shù)據(jù)寫入log file,并且flush(刷到磁盤)中去,該模式為系統(tǒng)默認(因此會保留每一份redo日志)
2代表:每次事務提交時MySQL都會把log buffer的數(shù)據(jù)寫入log file,但是flush(刷到磁盤)操作并不會同時進行。該模式下,MySQL會每秒執(zhí)行一次 flush(刷到磁盤)操作。該模式速度較快,也比0安全,只有在操作系統(tǒng)崩潰或者系統(tǒng)斷電的情況下,上一秒鐘所有事務數(shù)據(jù)才可能丟失。
除非你用的是小型機或者是超大規(guī)模mysql集群一類如:游戲行業(yè),那么需要保留每一秒的事務,否則請設成2,要不然會嚴重影響系統(tǒng)性能。這個參數(shù)是5.6所沒有的。
如果不配的后果:
默認為1,影響系統(tǒng)寫性能。
配置實例:
innodb_flush_log_at_trx_commit=2
10)transaction_isolation
推薦設置:
READ-COMMITTED
作用:
此參數(shù)直接決定了mysql的性能,oracle中的事務默認級別就是read-commited,而mysql的默認級別是:repeatable-read,它利用自身獨有的Gap Lock解決了"幻讀"。但也因為Gap Lock的緣故,相比于READ-COMMITTED級別的Record Lock,REPEATABLE-READ的事務并發(fā)插入性能受到很大的限制。離級別的選擇取決于實際的業(yè)務需求(安全與性能的權衡),如果不是金融、電信等事務級別要求很高的業(yè)務,完全可以設置成transaction_isolation=READ-COMMITTED。
Repeatable-read: 這是MySQL的InnoDB引擎默認的隔離級別,它阻止查詢的任何行被其他事務更改。因此,阻塞不可重復讀,而不是幻讀。也就是說在可重復讀中,可能會出現(xiàn)幻讀。重復讀使用一種中等嚴格的鎖定策略,以便事務中的所有查詢都能看到來自相同快照(即事務啟動時的數(shù)據(jù))的數(shù)據(jù)。當擁有該級別的事務執(zhí)行 UPDATE ... WHERE, DELETE ... WHERE, SELECT ... FOR UPDATE和LOCK IN SHARE MODE操作時,其他事務可能需要等待。
Read-Committed-推薦: 事務無法看到來自其他事務的未提交數(shù)據(jù),但可以看到當前事務啟動后另一個事務提交的數(shù)據(jù)。當擁有這種級別的事務執(zhí)行 UPDATE ... WHERE or DELETE ... WHERE操作時,其他事務可能需要等待。但是該事務可以執(zhí)行 SELECT ... FOR UPDATE, and LOCK IN SHARE MODE操作,其他事務不需要等待。
串行化(SERIALIZABLE)-極力不推薦,串行化隔離級別是最高的隔離級別,它使用了最保守的鎖策略。它阻止任何其他事務插入或更改此事務讀取的數(shù)據(jù),直到該事務完成。簡單的來說,就是一個事務一個事務的來執(zhí)行,顯然性能會很低。在這種隔離級別下,一個事務中的相同查詢可以反復執(zhí)行,每次查詢結果是一樣的。從當前事務開始執(zhí)行,任何更改另一個事務提交的數(shù)據(jù)的嘗試都會導致當前事務等待(阻塞)。這是SQL標準指定的默認隔離級別(注意不是MySQL)。在實踐中,這種嚴格程度是很少需要的。
讀未提交(READ-UNCOMMITTED)-它是最低的隔離級別,雖然性能最高,但也不推薦
它會讀取到其他事務修改尚未提交的數(shù)據(jù),使用此隔離級別就需要非常小心,認識到這種級別下的查詢結果可能不一致或不可復制,這取決于其他事務同時在做什么。通常,具有此隔離級別的事務只執(zhí)行查詢,而不執(zhí)行插入、更新或刪除操作。
在實際環(huán)境中,應當根據(jù)是否允許出現(xiàn)臟讀(dirty reads),不可重復讀(non-repeatable reads)和幻讀(phantom reads )現(xiàn)象而選擇相應的隔離級別。例如在大數(shù)據(jù)中,少量的數(shù)據(jù)不一致不會影響到最后的決策,這種情況下可以使用較低的隔離級別以提交性能和并發(fā)性。
如果不配的后果:
默認就是repeatable-read
配置實例:
transaction_isolation = READ-COMMITTED
11)explicit_defaults_for_timestamp
推薦設置:
1
作用:
mysql5.7默認對于timestamp字段會顯示“系統(tǒng)當前日期”,就算你在插表時這個timestamp字段留空,它在select出來時也會顯示系統(tǒng)日期。因此,這個值的影響范圍是你在建表時導致的。
系統(tǒng)默認這個值是0,在0的情況下,你要讓該表的timestamp字段在為null時不顯示系統(tǒng)默認時間,你的建表必須為:create table order(o_id int ,updateed_time timestamp null default null) ;
explicit_defaults_for_timestamp 變量會直接影響表結構,也就是說explicit_defaults_for_timestamp的作用時間是在表定義的時候;你的update | insert 想通過它去改變行為已經(jīng)太晚了!
因此,我推薦把這個值設為1.
如果不配的后果:
默認為0
配置實例:
explicit_defaults_for_timestamp = 1
12)join_buffer_size
推薦設置:
16M
作用:
系統(tǒng)默認大小為:512k,mac下默認大小為:256k,針對128GB,1萬并發(fā)的mysql我推薦給到的值為:8~16M
對于JOIN KEY 有索引和二級索引,JOIN KEY 無索引mysql會使用到join_buffer_size,一般建議設置一個很小的 GLOBAL 值,完了在 SESSION 或者 QUERY 的基礎上來做一個合適的調(diào)整。如果你拍腦袋給也個4g,我們有1000個并發(fā),就是用掉了4T的內(nèi)存。。。4T啊。。。你以為你是小型機。適當?shù)娜ジ淖兯_實可以帶來一定的提速,但并不是說很多值越大越好,為什么我們設置成4m呢?我們假設我們的mysql所在的vm是128gb,一根這樣的join(如果被用到)是4M,1萬個也不過用掉40G,而根據(jù)官方說法,total加在一起產(chǎn)生的join_buffer_size不要超過你所在系統(tǒng)的50%.默認512k肯定是小了點,我們可以適當放寬,比如說:2M,在實際使用場景時我們發(fā)覺有這樣的高頻操作(要看高頻出現(xiàn)的有意義的sql的執(zhí)行計劃,并確認該計劃的:執(zhí)行cost如: "query_cost": "1003179606.87",它產(chǎn)生的cost為:0.93個G,如果它真的很高頻出現(xiàn)在調(diào)優(yōu)sql到無法調(diào)優(yōu)的程度,我們會去做set session join_buffer_size = 1024 * 1024 * 1024;這樣的操作。而不是在一開始的my.cnf中去分配一個暴大的值,我們這邊基于128gb,1萬connection的并發(fā)來說,你給個16M不算小也不算多,我推薦給到8~16M間(這是指在一開始)。
如果不配的后果:
默認的為256k
配置實例:
join_buffer_size = 16M
13)tmp_table_size
推薦設置:
67108864
作用:
如果是128gb內(nèi)存的服務器,我建議是在my.cnf中設成64M
通過設置tmp_table_size選項來增加一張臨時表的大小,例如做高級GROUP BY操作生成的臨時表。默認系統(tǒng)為32M,如果當你的臨時表越來越多加在一起超過了這個值,那么mysql會在系統(tǒng)磁盤上創(chuàng)建,這個值不是越多越好,也沒有一個合適的值。一開始的建議為>64M,然后在運行時我們通過以下公式來做臨時調(diào)優(yōu),
show global status like 'created_tmp%';
把得到的結果中的:(Created_tmp_disk_tables / Created_tmp_tables) * 100% 如果<=25%為最佳值。注意了,在生產(chǎn)時熱設定時一定要用類似以下算法:
set global tmp_table_size=64*1024*1024而不是set global tmp_table_size=64M。
如果不配的后果:
默認為32M
配置實例:
tmp_table_size = 67108864
14)tmpdir
這塊參數(shù)可以讓運維給到,放到大空間里就行了,沒什么太敏感的。
15)max_allowed_packet
推薦設置:
134217728
作用:
如果你經(jīng)常在應用層碰到了:Got a packet bigger than'max_allowed_packet' bytes,這時你可以使用
show variables like '%max_allowed_packet%';來查看這個值,這個值沒有合適,一般如:用客戶端導入數(shù)據(jù)的時候,遇到 錯誤代碼: 1153 - Got a packet bigger than 'max_allowed_packet' bytes 終止了數(shù)據(jù)導入。這樣的場景下,當MySQL客戶端或mysqld服務器收到大于max_allowed_packet字節(jié)的信息包時,將發(fā)出“信息包過大”錯誤,并關閉連接。對于某些客戶端,如果通信信息包過大,在執(zhí)行查詢期間,可能會遇到“丟失與MySQL服務器的連接”錯誤。
客戶端和服務器均有自己的max_allowed_packet變量,因此,如你打算處理大的信息包,必須增加客戶端和服務器上的該變量。一般情況下,服務器默認max-allowed-packet為1MB,可以通過在交換機上抓包或者是圖形化分析來抓返回結果判斷。一般推薦在128gb內(nèi)存下設置的置為128M.也可以在運行時動態(tài)調(diào)整:set global max_allowed_packet = 128*1024*1024
如果不配的后果:
1M
配置實例:
max_allowed_packet = 134217728
16)sql_mode
不需要去設置,使用默認的,這塊和性能無關。我們的中臺中的sql如果碰到有sql報錯,因該是在測試環(huán)境上就已經(jīng)報了,它的作用是用來約束你sql的寫法的,如果是一個從頭開始開發(fā)的應用,我們比如說約束好都是ansi sql寫法,對于一個產(chǎn)品,不要去做這種畫蛇添足的做法。
17)interactive_timeout
推薦設置:
600
作用:
單位為s,系統(tǒng)默認為:28800s即8小時。如果這2個值太大,你會發(fā)覺在mysql中有大量sleep的連接,這些連接又被稱為:僵尸連接,僵尸連接一多你真正要用的時候就會拋:too many connection這樣的錯,因此對于長久不用的連接,我們一般要使用“踢出機制”,多久對于一個活動累的sql進行踢呢?我們說如果有一個長事務,它要執(zhí)行1小時,我不知道這是不是屬于正常?當然如果你設了太短,說1分鐘就把它踢了,還真不一定踢的對,按照我們在oracle中設置的best practice我們都會把它放到10分鐘。你有一條sql連著,10分鐘不用,我就把它踢了,這也算正常。但是在高并發(fā)的場景下這個timeout會縮短至3-5分鐘,這就是為什么我提倡我們的非報表即時類查詢需要優(yōu)化到sql的運行時間不超過300ms的原因,因為在高并發(fā)場景下,超過500ms的sql都已經(jīng)很夸張了。保守點我覺得可以設成10分釧,在應用端由其通過jdbc連接數(shù)據(jù)庫的,做的好的應用都會在jdbc里有一個autoconnect參數(shù),這個autoconnect參數(shù)就要和mysql中的wait_timeout來做匹配了。同時在應用端要有相應的validate sql一類的操作來keep alived。不過我更推薦使用”連接池內(nèi)連接的生存周期(idleConnectionTestPeriod)”來做設置,把這個置設成<mysql內(nèi)的這兩個值將會是最好,同時,idleConnectionTestPeriod會使用到異步的方式去做超時check。如c3p0中的:idleConnectionTestPeriod和testConnectionOnCheckin相當可靠
interactive_timeout:交互式連接超時時間(mysql工具、mysqldump等)
wait_timeout:非交互式連接超時時間,默認的連接mysql api程序,jdbc連接數(shù)據(jù)庫等
interactive_timeout針對交互式連接,wait_timeout針對非交互式連接。所謂的交互式連接,即在mysql_real_connect()函數(shù)中使用了CLIENT_INTERACTIVE選項。
showglobalvariableslike'wait_timeout';
1 timeout 只是針對空閑會話有影響。
2 session級別的wait_timeout繼承global級別的interactive_timeout的值。而global級別的session則不受interactive_timeout的影響。
3 交互式會話的timeout時間受global級別的interactive_timeout影響。因此要修改非交互模式下的timeout,必須同時修改interactive_timeout的值。
4 非交互模式下,wait_timeout參數(shù)繼承global級別的wait_timeout。
如果不配的后果:
系統(tǒng)默認為28800
配置實例:
interactive_timeout = 600
18)wait_timeout
同interactive_timeout,兩個值都設成一樣。
19)read_buffer_size
推薦設置:
4194304
作用:
這個值其實輕易是用不到的,因為,它只對2種場景的full table scan產(chǎn)生影響而不是所有的full table scan,同時從mysql5.6以后開始沒有數(shù)據(jù)塊多塊讀的功能,與是否設置 read_buffer_size參數(shù)無關。應用場景:
1)SELECT INTO … OUTFILE ‘fileName‘
2)When filesort is used, during merge buffers and when merged results are written to a temporary file, then writes are buffered
一般保留默認:64k,保守作法是設置在1~4M,不過它的應用場景很有限,對于互聯(lián)網(wǎng)場景真的不太用,我推薦設成4M
如果不配的后果:
默認為64k
配置實例:
read_buffer_size = 4194304
20)read_rnd_buffer_size
推薦設置:
8388608
作用:
就是當數(shù)據(jù)塊的讀取需要滿足一定的順序的情況下,MySQL 就需要產(chǎn)生隨機讀取,進而使用到 read_rnd_buffer_size 參數(shù)所設置的內(nèi)存緩沖區(qū)。它的默認為256k,最大可以設到2G,它會對order by關鍵字起作用,當order by的計劃成本超出了sort_buffer_size后,mysql會產(chǎn)用隨機讀取并消耗額外的內(nèi)容,很多外面的博客說它是只對myisam引擎起作用,但其實不是,該參數(shù)還真的覆蓋到所有引擎,一般它的推薦設置在8-16M,我推薦8M,根據(jù)sql分析計劃如果碰到高頻的查詢且order by的返回包體都很大,那么再在session級別去放。
如果不配的后果:
默認為256k
配置實例:
read_rnd_buffer_size = 8388608
21)sort_buffer_size
推薦設置:
4194304
作用:
每個會話執(zhí)行排序操作所分配的內(nèi)存大小。想要增大max_sort_length參數(shù),需要增大sort_buffer_size參數(shù)。如果在SHOW GLOBAL STATUS輸出結果中看到每秒輸出的Sort_merge_passes狀態(tài)參數(shù)很大,可以考慮增大sort_buffer_size這個值來提高ORDER BY 和 GROUP BY的處理速度。建議設置為1~4MB。當個別會話需要執(zhí)行大的排序操作時,在會話級別增大這個參數(shù)。所謂會話級別,我舉個例子,你拍腦袋一下,說我設個32M,你所它乘10,000請求,這得多大內(nèi)存。另外,千萬要注意,在mysql內(nèi)存,當你的sort_buffer_size在超過2K時在底層使用的是mmap()的c函數(shù)去做內(nèi)存分配的,而不是malloc(),做過c的都知道m(xù)map()是一個矢量單位,因此它會付出性能的影響,能影響多少呢?單條sql影響值在30%。
如果不配的后果:
默認值為1M
配置實例:
sort_buffer_size =4194304
22)innodb_page_size
推薦設置:
8192
作用:
這個值可要小心,一般它在設置后就不能輕易改了,一般來說我們都認為,值越大越好,不是的, 這個值它的原理是這樣的:size越小,內(nèi)存劃分粒度越大,使用率越高,但是會有其他問題,就是限制了索引字段還有整行的大小。innodb引擎讀取內(nèi)存還有更新都是一頁一頁更新的,這個innodb_page_size決定了,一個基本頁的大小。常用B+Tree索引,B+樹是為磁盤及其他存儲輔助設備而設計一種平衡查找樹(不是二叉樹)。B+樹中,所有記錄的節(jié)點按大小順序存放在同一層的葉子節(jié)點中,各葉子節(jié)點用指針進行連接。MySQL將每個葉子節(jié)點的大小設置為一個頁的整數(shù)倍,利用磁盤的預讀機制,能有效減少磁盤I/O次數(shù),提高查詢效率。 如果一個行數(shù)據(jù),超過了一頁的一半,那么一個頁只能容納一條記錄,這樣B+Tree在不理想的情況下就變成了雙向鏈表。我們拿白話來說就是:你越大,空間利用率更高,但是越小呢越有助于性能但是這邊一定一定有一個“但是”,但是小到一定的量反而性能不好,為什么呢?太大上面我已經(jīng)舉例了,太小。。。mysql的頁間的check point太頻繁。怎么樣做才能達到一個合理值呢?
這個我們是在全真生產(chǎn)環(huán)境、全數(shù)據(jù)量下用測試工具去對4k,8k,16k三種場景壓測得到的吞吐量即tps來做觀察的,我這邊可以給出一個推薦值,以單表超1000w條數(shù)據(jù)基于中臺1.1的數(shù)據(jù)庫結果(每個表都超1000w),我們在設置該值為:8K時,它的吞吐達到最優(yōu)。
如果不配的后果:
32位下默認為8192
64位下默認為16384
配置實例:
innodb_page_size = 8192
23)innodb_buffer_pool_size
推薦設置:
72G
作用:
這個值和innodb_buffer_pool_instances相輔相成。在32位機器下,innodb_buffer_pool_instances一般為1,在64位機器上,這個值為8-64.
pool_instances其實為cpu核數(shù),它的作用是:
1)對于緩沖池在數(shù)千兆字節(jié)范圍內(nèi)的系統(tǒng),通過減少爭用不同線程對緩存頁面進行讀寫的爭用,將緩沖池劃分為多個單獨的實例可以提高并發(fā)性。
2)使用散列函數(shù)將存儲在緩沖池中或從緩沖池讀取的每個頁面隨機分配給其中一個緩沖池實例。每個緩沖池管理自己的空閑列表, 刷新列表, LRU和連接到緩沖池的所有其他數(shù)據(jù)結構,并受其自己的緩沖池互斥量保護。
innodb_buffer_pool_size的設置需要為pool_instance的整數(shù)倍。
網(wǎng)上很多說innodb_buffer_pool_size為系統(tǒng)的70%,這是錯的!因為你真的設了70%你的swap空間會被擠壓,你不要忘了你還有os,上面還可能有監(jiān)控agent端。一旦swap空間被擠壓后你的mysql反面嚴重拖慢讀寫。
此處強烈建議設成內(nèi)存的20%-65%間(獨立的mysql服務器),為什么有一個20%呢?對于<4gb的mysql用服務器來說按照20%系統(tǒng)內(nèi)存來設置。由于我們是128gb的內(nèi)存,此處我建議使用72G,如果內(nèi)存超過128gb,一般我們會把pool instance設成16個,每個開啟10g左右的buffer_pool_size,對于256gb內(nèi)存的服務器來說我們可以這樣設。
如果不配的后果:
默認為64
配置實例:
innodb_buffer_pool_size = 72G
24)innodb_buffer_pool_instances = 8
這個參數(shù)同innodb_buffer_pool_size一起講解了。
25)innodb_buffer_pool_load_at_startup
推薦設置:
0
作用:
這兩個參數(shù)幾乎沒人用一般dba也不曾聽說過,它是什么意思呢?Mysql在第一次(重啟)時,它的buffer_pool_size中是空的,隨著mysql運行時間1-2小時后,它的buffer_pool_size里開始被塞入東西,它分為old block與new block,而此時mysql性能開始一點點讀寫效率上去了,那是因為在buffer_pool_size沒有放入東西時,mysql很多讀寫發(fā)生在硬盤上,從硬盤到內(nèi)存的加載過程是一個比較漫長和耗時的過程,因此我們往往會設一個startup=1以加快這個“預熱”過程,它與參數(shù)shutdown配合使用,即相當于把上次使用的innot_db_buffer_pool里的東西在啟動時先做一次加載,以加快mysql的性能。它會在innodb的數(shù)據(jù)目錄中生成一個文件:ib_buffer_pool。高度注意:加入了startup和shutdown=1時,mysql的啟動過程會比較慢,如果你上次的dump出的buffer_pool里的東西有50多g那么mysql啟動時的加載過程會變得比較慢。這個值很多人使用默認的0(不開啟),它的影響就是你在mysql重啟后,一開始你的系統(tǒng)讀寫性能不如在你系統(tǒng)運行了2-4小時(視db讀寫而定)反而它的讀寫性能變好了。不設使用默認值(0)。
如果不配的后果:
不配的話系統(tǒng)默認為0
配置實例:
innodb_buffer_pool_load_at_startup = 0
26)innodb_buffer_pool_dump_at_shutdown
同上面的startup參數(shù)以及解說
27)innodb_lru_scan_depth
推薦設置:
2000
作用:
innodb_io_capactiy 在sas 15000轉的下配置800就可以了,在ssd下面配置2000以上。
可使用默認配置。即不設。
如果不配的后果:
默認為200,db吞吐量上不去。
配置實例:
innodb_lru_scan_depth = 2000
28)innodb_lock_wait_timeout
推薦設置:
60
作用:
我們一般會碰到,mysql innodb_lock_wait_timeout這個錯,這個錯是慢sql導致,它代表的是慢sql的事務鎖超過了mysql鎖超時的設置了。默認這個值為:50s,這個值是可以動態(tài)改變的,我不建議去改這個值,因為一個sql能達50s這得多夸張?
動態(tài)改變命令如下:
SHOW GLOBAL VARIABLES LIKE 'innodb_lock_wait_timeout';
SET GLOBAL innodb_lock_wait_timeout=500;
SHOW GLOBAL VARIABLES LIKE 'innodb_lock_wait_timeout';
把它設成60s足夠了。
如果不配的后果:
默認為50s
配置實例:
innodb_lock_wait_timeout = 60
29)innodb_io_capacity_max
推薦設置:
8000
作用:
這個值很重要,它對讀無效,對寫很有決定意義。
它會直接決定mysql的tps(吞吐性能),這邊給出參考:sata/sas硬盤這個值在200. sas raid10: 2000,ssd硬盤:8000, fusion-io(閃存卡):25,000-50,000
本調(diào)優(yōu)基于的是ssd,此值設置為8000,筆者上一家公司互聯(lián)網(wǎng)金融是把一整個mysql扔到了閃存卡里的,因此設置的值為:50,000.
需要根據(jù)paas或者是ias的vm的硬盤性號來定
如果不配的后果:
默認為200,系統(tǒng)吞吐上不去。
配置實例:
innodb_io_capacity_max = 8000
30)innodb_io_capacity
它是io_capacity_max的一半,同樣,它對讀無效對寫有決定意義。
配置實例:
innodb_io_capacity_max = 4000
31)innodb_flush_method
推薦設置:
O_DIRECT
作用:
推薦使用O_DIRECT。讓我們一起來理解一下,它有3種模式:
1)fdatasync,上面最常提到的fsync(int fd)函數(shù),該函數(shù)作用是flush時將與fd文件描述符所指文件有關的buffer刷寫到磁盤,并且flush完元數(shù)據(jù)信息(比如修改日期、創(chuàng)建日期等)才算flush成功。它對磁盤的io讀寫會很頻繁
2)O_DIRECT則表示我們的write操作是從mysql innodb buffer里直接向磁盤上寫,它會充分利用緩存
3)_DIRECT模式的free內(nèi)存下降比較慢,因為它是據(jù)文件的寫入操作是直接從mysql innodb buffer到磁盤的,并不用通過操作系統(tǒng)的緩沖,而真正的完成也是在flush這步,日志還是要經(jīng)過OS緩沖,O_DIRECT在SQL吞吐能力上較好。
如果不配的后果:
它的默認值為fdatasync。
配置實例:
innodb_flush_method = O_DIRECT
32)innodb_file_format
推薦設置:
Barracuda
作用:
推薦使用Barracuda模式
它是啟用表壓縮用的,如:
CREATE TABLE `test_1` (
`x` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8;
建完后可以通過:show table status like 'test_1';來查看是否已經(jīng)啟用了表壓縮了。
innodb_file_format有這么幾種模式:
Antelope-羚羊模式,支持Redundant(冗余)、Compact(緊湊)模式
Barracuda-梭子魚,是InnoDB Plugin支持的文件格式,在原來的基礎上新增了兩種數(shù)據(jù)表格式的支持:Dynamic 和 Compressed
因此我推薦使用:Barracude模式,因為它可以兼容其它數(shù)據(jù)模式。
它也可以在運行時動態(tài)改變:SET GLOBAL innodb_file_format_max = barracuda;
如果不配的后果:
它默認使用的是叫“聯(lián)合模式”,即不是棱子魚也不是羚羊。
配置實例:
innodb_file_format = Barracuda
33)innodb_file_format_max
這個參數(shù)必須和innodb_file_format參數(shù)一致,一定記住,要不然不生效。
34)innodb_log_group_home_dir = /redolog/
這個就不用解釋了,太傻瓜了。這種路徑的都可由運維決定,記得掛在大磁盤下。
35)innodb_undo_directory = /undolog/
這個就不用解釋了,太傻瓜了。這種路徑的都可由運維決定,記得掛在大磁盤下。
36)innodb_undo_logs = 128
推薦設置:
128
作用:
指定回滾段的個數(shù)(早期版本該參數(shù)名字是innodb_rollback_segments),默認128個。每個回滾段可同時支持1024個在線事務。這些回滾段會平均分布到各個undo表空間中。該變量可以動態(tài)調(diào)整,但是物理上的回滾段不會減少,只是會控制用到的回滾段的個數(shù)?,F(xiàn)在SSD非常普及。innodb_undo_logs可以默認為128不變。
如果不配的后果:
默認就是128
配置實例:
innodb_undo_logs = 128
37)innodb_undo_tablespaces
推薦設置:
3
作用:
推薦:3,默認為3
定單獨存放的undo表空間個數(shù),例如如果設置為3,則undo表空間為undo001、undo002、undo003,每個文件初始大小默認為10M。該參數(shù)我們推薦設置為大于等于3,更多的碎片文件會影響磁盤的io性能,而不夠碎片同樣影響mysql的吞吐率,在ssd上一般最佳的配置在3.如果只有1個undo表空間,那么整個系統(tǒng)在此過程中將處于不可用狀態(tài)。為了盡可能降低truncate對系統(tǒng)的影響,建議將該參數(shù)最少設置為3;
如果不配的后果:
默認為:3
配置實例:
innodb_undo_tablespaces = 3
38)innodb_flush_neighbors
推薦設置:
推薦為:0
作用:
這個參數(shù)很要緊,目前在ssd盛行的情況下我們都把它設為0(不開啟),如果你設置成了1即開啟(默認狀態(tài))InnoDB就會刷新一個extent中的所有頁面,因為SSD在隨機IO上沒有額外負載,所以不需要啟用該特性,開啟了反而多此一句。下面給出一段mysql5.7源碼編譯前程序員看的readme里的一句話:
This new default changes MySQL to cater for SSDs and fast storage devices by default. We expect that for the majority of users, this will result in a small performance gain. Users who are using slower hard drives may see a performance loss, and are encouraged to revert to the previous defaults by setting innodb_flush_neighbors=1.
如果不配的后果:
它的默認是1,不是0.這個參數(shù)對機性硬盤來說很有效,可以減少隨機io,增加性能。如果是ssd類磁盤,建議設置為0,可以更快的刷新臟頁。如果你把它設為1同時又是ssd那就顯得沒必要了。這邊普及一下小知識,如果你裝過8.0,你可以去看一下,8.0已經(jīng)把這個默認值設為0了。
配置實例:
innodb_flush_neighbors = 0
39)innodb_log_file_size
推薦設置:
第1步:show engine innodb status;
得到:
Log sequence number 2944118284
Log flushed up to 2944118283
Last checkpoint at 2724318261
第2步:設innodb_log_file_size$=log Log sequence number-last checkpoint at=select (2944118284-2724318261)/1024/1024;=209M
第3步:設真正的innodb_log_file_size<=(innodb_log_files_in_group*innodb_log_file_size)*0.75,innodb_log_files_in_group為2(默認),得:
第4步:select 209/(2*0.75);=139.33即:139m,此時可把這個值設為140M
作用:
這個值的默認為5M,是遠遠不夠的,在安裝完mysql時需要盡快的修改這個值。
如果對 Innodb 數(shù)據(jù)表有大量的寫入操作,那么選擇合適的 innodb_log_file_size 值對提升MySQL性能很重要。然而設置太大了,就會增加恢復的時間,因此在MySQL崩潰或者突然斷電等情況會令MySQL服務器花很長時間來恢復。
而這個值是沒有一個絕對的概念的,MySQL的InnoDB 存儲引擎使用一個指定大小的Redo log空間(一個環(huán)形的數(shù)據(jù)結構)。Redo log的空間通過innodb_log_file_size和innodb_log_files_in_group(默認2)參數(shù)來調(diào)節(jié)。將這倆參數(shù)相乘即可得到總的可用Redo log 空間。盡管技術上并不關心你是通過innodb_log_file_size還是innodb_log_files_in_group來調(diào)整Redo log空間,不過多數(shù)情況下還是通過innodb_log_file_size 來調(diào)節(jié)。為InnoDB引擎設置合適的Redo log空間對于寫敏感的工作負載來說是非常重要的。然而,這項工作是要做出權衡的。你配置的Redo空間越大,InnoDB就能更好的優(yōu)化寫操作;然而,增大Redo空間也意味著更長的恢復時間當出現(xiàn)崩潰或掉電等意外時。我們是通過“測試”得到,怎么測試下面給出方法論:一般情況下我們可以按照每1GB的Redo log的恢復時間大約在5分鐘左右來估算。如果恢復時間對于你的使用環(huán)境來說很重要,我建議你做一些模擬測試,在正常工作負載下(預熱完畢后)模擬系統(tǒng)崩潰,來評估更準確的恢復時間。你可以安裝 Percona Monitoring and Management,在該pmm的percona monitoring and management圖表中,主要看:
1)Uncheckpointed Bytes ,如果它已經(jīng)非常接近 Max Checkpoint Age,那么你幾乎可以確定當前的 innodb_log_file_size 值因為太小已經(jīng)某種程度上限制了系統(tǒng)性能。增加該值可以較為顯著的提升系統(tǒng)性能。
2)Uncheckpointed Bytes 遠小于 Max Checkpoint Age,這種情況下再增加 innodb_log_file_size 就不會有明顯性能提升。
在調(diào)整完log_file_size后我們再到pmm中去看:Redo Log空間指標,比如說我們看到了1小時內(nèi)有60g數(shù)據(jù)被寫入日志文件,差不多就是每10分鐘會有10g數(shù)據(jù)在進行“寫日志“,我們需要牢牢記得,這個”寫日日土已“的時間拖得越久、出現(xiàn)的頻次越少就越有助于mysql的innodb的性能。因此這個值沒有絕對推薦。如果你沒有pmm,那么我們來人肉算,在上面我已經(jīng)給出了人肉算的詳細例子!
如果不配的后果:
默認是5M,這是肯定不夠的。
配置實例:
innodb_log_file_size = 140M
40)innodb_log_buffer_size
推薦設置:
16777216
作用:
對于較小的innodb_buffer_pool_size,我們會把它設成和innodb_buffer_pool_size一樣。
而當超過4gb的innodb_buffer_pool_size時,我們的建議是把它切的夠碎,這是mysql5.7里新帶的特性,它的默認在8m,但是對于大量有事務操作的mysql我們推薦在寫操作庫上設置:16m
此參數(shù)確定些日志文件所用的內(nèi)存大小,以M為單位。緩沖區(qū)更大能提高性能,但意外的故障將會丟失數(shù)據(jù).官方的方檔建議設置為1-8M之間!
如果不配的后果:
默認是8M
配置實例:
innodb_log_buffer_size = 16777216
41)innodb_purge_threads
推薦設置:
0
作用:
這個參數(shù)輕易不用的,我推薦它設為:0,為什么呢?這個參數(shù)是和innodb_force_recovery關聯(lián)起來的,只有當數(shù)據(jù)庫崩潰后重啟時才會臨時去設的。它的使用場景如下:
mysql斷電,重啟后無效,起不來。所以我們根據(jù)innodb_force_recovery的參數(shù):
1. (SRV_FORCE_IGNORE_CORRUPT):忽略檢查到的corrupt頁。
2. (SRV_FORCE_NO_BACKGROUND):阻止主線程的運行,如主線程需要執(zhí)行full purge操作,會導致crash。
3. (SRV_FORCE_NO_TRX_UNDO):不執(zhí)行事務回滾操作。
4. (SRV_FORCE_NO_IBUF_MERGE):不執(zhí)行插入緩沖的合并操作。
5. (SRV_FORCE_NO_UNDO_LOG_SCAN):不查看重做日志,InnoDB存儲引擎會將未提交的事務視為已提交。
6. (SRV_FORCE_NO_LOG_REDO):不執(zhí)行前滾的操作。
我們在my.cnf中如下設置:
innodb_force_recovery = 6
innodb_purge_threads = 0
記住,一旦當innodb_force_recovery>2時,要把innodb_purge_threads設成0.
如果不配的后果:
默認不要去設,可以不配,出現(xiàn)了問題在recover需要時再去改。
配置實例:
innodb_purge_threads = 0
42)innodb_large_prefix
推薦設置:
1
作用:
如果你的客戶端和服務端的字符集設成了utf8mb4,那么我們需要把這個開關開啟,為什么呢?mysql在5.6之前一直都是單列索引限制767,起因是256×3-1。這個3是字符最大占用空間(utf8)。但是在5.6以后,開始支持4個字節(jié)的uutf8。255×4>767, 于是增加了這個參數(shù)。這個參數(shù)默認值是OFF。當改為ON時,允許列索引最大達到3072.
在mysql5.6中這個開關叫on, off。而在5.7中叫0和1,由于我們前面設置了utf8mb4,因此這邊我們必須把這個參數(shù)開啟。
如果不配的后果:
不配會有問題,特別是索引會無效、或者不是走最優(yōu)計劃,如果你的字符集是utf8mb4,那么這個值必開啟。
配置實例:
innodb_large_prefix = 1
43)innodb_thread_concurrency
推薦設置:
裝mysql的服務器的cpu的核數(shù)
作用:
如:64核cpu,那么推薦:64(<=cpu核數(shù))
如果一個工作負載中,并發(fā)用戶線程的數(shù)量小于等于64,建議設置innodb_thread_concurrency=0;而事實上我們的系統(tǒng)是處于大并發(fā)大事務的情況下的,怎么來算這個值?建議是先設置為128,然后我們不斷的降這個值,直到發(fā)現(xiàn)能夠提供最佳性能的線程數(shù)。為了安全起間我們會把它設成和cpu一樣大小。
如果不配的后果:
默認在64位下會是8
配置實例:
innodb_thread_concurrency = 64
44)innodb_print_all_deadlocks
推薦設置:
1
作用:
推薦:1
當mysql 數(shù)據(jù)庫發(fā)生死鎖時, innodb status 里面會記錄最后一次死鎖的相關信息,但mysql 錯誤日志里面不會記錄死鎖相關信息,要想記錄,啟動 innodb_print_all_deadlocks 參數(shù) 。
如果不配的后果:
不會記錄該信息。
配置實例:
innodb_print_all_deadlocks = 1
45)innodb_strict_mode
推薦設置:
1
作用:
必須開啟,沒得選擇,1,為什么?
從MySQL5.5.X版本開始,你可以開啟InnoDB嚴格檢查模式,尤其采用了頁數(shù)據(jù)壓縮功能后,最好是開啟該功能。開啟此功能后,當創(chuàng)建表(CREATE TABLE)、更改表(ALTER TABLE)和創(chuàng)建索引(CREATE INDEX)語句時,如果寫法有錯誤,不會有警告信息,而是直接拋出錯誤,這樣就可直接將問題扼殺在搖籃里。
如果不配的后果:
如果不配碰到開發(fā)或者非專業(yè)的dba會把舊ddl語句生效在5.7內(nèi),另外一個問題就是ddl語句出錯時報錯不明顯,這會影響到“主從復制”,至于dll為什么會影響到主從復制,我們后面會在“slave_skip_errors = ddl_exist_errors”中詳細解說。
配置實例:
innodb_strict_mode = 1
46)log_error
error log所在位置,這個不用多講,可以和mysql log放在同一路徑下,文件名能夠和其它log區(qū)分開來。
47)slow_query_log
建議開啟
48)slow_query_log_file
慢sql所在位置,這個不用多講,可以和mysql log放在同一路徑下,文件名能夠和其它log區(qū)分開來。
49)log_queries_not_using_indexes=1
強烈建議開啟成1.
50)log_slow_admin_statements = 1
強烈建議開啟成1.
51)log_slow_slave_statements = 1
強烈建議開啟成1.
52)log_throttle_queries_not_using_indexes
推薦設置:
在一開始上線后的初期我們會開成30~50條。隨著性能逐漸優(yōu)化我們會把這個數(shù)量開成10.
作用:
上線前一段時間會不太穩(wěn)定,我們發(fā)生過近幾十條sql沒有走index
如果不配的后果:
不配不開啟,建議開啟。
配置實例:
log_throttle_queries_not_using_indexes = 50
53)expire_logs_days
推薦設置:
30
作用:
這個值不能太大,因為你不是土豪,不能讓binlog無限占用你的磁盤空間,記得這個值一旦設小,你需要做好binlog備份策略,30這個值就是30天,前提是你的binlog的備份做的有效且不占用mysql的磁盤空間。
如果不配的后果:
默認是0,即永不過期。
配置實例:
expire_logs_days = 30
54)long_query_time
推薦設置:
10
作用:
默認為10秒種,即一切>=10s的sql都會被記錄。我建議在開始剛上線期設成10(用默認值),越著慢sql調(diào)優(yōu)越來越好,可以把這個值設成1.因為秒數(shù)越低,記錄的sql越多,記錄越多,也會造成mysql過慢。另外不能完全依賴于mysql的慢sql log,而是應該布署druid sql實時查看器或者是apm或者是專業(yè)的慢sql實時查詢器。
如果不配的后果:
默認為10
配置實例:
long_query_time = 10
55)min_examined_row_limit
推薦設置:
100
作用:
這個值配合著慢查詢sql記錄用,指定為少于該值的行的查詢就算慢sql不被記錄成”慢sql日志“。
如果不配的后果:
不開啟的話以慢sql的long_query_time為優(yōu)先規(guī)則。
配置實例:
min_examined_row_limit = 100
56)master_info_repository
推薦設置:
TABLE
作用:
主從復制時用,推薦TABLE.
從機保存主節(jié)點信息方式,設成file時 會生成master.info 和 relay-log.info2個文件,設成table,信息就會存在mysql.master_slave_info表中。不管是設置的哪種值,都不要移動或者編輯相關的文件和表。
如果不配的后果:
不配的話默認存成file格式。
配置實例:
master_info_repository = TABLE
57)relay_log_info_repository
推薦設置:
TABLE
作用:
主從復制時用,推薦TABLE.
這個參數(shù)和上面的master_info_repository必須保持一致,要不然mysql實例啟不起來。
不過需要注意的是,這幾個table默認用的是myIsAM引擎,要開啟成TABLE模式的話一定記得把這兩個表的引擎改成innodb
altertableslave_master_infoengine=innodb;altertableslave_relay_log_infoengine=innodb;altertableslave_worker_infoengine=innodb;
如果不配的后果:
這個參數(shù)和上面的master_info_repository必須保持一致,要不然mysql實例啟不起來
配置實例:
relay_log_info_repository = TABLE
58)log_bin = bin.log
主從復制時用,主從復制下的bin.log日志所在文件夾。
59)sync_binlog
推薦設置:
1
作用:
主從復制時用,這個值是要看業(yè)務的,它可以有0,1,非零共3種設置方式。
1)0-代表mysql不控制寫binlog的時間,由file system自由去控制,此時的mysql的并發(fā)性達到最好,但是一旦系統(tǒng)崩潰你會丟失很多還會寫入binlog的數(shù)據(jù)(比如說你正在刪數(shù)據(jù)和更新數(shù)據(jù))
2)1-最安全,你最多丟掉一個事務或者是一條語句,但是此時它的性能很差,此參數(shù)設為0或者是1之間的性能能差4~5倍。
3)如果你用的是萬兆光纖高速磁盤像或者是ssd同時data和binlog都放在一個目錄下的同時你要為了安全可以開啟成1.
如果不配的后果:
默認為0
配置實例:
sync_binlog = 1
60)gtid_mode
推薦設置:
on
作用:
主從復制時用,推薦開啟成on,它的用處就是允許你在從庫上進行”備份“,從庫上在進行備份時它能夠獲取主庫的binlog位點。
該參數(shù)也可以動態(tài)在線設定。如果你要在線運行時設定,在my.cnf文件中必須把它設成on。在開啟該參數(shù)時,log-bin和log-slave-updates也必須開啟,否則MySQL Server拒絕啟動,當開啟GTID模式時,集群中的全部MySQL Server必須同時配置gtid_mod = ON,否則無法同步。
如果不配的后果:
默認為off
配置實例:
gtid_mode = on
61)enforce_gtid_consistency
推薦設置:
1
作用:
主從復制時用,見gtid_mode,這是牽連參數(shù),隨著gtid_mode的開啟一起開啟。
如果不配的后果:
必須跟著gtid_mode一起開啟,要不然mysql實例起不來。
配置實例:
enforce_gtid_consistency = 1
62)log_slave_updates
推薦設置:
它只要標注在my.cnf里就代表起作用了。
作用:
主從復制時用,見gtid_mode,這是牽連參數(shù),隨著gtid_mode的開啟一起開啟。它只要標注在這就可以了,代表開啟,否則也就不要有這一行了。
如果不配的后果:
它是牽連參數(shù),隨著gtid_mode的開啟一起開啟。
配置實例:
log_slave_updates
63)binlog_format
推薦設置:
row
作用:
主從復制時用,mysql5.7有3種bin log模式:
1. STATEMENT:歷史悠久,技術成熟,binlog文件較小,binlog中包含了所有數(shù)據(jù)庫更改信息,可以據(jù)此來審核數(shù)據(jù)庫的安全等情況。binlog可以用于實時的還原,而不僅僅用于復制主從版本可以不一樣,從服務器版本可以比主服務器版本高。缺點是:不是所有的UPDATE語句都能被復制,尤其是包含不確定操作的時候。調(diào)用具有不確定因素的 UDF 時復制也可能出問題,使用以下函數(shù)的語句也無法被復制:
* LOAD_FILE()
* UUID()
* USER()
* FOUND_ROWS()
* SYSDATE() (除非啟動時啟用了 --sysdate-is-now 選項)
2.同時,INSERT ... SELECT 會產(chǎn)生比 ROW 更多的行級鎖,復制需要進行全表掃描(WHERE 語句中沒有使用到索引)的 UPDATE 時,需要比 RBR 請求更多的行級鎖
3.對于有 AUTO_INCREMENT 字段的 InnoDB表而言,INSERT 語句會阻塞其他 INSERT 語句,對于一些復雜的語句,在從服務器上的耗資源情況會更嚴重,而 RBR 模式下,只會對那個發(fā)生變化的記錄產(chǎn)生影響,存儲函數(shù)(不是存儲過程)在被調(diào)用的同時也會執(zhí)行一次 NOW() 函數(shù),這個可以說是壞事也可能是好事,確定了的 UDF 也需要在從服務器上執(zhí)行,數(shù)據(jù)表必須幾乎和主服務器保持一致才行,否則可能會導致復制出錯,執(zhí)行復雜語句如果出錯的話,會消耗更多資源。
2. ROW:任何情況都可以被復制,這對復制來說是最安全可靠的,和其他大多數(shù)數(shù)據(jù)庫系統(tǒng)的復制技術一樣。多數(shù)情況下,從服務器上的表如果有主鍵的話,復制就會快了很多。復制以下幾種語句時的行鎖更少:
* INSERT ... SELECT
* 包含 AUTO_INCREMENT 字段的 INSERT
* 沒有附帶條件或者并沒有修改很多記錄的 UPDATE 或 DELETE 語句
執(zhí)行 INSERT,UPDATE,DELETE 語句時鎖更少,從服務器上采用多線程來執(zhí)行復制成為可能,它的缺點是:inlog 大了很多,復雜的回滾時 binlog 中會包含大量的數(shù)據(jù),主服務器上執(zhí)行 UPDATE 語句時,所有發(fā)生變化的記錄都會寫到 binlog 中,而 SBR 只會寫一次,這會導致頻繁發(fā)生 binlog 的并發(fā)寫問題,UDF 產(chǎn)生的大 BLOB 值會導致復制變慢,無法從 binlog 中看到都復制了寫什么語句。
從安全和穩(wěn)定性的縮合考慮上來說我們選擇ROW模式。
3. 混合式-不推薦
如果不配的后果:
5.7.6之前默認為STATEMENT模式。MySQL 5.7.7之后默認為ROW模式
配置實例:
binlog_format = row
64)relay_log
主從復制用,定義relay_log的位置和名稱,如果值為空,則默認位置在數(shù)據(jù)文件的目錄(datadir),文件名為host_name-relay-bin.nnnnnn(By default, relay log file names have the form host_name-relay-bin.nnnnnn in the data directory)
65)relay_log_recovery
推薦設置:
1
作用:
主從復制用,推薦值為1,建議打開。
當slave從庫宕機后,假如relay-log損壞了,導致一部分中繼日志沒有處理,則自動放棄所有未執(zhí)行的relay-log,并且重新從master上獲取日志,這樣就保證了relay-log的完整性。默認情況下該功能是關閉的,將relay_log_recovery的值設置為 1時,可在slave從庫上開啟該功能,建議開啟。
如果不配的后果:
默認情況下是關閉的。
配置實例:
relay_log_recovery = 1
66)slave_skip_errors
推薦設置:
ddl_exist_errors
作用:
主從復制用,推薦值:ddl_exist_errors。理論上我們不應該設置這個值的。即它在my.cnf文件中應該是消失的或者是這樣的表示的:
#slave_skip_errors = ddl_exist_errors
但是有時我們的一些表(特別是不熟悉mysql的一些開發(fā))真的是用的是mysql5.6舊版的建表語句,這個問題在平時單機模式下很難發(fā)現(xiàn),一旦主從結構一上后,在5.7上真的是有一定機率(有10%-20%的機率)碰到ddl語句是舊版mysql而運行在mysql5.7上,這時在主從復制時會拋一個無法主從復制的錯,那么這時我們需要抓數(shù)據(jù),表已經(jīng)建好了,這個影響不大、微乎其微,因此我們可以把它設成”忽略“。這個是本人的吐血經(jīng)驗,為什么要提這個梗。。。你們懂的。
如果不配的后果:
如果因為建表語句和mysql5.7有沖突時在單實例模式下mysql運行時不會發(fā)現(xiàn),在主從復制時如果沒有設跳過值,一旦發(fā)生,會影響主從復制,表現(xiàn)就是:主從復制失敗。
配置實例:
slave_skip_errors = ddl_exist_errors
67)innodb_buffer_pool_dump_pct
推薦設置:
25~40
作用:
錦上添花的值,非必要,這邊給出一些best practice:
通常來說我們會設成25%。對于大并發(fā)前提下我們會使用40這個值,這個值越大,mysql啟動時間越長。它是你的innodb_buffer_pool_size的百分比!
MySQL默認在InnoDB緩沖池(而不是整個緩沖池)中僅保留最頻繁訪問頁的25%。請注意,這個變量是基于內(nèi)存中的實際數(shù)據(jù)量,而不是緩沖池的大小。例如,如果有100GB的緩沖池,但只有10GB的數(shù)據(jù),默認只有10GB的25%(即2.5GB)數(shù)據(jù)保存在內(nèi)存中。
在多數(shù)使用場景下,合理的選擇是:保留最有用的數(shù)據(jù)頁,比加載所有的頁(很多頁可能在后續(xù)的工作中并沒有訪問到)在緩沖池中要更快。你可以更改innodb_buffer_pool_dump_pct變量的值。
如果不配的后果:
不配的話不生效。
配置實例:
innodb_buffer_pool_dump_pct=25
68)innodb_page_cleaners=8
這值一般會在主從延遲的情況下會去設,它的值最好是=innodb_buffer_pool_instance的值,它就是cpu的核數(shù)。
69)innodb_undo_log_truncate
推薦設置:
1
作用:
建議開啟,設為1
innodb_undo_log_truncate參數(shù)設置為1,即開啟在線回收(收縮)undo log日志文件,支持動態(tài)設置。
如果不配的后果:
不配的話是不生效的。
配置實例:
innodb_undo_log_truncate=1
70)innodb_max_undo_log_size
推薦設置:
推薦在默認值的2倍(默認為1GB)
作用:
推薦在默認值的2倍(默認為1GB),一般我們不會輕易去設它。
這個值和innodb_undo_tablespaces、innodb_undo_logs以及innodb_purge_rseg_truncate_frequency有關,這4個值是互相有牽連的。
1)innodb_undo_tablespaces必須為>=3
2)innodb_undo_logs必須開啟
3)innodb_purge_rseg_truncate_frequence必須開啟
如果不配的后果:
系統(tǒng)按照1GB來計算。
配置實例:
innodb_max_undo_log_size=2G
71)innodb_purge_rseg_truncate_frequency
推薦設置:
128
作用:
默認值在128,這個值不太會去碰??刂苹厥誹ndo log的頻率。 指定purge操作被喚起多少次之后才釋放rollback segments。當undo表空間里面的rollback segments被釋放時,undo表空間才會被truncate。由此可見,該參數(shù)越小,undo表空間被嘗試truncate的頻率越高。
如果不配的后果:
系統(tǒng)默認按照:128去設定。
配置實例:
innodb_purge_rseg_truncate_frequency=128
72)binlog_gtid_simple_recovery
推薦設置:
建議開啟
作用:
前提是你的mysql必須>5.7.6,否則要設為關閉。
這個參數(shù)控制了當mysql啟動或重啟時,mysql在搜尋GTIDs時是如何迭代使用binlog文件的。
這個選項設置為真,會提升mysql執(zhí)行恢復的性能。因為這樣mysql-server啟動和binlog日志清理更快。該參數(shù)為真時,mysql-server只需打開最老的和最新的這2個binlog文件。
如果不配的后果:
默認為0
配置實例:
binlog_gtid_simple_recovery=1
73)log_timestamps
推薦設置:
system
作用:
推薦使用:system
這個參數(shù)主要是控制錯誤日志、慢查詢?nèi)罩镜热罩局械娘@示時間。但它不會影響查詢?nèi)罩竞吐罩緦懙奖?(mysql.general_log, mysql.slow_log) 中的顯示時間,此參數(shù)是全局的,可以動態(tài)修改。
如果不配的后果:
默認值為:UTC
配置實例:
log_timestamps=system
74)transaction_write_set_extraction
推薦設置:
這個值不需要去設,因為你用的不是mysql8.0,在5.7.6版以后這個制不是很成熟,如果要開啟一般會使用:XXHASH64.
作用:
這個值是基于group(并行)復制用的,推薦值為:XXHASH64,如果沒有開啟基于group(并行)的復制千萬不要去設這個參數(shù),設都不用去設,保持默認就可以了。
如果不配的后果:
默認為off狀態(tài),即不生效。
配置實例:
transaction_write_set_extraction=OFFtransaction_write_set_extraction= XXHASH64transaction_write_set_extraction= MURMUR32
75)show_compatibility_56
推薦設置:
on
作用:
推薦打開。這個參數(shù)是兼容mysql5.6版的INFORMATION_SCHEMA.GLOBAL_STATUS相關功能的,它有利于從5.6到5.7的過渡時非mysql專職dba但是懂mysql的運維用的。
如果不配的后果:
默認是off。相當于嚴格模式。
配置實例:
show_compatibility_56=on
至此,本文完,一共介紹了mysql5.7性能提升的75種方法和詳細解釋,希望對大家有所幫助!