案例描述:mysql
一個普通的事務提交,在應用裏面會提示commit超時,失敗。sql
1、理論知識數據庫
一、關於commit原理,事務提交過程服務器
一、尋找修改的數據頁:網絡
一、若是該數據頁在內存中,則直接是內存讀;異步
二、若是該數據頁內存中沒有,物理讀,就從磁盤調入內存;ide
二、磁盤中的undo頁調入內存;性能
三、先將原來的數據存入undo,而後修改數據(數據頁成髒頁);優化
四、修改數據的信息生成redo數據存入log_buffer(內存buffer_pool的一個空間,默認16M)中;spa
mysql> show variables like '%log_buffer%';+------------------------+----------+| Variable_name | Value |+------------------------+----------+| innodb_log_buffer_size | 16777216 |+------------------------+----------+1 row in set (0.01 sec)
五、log_buffer經過log線程(後臺線程,很是勤快),持續不斷的將redo信息寫入disk的innodb_log_file中;
mysql> show variables like 'innodb_log_file%';+---------------------------+----------+| Variable_name | Value |+---------------------------+----------+| innodb_log_file_size | 50331648 || innodb_log_files_in_group | 2 |+---------------------------+----------+2 rows in set (0.01 sec)
六、事務提交,刻意觸發log線程,將剩餘的log_buffer中的redo數據信息寫入磁盤中,數據量已剩很少,寫完提交成功。
注意:
一、修改記錄前,必定要先寫日誌;
「日誌先行」,這是數據庫最基本的原則。
二、事務提交過程當中,必定要保證日誌先落盤,才能算事務提交完成。
三、意外掉電,內存髒頁丟失,可是磁盤的innodb_log_file中存放了redo日誌信息,待重啓服務器,MySQL經過讀取磁盤的log_files數據,自動將數據的修改從新跑一邊。
Q:爲何mysql commit速度老是很快,儘管事務修改的數據量可能很大?
A:
由於事務提交,並非對磁盤數據進行修改,而是將修改數據的redo信息經過後臺log線程寫入磁盤的redo logfile中,完成mysql commit,不管事務修改的數據量有多大,這個過程速度是很快的。
而內存中的髒塊,也就是修改後的數據頁,正常狀況下是由後臺相關write線程週期性的將髒頁數據刷入磁盤中,保證innodb buffer pool有足夠的乾淨塊、可用塊。
二、關於rollback原理,回滾過程
一、MySQL讀取內存中undo頁信息
二、經過undo信息找到髒頁,反着對數據進行修改
三、do、undo的時間相同,且都會產成redo信息
四、事務提交
MySQL回滾處理機制:
若是線程中斷,事務沒有提交,undo會將記錄此信息,待另外一會話進程連上,查看該塊數據信息,MySQL自動回滾進行數據頁修改,而後被讀取。也就是說爲了不繫統由於rollback被hang住,經過直接殺死進程的方式,中斷事務,等待後來者要讀取該數據信息時進行回滾,再返回結果。
Q:rollback爲何有時候很慢,rollback的風險和風險避免方式?
A:
rollback的時間取決於回滾前事務修改數據的時間,處理量大回滾時間長,處理量小回滾時間短。
一、rollback風險:容易致使系統被hang住;
二、風險避免方式:直接殺死會話進程或是mysql進程。
三、存儲寫入性能分析
Q:mysql commit,存儲爲何寫速度可以保持在0ms,極少出現1ms狀況?
A:
對於存儲來講,寫性能至關高:假設存儲cache總有空閒空間的狀況下,事務提交,將log buffer中剩餘的不多的redo數據寫入存儲cache,即爲完成mysql commit,這個過程是至關快的(可以保持在0ms,極少出現1ms狀況),後續redo數據由cache寫入磁盤的過程是後臺進行。
四、存儲級別的災備(同城災備)
一、災備同步過程:commit
一、redo、binlog寫入本地存儲cache;
二、經過網絡同步binlog寫入遠端同步的服務器的存儲cache中;
三、響應本地數據庫;
四、事務提交成功;
二、風險:
網絡出現問題(信號斷續,纜線斷了),致使寫hang住,commit超時失敗。
三、解決:
經過超時設置,網絡中斷超過限制,自動將同步改成災備異步,儘量少的影響業務commit超時失敗。
2、分析與處理
存儲寫性能比較差,不少時段會達到5ms,甚至於10ms以上
備註:災備同步已經中止的狀況下。
一、存儲中BBU問題,出現監控BBU的bug;
解決:重啓BBU,不行就更新BBU。
二、cache被佔滿
一、海量數據寫入,commit數據佔滿cache;
二、硬盤I/O異常,異常SQL致使的海量物理讀;
解決:索引優化。
三、存儲性能差
解決:找老闆掏錢,更換優質設備。