MySQL因大事務導致的Insert慢實例分析
【問題】
INSERT語句是最常見的SQL語句之一,最近有臺MySQL服務器不定時的會出現(xiàn)并發(fā)線程的告警,從記錄信息來看,有大量insert的慢查詢,執(zhí)行幾十秒,等待flushing log,狀態(tài)query end

【初步分析】
從等待資源來看,大部分時間消耗在了innodb_log_file階段,懷疑可能是磁盤問題導致,經(jīng)過排查沒有發(fā)現(xiàn)服務器本身存在硬件問題

后面開啟線程上升時pstack的自動采集,定位MySQL線程等待的位置。
【分析過程】
部署了pstack的自動抓取后,出現(xiàn)過6次thread concurrency >=50的告警(每次告警時會有大量的慢查詢產(chǎn)生),有3次抓到了現(xiàn)場。
并發(fā)線程升高時,有50多個線程卡在Stage_manager::enroll_for函數(shù),處于group commit階段


線程0x519c5940對應的SQL語句如下,已經(jīng)執(zhí)行18秒

Stage_manager::enroll_for函數(shù)的作用實現(xiàn)了多個線程在flush_stage階段的排隊。簡單來說,對于一個分組的事務,是被leader線程去提交的,其他線程處于排隊等待狀態(tài),等待leader線程將該線程的事務提交完成。
如果第一個線程執(zhí)行慢,后面的線程都處于等待狀態(tài),整組事務無法提交。

流程也可以理解如下,
Session A COMMIT-->拿到鎖-->進行binlog寫-->commit完成
Session B COMMIT-->等待鎖--------------------------->拿到鎖-->進行binlog寫-->commit完成
第一個線程為什么執(zhí)行很慢,分析了發(fā)生告警時間段的日志文件,發(fā)現(xiàn)日志中存在2個15M和20M的大事務

查看日志明細,存在delete from的大事務刪除語句,約包含23W條記錄,ROW模式下刪除23W條記錄,會產(chǎn)生大約20M的日志文件,刷盤時間較長,阻塞了同一個分組下其他事務的提交。

事務的開始時間與告警時間吻合
積壓的分組下事務集中刷盤,反應到磁盤指標上可以看到在問題時間段的disk_write_kbytes指標出現(xiàn)明顯的上升

【優(yōu)化方案】
1、 建議開發(fā)避免使用delete from 整表的大事務刪除語句
【其他變通方案】
2、 Binlog 記錄的ROW模式下會產(chǎn)生大量的日志,改為MIXED模式,理論上也可以解決問題
3、 更換性能好的磁盤
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。
相關文章
MySQL使用GROUP?BY使用技巧和注意事項總結(jié)
GROUP?BY?子句是?在MySQL?中用于將查詢結(jié)果按照指定的列或表達式進行分組的關鍵字,它通常與聚合函數(shù)一起使用,能夠?qū)γ總€分組進行統(tǒng)計或計算,本文給大家總結(jié)了MySQL使用GROUP?BY使用技巧和注意事項,需要的朋友可以參考下2024-05-05
Windows安裝MySQL后怎么開啟root的網(wǎng)絡訪問權(quán)限
Windows安裝MySQL后默認只能本機訪問,怎么開啟網(wǎng)絡訪問,本文給大家介紹介紹了Windows安裝MySQL后怎么開啟root的網(wǎng)絡訪問權(quán)限,需要的朋友可以參考下2023-08-08

