【MySQL】長事務

一. 長事務原因

1. set autocommit=0

  1. 這個命令會關閉當前線程的事務自動提交功能
  1. 意味着如果只執行一個 select 語句,這個事務就啓動了,並且不會自動提交。
    這個事務持續存在直到主動執行 commit 或 rollback 語句,或者斷開連接。如果是長連接,就導致了長事務。
  1. 有些客戶端連接框架會默認連接成功後先執行一個 set autocommit=0 的命令。這就導致接下來的查詢都在事務中,如果是長連接,就導致了長事務。
  1. 所以建議使用【set autocommit=1】, 通過顯式語句的方式來啓動事務。

2. 事務方法業務複雜,執行時間長


二. 長事務危害

1. 佔用大量的存儲空間

  1. 在 MySQL 中,實際上每條記錄在更新的時候都會同時記錄一條回滾操作。記錄更新前的值,通過回滾操作,就可以得到前一個狀態的值。
  2. 這些記錄下來的回滾操作就是回滾段,長事務意味着系統裏面會存在很老的回滾段。由於這些事務隨時可能訪問數據庫裏面的任何數據,所以這個事務提交之前,這些回滾記錄數據都必須保留,這就會導致佔用大量的存儲空間。

在這裏插入圖片描述


2. 佔用鎖資源,甚至拖垮整個庫

  1. 事務內的增刪改操作都會對數據加鎖,在事務提交或回滾前會一直佔用鎖資源

三. 查看長事務

  1. 查找持續時間超過 60s 的事務
select * from information_schema.innodb_trx where TIME_TO_SEC(timediff(now(),trx_started))>60

四. 解決長事務

1. 程序端

  1. 確認是否使用了【set autocommit=0】,建議使用【set autocommit=1】。
  2. 確認是否有不必要的只讀事務。
  3. 通過 SET MAX_EXECUTION_TIME 命令,來控制每個語句執行的最長時間,避免單個語句執行太長時間。
  4. 通過【消息隊列、異步線程】分離事務方法內的業務,減少事務方法的執行時間。

2. 數據庫端

  1. 監控 information_schema.Innodb_trx 表,設置長事務閾值,超過就報警 或者 kill。
  2. 如果使用的是 MySQL 5.6 或者更新版本,把 innodb_undo_tablespaces 設置成 2(或更大的值)。如果真的出現大事務導致回滾段過大,這樣設置後清理起來更方便。
  3. 在業務功能測試階段要求輸出所有的 general_log,分析日誌行爲提前發現問題。

五. 參考資料

1. mysql 之general_log日誌開啓詳解以及清空

https://blog.csdn.net/u010735147/article/details/81871560

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章