關於MySQL的commit非規律性失敗案例的深入分析 關於MySQL的commit非規律性失敗案例的深入分析
關於MySQL的commit非規律性失敗案例的深入分析
案例描述:
一個普通的事務提交,在應用裡面會提示commit超時,失敗。
一、理論知識
1、關於commit原理,事務提交過程
1、尋找修改的資料頁:
1、如果該資料頁在記憶體中,則直接是記憶體讀;
2、如果該資料頁記憶體中沒有,物理讀,就從磁碟調入記憶體;
2、磁碟中的undo頁調入記憶體;
3、先將原來的資料存入undo,然後修改資料(資料頁成髒頁);
4、修改資料的資訊生成redo資料存入log_buffer(記憶體中的一個空間,預設16M)中;
mysql> show variables like '%log_buffer%'; +------------------------+----------+ | Variable_name | Value | +------------------------+----------+ | innodb_log_buffer_size | 16777216 | +------------------------+----------+ 1 row in set (0.01 sec)
5、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)
6、事務提交,刻意觸發log執行緒,將剩餘的log_buffer中的redo資料資訊寫入磁碟中,資料量已剩不多,寫完提交成功。
注意:
1、修改記錄前,一定要先寫日誌;
“日誌先行”,這是資料庫最基本的原則。
2、事務提交過程中,一定要保證日誌先落盤,才能算事務提交完成。
3、意外掉電,記憶體髒頁丟失,但是磁碟的innodb_log_file中存放了redo日誌資訊,待重啟伺服器,MySQL通過讀取磁碟的log_files資料,自動將資料的修改重新跑一邊。
Q:為什麼mysql commit速度總是很快,儘管事務修改的資料量可能很大?
A:
因為事務提交,並不是對磁碟資料進行修改,而是將修改資料的redo資訊通過後臺log執行緒寫入磁碟的redo logfile中,完成mysql commit,無論事務修改的資料量有多大,這個過程速度是很快的。
而記憶體中的髒塊,也就是修改後的資料頁,正常情況下是由後臺相關write執行緒週期性的將髒頁資料刷入磁碟中,保證innodb buffer pool有足夠的乾淨塊、可用塊。
2、關於rollback原理,回滾過程
1、MySQL讀取記憶體中undo頁資訊
2、通過undo資訊找到髒頁,反著對資料進行修改
3、do、undo的時間相同,且都會產成redo資訊
4、事務提交
MySQL回滾處理機制:
如果執行緒中斷,事務沒有提交,undo會將記錄此資訊,待另一會話程序連上,檢視該塊資料資訊,MySQL自動回滾進行資料頁修改,然後被讀取。也就是說為了避免系統因為rollback被hang住,通過直接殺死程序的方式,中斷事務,等待後來者要讀取該資料資訊時進行回滾,再返回結果。
Q:rollback為什麼有時候很慢,rollback的風險和風險避免方式?
A:
rollback的時間取決於回滾前事務修改資料的時間,處理量大回滾時間長,處理量小回滾時間短。
1、rollback風險:容易導致系統被hang住;
2、風險避免方式:直接殺死會話程序或是mysql程序。
3、儲存寫入效能分析
Q:mysql commit,儲存為什麼寫速度能夠保持在0ms,極少出現1ms情況?
A:
對於儲存來說,寫效能相當高:假設儲存cache總有空閒空間的情況下,事務提交,將log buffer中剩餘的很少的redo資料寫入儲存cache,即為完成mysql commit,這個過程是相當快的(能夠保持在0ms,極少出現1ms情況),後續redo資料由cache寫入磁碟的過程是後臺進行。
4、儲存級別的災備(同城災備)
1、災備同步過程:commit
1、redo、binlog寫入本地儲存cache;
2、通過網路同步binlog寫入遠端同步的伺服器的儲存cache中;
3、響應本地資料庫;
4、事務提交成功;
2、風險:
網路出現問題(訊號斷續,纜線斷了),導致寫hang住,commit超時失敗。
3、解決:
通過超時設定,網路中斷超過限制,自動將同步改為災備非同步,儘可能少的影響業務commit超時失敗。
二、分析與處理
儲存寫效能比較差,很多時段會達到5ms,甚至於10ms以上
備註:災備同步已經停止的情況下。
1、儲存中BBU問題,出現監控BBU的bug;
解決:重啟BBU,不行就更新BBU。
2、cache被佔滿
1、海量資料寫入,commit資料佔滿cache;
2、硬碟I/O異常,異常SQL導致的海量物理讀;
解決:索引優化。
3、儲存效能差
解決:找老闆掏錢,更換優質裝置。
@author:http://www.cnblogs.com/geaozhang/案例描述:
一個普通的事務提交,在應用裡面會提示commit超時,失敗。
一、理論知識
1、關於commit原理,事務提交過程
1、尋找修改的資料頁:
1、如果該資料頁在記憶體中,則直接是記憶體讀;
2、如果該資料頁記憶體中沒有,物理讀,就從磁碟調入記憶體;
2、磁碟中的undo頁調入記憶體;
3、先將原來的資料存入undo,然後修改資料(資料頁成髒頁);
4、修改資料的資訊生成redo資料存入log_buffer(記憶體中的一個空間,預設16M)中;
mysql> show variables like '%log_buffer%'; +------------------------+----------+ | Variable_name | Value | +------------------------+----------+ | innodb_log_buffer_size | 16777216 | +------------------------+----------+ 1 row in set (0.01 sec)
5、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)
6、事務提交,刻意觸發log執行緒,將剩餘的log_buffer中的redo資料資訊寫入磁碟中,資料量已剩不多,寫完提交成功。
注意:
1、修改記錄前,一定要先寫日誌;
“日誌先行”,這是資料庫最基本的原則。
2、事務提交過程中,一定要保證日誌先落盤,才能算事務提交完成。
3、意外掉電,記憶體髒頁丟失,但是磁碟的innodb_log_file中存放了redo日誌資訊,待重啟伺服器,MySQL通過讀取磁碟的log_files資料,自動將資料的修改重新跑一邊。
Q:為什麼mysql commit速度總是很快,儘管事務修改的資料量可能很大?
A:
因為事務提交,並不是對磁碟資料進行修改,而是將修改資料的redo資訊通過後臺log執行緒寫入磁碟的redo logfile中,完成mysql commit,無論事務修改的資料量有多大,這個過程速度是很快的。
而記憶體中的髒塊,也就是修改後的資料頁,正常情況下是由後臺相關write執行緒週期性的將髒頁資料刷入磁碟中,保證innodb buffer pool有足夠的乾淨塊、可用塊。
2、關於rollback原理,回滾過程
1、MySQL讀取記憶體中undo頁資訊
2、通過undo資訊找到髒頁,反著對資料進行修改
3、do、undo的時間相同,且都會產成redo資訊
4、事務提交
MySQL回滾處理機制:
如果執行緒中斷,事務沒有提交,undo會將記錄此資訊,待另一會話程序連上,檢視該塊資料資訊,MySQL自動回滾進行資料頁修改,然後被讀取。也就是說為了避免系統因為rollback被hang住,通過直接殺死程序的方式,中斷事務,等待後來者要讀取該資料資訊時進行回滾,再返回結果。
Q:rollback為什麼有時候很慢,rollback的風險和風險避免方式?
A:
rollback的時間取決於回滾前事務修改資料的時間,處理量大回滾時間長,處理量小回滾時間短。
1、rollback風險:容易導致系統被hang住;
2、風險避免方式:直接殺死會話程序或是mysql程序。
3、儲存寫入效能分析
Q:mysql commit,儲存為什麼寫速度能夠保持在0ms,極少出現1ms情況?
A:
對於儲存來說,寫效能相當高:假設儲存cache總有空閒空間的情況下,事務提交,將log buffer中剩餘的很少的redo資料寫入儲存cache,即為完成mysql commit,這個過程是相當快的(能夠保持在0ms,極少出現1ms情況),後續redo資料由cache寫入磁碟的過程是後臺進行。
4、儲存級別的災備(同城災備)
1、災備同步過程:commit
1、redo、binlog寫入本地儲存cache;
2、通過網路同步binlog寫入遠端同步的伺服器的儲存cache中;
3、響應本地資料庫;
4、事務提交成功;
2、風險:
網路出現問題(訊號斷續,纜線斷了),導致寫hang住,commit超時失敗。
3、解決:
通過超時設定,網路中斷超過限制,自動將同步改為災備非同步,儘可能少的影響業務commit超時失敗。
二、分析與處理
儲存寫效能比較差,很多時段會達到5ms,甚至於10ms以上
備註:災備同步已經停止的情況下。
1、儲存中BBU問題,出現監控BBU的bug;
解決:重啟BBU,不行就更新BBU。
2、cache被佔滿
1、海量資料寫入,commit資料佔滿cache;
2、硬碟I/O異常,異常SQL導致的海量物理讀;
解決:索引優化。
3、儲存效能差
解決:找老闆掏錢,更換優質裝置。