mysql長事務查詢 智庫 資料庫長事務詳解

2021-10-18 12:09:10 字數 3715 閱讀 2938

在資料庫的日常維護中,我們常常會聽說資料庫「長事務」這個詞,那麼何為長事務?長事務是如何產生的?長事務對資料庫有什麼影響?如何防止長事務的產生?本文就根據筆者的運維經驗談談對資料庫長事務的理解。

1.什麼是事務

事務是關係型資料庫中的乙個邏輯工作單元,它由乙個或多個sql語句組成,這些語句要麼全都執行,要麼全都不執行,執行前和執行後必須有一致的狀態,語句未執行完成之前對其它事務不可見,語句執行完成後所做的改變是永久的,即滿足acid特性。事務的acid特性確保了資料庫併發資料處理的正確性和災難恢復時資料的完整性,這是它有別於檔案系統的重要特徵。

2.什麼是長事務

長事務,顧名思義就是乙個事務執行了很長時間仍未結束。那麼乙個事務執行多長時間算是長事務?這在不同的資料庫產品中有不同的定義,對於informix資料庫來說占用邏輯日誌個數的百分比達到長事務高水位線就被定義為乙個長事務,而在oracle中乙個事務執行時間超過6秒鐘就被認為是長事務。一般來說在乙個聯機事務處理系統中事務執行時間應該控制在一定範圍內,如果乙個事務執行時間太長,會長時間鎖定某些資源,不利於併發處理,有時還會因為某些資源耗盡導致資料庫掛起。

3.事務的控制

事務有開始和結束,以「begin」作為事務的開始,以「commit」或「rollback」結束,「commit」表明事務執行成功,對資料庫所做的修改已經生效,「rollback」則說明事務執行失敗,對資料庫的所有操作均需要撤銷,恢復到事務執行之前的狀態。為了使事務能被撤銷,資料庫管理系統必須對所有操作及被修改前的資料進行記錄,以便撤銷時能夠執行逆向操作,將資料恢復到以前的狀態。在具體的實現中,不同的資料庫有不同的方法,下面以informix和oracle為例進行分析。

informix使用記錄日誌方式儲存事務操作及資料,稱為物理日誌和邏輯日誌。

物理日誌是一塊連續的磁碟空間,可以迴圈使用,用來存放上一次檢查點之後第一次被修改的資料塊的前映像,資料在下一次檢查點完成時被邏輯清空,所使用儲存空間被釋放。當物理日誌使用率達到75%時就會觸發檢查點,物理日誌即被清空。因此,物理日誌並不能用於事務回滾,只能用於例項恢復,當資料庫非正常關閉時,使用物理日誌可以將資料庫快速恢復到最近一次檢查點的狀態。

邏輯日誌由三個或多個日誌檔案組成,採用迴圈寫入的方式,當乙個邏輯日誌寫滿時切換到下乙個未被使用的日誌繼續寫。邏輯日誌不僅記錄事務開始、提交、回滾、檢查點、ddl、dml等操作,還同時記錄被修改資料的前後映像,而且如果乙個日誌包含未提交的事務就不能被釋放,故邏輯日誌被應用在事務回滾和事務恢復中。

物理日誌的釋放只與檢查點有關,檢查點一旦完成,物理日誌中內容就不再需要了,就可以釋放,但是邏輯日誌空間只有同時滿足以下條件時才能被釋放:不包含活動事務、不包含最後一次檢查點、日誌已被備份,以便保留足夠的資訊用於事務回滾和恢復。這樣就帶來乙個問題,如果乙個事務佔據了全部邏輯日誌,資料庫就會進入阻塞狀態,甚至連回滾操作也不能進行,因為回滾也需要寫日誌。為了防止資料庫因日誌資源耗盡發生阻塞,informix設定了長事務高水位線(ltxhwm)和獨佔的長事務高水位線(ltxehwm),當乙個事務占用日誌個數的百分比達到長事務高水位線就被標識為乙個長事務,並自動觸發回滾操作,當百分比達到獨佔的長事務高水位線時,其它會話均進入阻塞狀態,只進行長事務回滾操作。

informix的事務控制機制嚴重依賴於邏輯日誌,在邏輯日誌中既要寫操作又要寫資料,導致邏輯日誌非常繁忙,容易引發故障。我們再來看看另外一種廣泛使用的資料庫oracle,似乎很少聽到關於長事務的討論,那它是如何來進行事務控制的呢?

oracle也是使用類似機制來實現事務控制,稱為撤銷段(undo segment,9i版本以前使用回滾段,需手工管理)和重做日誌檔案(redo log file)。

撤銷段由系統自動管理,在undo表空間中分配,一般會分配乙個系統段和多個非系統段,系統根據需要自動進行擴充套件和收縮,可以迴圈使用。撤銷段中儲存了事務資訊及被更新資料的前值,當事務回滾時利用這些資料就可以將資料恢復到事務開始前的狀態,這就要求在事務未提交之前撤銷段中的資料不能被覆蓋,有時為了滿足查詢一致性要求可能保留更長時間。

