自建Mysql.5.7.17插入速度優化

前言

最近開發同事表示這dev環境的mysql插入怎麼這麼慢(表字段大概有242個),作爲運維,那肯定是不能忍的。於是寫了個重複插入,開始測試mysql參數。直到看到了這篇文章。於是乎,借輪子用用。於是對此進行排版。

#於是我自己寫了個insert腳本,插入自定義數量的記錄,進行測試。
#!/bin/bash
sum=0
switch=true
user=test
pwd=test
start=$(date +%s )

Get_date() {
datetime=$(date +%s )
end=$datetime
}

Insert() {
        sql=`mysql -u$user-$pwd  << EOF
        source /data/test/insert.sql;
        exit
        EOF`
        echo $sql
}

while $switch ;do
sum=$((sum+1))
Insert
[ $sum = 1000 ] &&  $swtich=false
done
Get_date
echo "Insert counts $sum times,expend $(($end-$start)) sec"
#Mysql默認innodb_flush_log_at_trx_commit=1
#原本插入1000條記錄,花費138秒

#Counts 1000 times,expend 138 sec
#my.cnf中增加下面參數後重啓mysql
innodb_flush_log_at_trx_commit=2

#現在插入1000條記錄,花費了9秒鐘
#Counts 1000 times,expend 9 sec
#得出結論,插入速度得到大幅度提升。

下面內容是對innodb_flush_log_at_trx_commit的參數的詳解。

參數意義

innodb_flush_log_at_trx_commit和sync_binlog 兩個參數是控制MySQL 磁盤寫入策略以及數據安全性的關鍵參數。本文從參數含義,性能,安全角度闡述兩個參數爲不同的值時對db 性能,數據的影響.

innodb_flush_log_at_trx_commit

如果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(刷到磁盤)操作。
注意:
	由於進程調度策略問題,這個“每秒執行一次 flush(刷到磁盤)操作”並不是保證100%的“每秒”。

sync_binlog

sync_binlog 的默認值是0,像操作系統刷其他文件的機制一樣,MySQL不會同步到磁盤中去而是依賴操作系統來刷新binary log。
當sync_binlog =N (N>0) ,MySQL 在每寫 N次 二進制日誌binary log時,會使用fdatasync()函數將它的寫二進制日誌binary log同步到磁盤中去。
注意:
	如果啓用了autocommit,那麼每一個語句statement就會有一次寫操作;否則每個事務對應一個寫操作。

根據上述描述,原博做了一張圖,可以方便大家查看。
在這裏插入圖片描述

性能

兩個參數在不同值時對db的純寫入的影響表現如下:
![在這裏插入圖片描述](https://img-blog.csdnimg.cn/20200410094153493.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dheW5lX3ByaW1lcw==,size_16,color_FFFFFF,t_70)

測試場景1

innodb_flush_log_at_trx_commit=2 
sync_binlog=1000

測試場景2

innodb_flush_log_at_trx_commit=1 
sync_binlog=1000

測試場景3

innodb_flush_log_at_trx_commit=1 
sync_binlog=1

測試場景4

innodb_flush_log_at_trx_commit=1
sync_binlog=1000

測試場景5

innodb_flush_log_at_trx_commit=2 
sync_binlog=1000 
場景 TPS
場景1 41000
場景2 33000
場景3 26000
場景4 33000
由此可見,當兩個參數設置爲雙1的時候,寫入性能最差,sync_binlog=N (N>1 ) 	
innodb_flush_log_at_trx_commit=2 時,(在當前模式下)MySQL的寫操作才能達到最高性能。

安全

當innodb_flush_log_at_trx_commit和sync_binlog  都爲 1 時是最安全的,在mysqld 服務崩潰或者服務器主機crash的情況下,binary log 只有可能丟失最多一個語句或者一個事務。但是魚與熊掌不可兼得,雙11 會導致頻繁的io操作,因此該模式也是最慢的一種方式。
當innodb_flush_log_at_trx_commit設置爲0,mysqld進程的崩潰會導致上一秒鐘所有事務數據的丟失。
當innodb_flush_log_at_trx_commit設置爲2,只有在操作系統崩潰或者系統掉電的情況下,上一秒鐘所有事務數據纔可能丟失。

雙1適合數據安全性要求非常高,而且磁盤IO寫能力足夠支持業務,比如訂單,交易,充值,支付消費系統。雙1模式下,當磁盤IO無法滿足業務需求時 比如11.11 活動的壓力。推薦的做法是 innodb_flush_log_at_trx_commit=2 ,sync_binlog=N (N爲500 或1000) 且使用帶蓄電池後備電源的緩存cache,防止系統斷電異常。

小結

系統性能和數據安全是業務系統高可用穩定的必要因素。我們對系統的優化需要尋找一個平衡點,合適的纔是最好的,根據不同的業務場景需求,可以將兩個參數做組合調整,以便是db系統的性能達到最優化。

原博的參考文章

http://dev.mysql.com/doc/refman/5.1/en/innodb-parameters.html#sysvar_innodb_flush_log_at_trx_commit
http://dev.mysql.com/doc/refman/5.1/en/replication-options-binary-log.html#sysvar_sync_binlog
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章