重做日誌檔案以組的形式存在,每個例項至少有兩組,以便能在寫滿之後進行切換,每個組至少包含乙個成員。重做日誌檔案中記錄了對資料庫所做的全部操作,通過重放日誌可實現例項恢復。在例項恢復過程中,通過前滾重做日誌,將最近一次檢查點以來已提交的事務重做一次,如果遇到未提交的事務則進行入回滾過程,此時需要撤銷段的參與。重做日誌檔案只要不包含最近一次檢查點以後的資料(inactive狀態)且歸檔完成(歸檔模式下)後就可以被重寫,與事務是否提交無關。

與informix相比,oracle將用於回滾的資料與事務操作分離開來,緩解了重做日誌檔案寫入的壓力,也不用擔心重做日誌檔案被覆蓋的問題,使用專用的撤銷段來管理回滾資料,就算undo表空間耗盡引發事務回滾,也不會導致資料庫掛起,因為事務回滾時只寫重做日誌,不寫撤銷段。

4.長事務產生的幾種原因

在informix中,長事務現象時有發生,主要有以下原因:

1) 邏輯日誌引數設定不合理,日誌個數太少或長事務高水位線太低;

2) 資料庫併發很高,某些事務的粒度太粗,事務長時間不能提交,最終觸及長事務高水位線;

3) 事務啟動後,未使用commit或rollback來終止事務;

4) 大表連線插入目標表,連線條件不正確產生笛卡爾集,結果集超出預期,長時間不能處理完成;

5) 使用臨時表裝載大量資料,未指定withno log子句,也未設定temptab_nolog引數。

5.如何避免長事務

對於oracle來說,長事務可能會導致「ora-30036」錯誤,即undo表空間已被用完,無法擴充套件撤銷段,但只要將undo表空間設定為自動擴充套件並確保磁碟空間足夠就不會產生此問題。而informix長事務帶來的後果是很嚴重的,雖然在長事務發生時可以通過手工新增邏輯日誌方式來挽救,但是及時性難以保證。不過長事務也是可以避免的,只要合理地設定資料庫引數,合理的編寫應用,長事務發生的概率會大大降低。具體來說可以從以下幾點做起:

1) 根據資料庫併發使用者數量及更新資料量設定邏輯日誌大小和個數,應保證在高併發情況下大部分事務能正常完成;

2) 適當調低長事務高水位線,確保在長事務發生時有足夠的日誌檔案用於回滾;

3) 設定引數dynamic_logs為2,當資料庫檢測到第n+1(n為當前正在寫的日誌)個日誌不可用就會自動新增乙個新的日誌檔案,需要注意的是日誌不是在事務到達高水位線之後就增加,而是在無可用日誌檔案時才增加,因此若不希望事務回滾過程中資料庫進入阻塞狀態,還須手工新增日誌;

4) 合理控制事務的顆粒度,將大事務分割為小事務進行處理,減少單個事務處理時間,提高邏輯日誌資源利用率;

5) 事務操作應閉合,事務開始之後必須結束,盡量避免回滾操作,減少對系統資源的消耗;

6) 大表進行連線時,盡量保證連線條件唯一,避免產生笛卡爾集,目標錶可使用裸表,避免產生事務日誌;

7) 對於臨時表的使用應謹慎,在建立臨時表應養成寫with no log字句的習慣,或將資料庫引數temptab_nolog指定為1,這樣就算建立臨時表沒有with no log語句,資料庫也會預設使用臨時表空間,不會記錄事務日誌;

mysql資料庫事務

維基百科 事務是資料庫管理系統 dbms 執行過程中的乙個邏輯單位,由乙個有限的資料庫操作序列構成。只有innodb和ndb 1 原子性 atomicity 事務中的全部操作在資料庫中是不可分割的,要麼全部完成,要麼全部不執行。2 一致性 consistency 幾個並行執行的事務,其執行結果必須與...

MySQL資料庫事務

文章出處 只有innodb引擎支援事務,下邊的內容均以innodb引擎為預設條件 1 髒讀 2 不可重複讀 3 幻讀 1 讀未提交 read uncommitted 可能產生髒讀 不可重複讀 幻讀 2 讀已提交 read committed 避免了髒讀,可能產生不可重複讀 幻讀 3 可重複讀 rep...

mysql資料庫事務

原子性 乙個事務 transaction 中的所有操作,要麼全部完成,要麼全部不完成,不會結束在中間某個環節 一致性 在事務開始之前和事務結束以後,資料庫的完整性沒有被破壞 隔離性 資料庫允許多個併發事務同時對其資料進行讀寫和修改的能力,隔離性可以防止多個事務併發執行時由於交叉執行而導致資料的不一致...