<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                ## 1. 事務基礎知識 ### 1.1 存儲引擎支持情況 SHOW ENGINES 命令來查看當前 MySQL 支持的存儲引擎都有哪些,以及這些存儲引擎是否支持事務。目前只有 InnoDB 是支持事務的。 ### 1.2 基本概念 事務:一組邏輯操作單元,使數據從一種狀態變換到另一種狀態。 事務處理的原則:保證所有事務都作為 一個工作單元 來執行,即使出現了故障,都不能改變這種執行方 式。當在一個事務中執行多個操作時,要么所有的事務都被提交( commit ),那么這些修改就 永久 地保 存下來;要么數據庫管理系統將 放棄 所作的所有 修改 ,整個事務回滾( rollback )到最初狀態。 ### 1.3 事務的ACID特性 * 原子性(atomicity):原子性是指事務是一個不可分割的工作單位,要么全部提交,要么全部失敗回滾。 * 一致性(consistency):一致性是指事務執行前后,數據從一個 合法性狀態 變換到另外一個 合法性狀態 。這種狀態 是 語義上 的而不是語法上的,跟具體的業務有關。 * 隔離型(isolation):一個事務的執行 不能被其他事務干擾 ,即一個事務內部的操作及使用的數據對 并發 的 其他事務是隔離的,并發執行的各個事務之間不能互相干擾。 * 持久性(durability):持久性是指一個事務一旦被提交,它對數據庫中數據的改變就是 永久性的 ,接下來的其他操作和數據庫 故障不應該對其有任何影響。 持久性是通過 事務日志 來保證的。日志包括了 重做日志 和 回滾日志 。當我們通過事務對數據進行修改 的時候,首先會將數據庫的變化信息記錄到重做日志中,然后再對數據庫中對應的行進行修改。這樣做 的好處是,即使數據庫系統崩潰,數據庫重啟后也能找到沒有更新到數據庫系統中的重做日志,重新執 行,從而使事務具有持久性。 ### 1.4 事務的狀態 MySQL根據這些操作所執 行的不同階段把 事務 大致劃分成幾個狀態: * 活動的(active) 事務對應的數據庫操作正在執行過程中時,我們就說該事務處在 活動的 狀態。 * 部分提交的(partially committed) 當事務中的最后一個操作執行完成,但由于操作都在內存中執行,所造成的影響并 沒有刷新到磁盤 時,我們就說該事務處在 部分提交的 狀態。 * 失敗的(failed) 當事務處在 活動的 或者 部分提交的 狀態時,可能遇到了某些錯誤(數據庫自身的錯誤、操作系統 錯誤或者直接斷電等)而無法繼續執行,或者人為的停止當前事務的執行,我們就說該事務處在 失敗的 狀態。 * 中止的(aborted)如果事務執行了一部分而變為 失敗的 狀態,那么就需要把已經修改的事務中的操作還原到事務執 行前的狀態。換句話說,就是要撤銷失敗事務對當前數據庫造成的影響。我們把這個撤銷的過程稱 之為 回滾 。當 回滾 操作執行完畢時,也就是數據庫恢復到了執行事務之前的狀態,我們就說該事 務處在了 中止的 狀態。 * 提交的(committed) 當一個處在 部分提交的 狀態的事務將修改過的數據都 同步到磁盤 上之后,我們就可以說該事務處 在了 提交的 狀態。 ![](https://img.kancloud.cn/22/d0/22d0d1843bdc434d4d0f74fa5edb84b3_1447x935.png) ## 2. 如何使用事務 ### 2.1 顯式事務 START TRANSACTION 或者 BEGIN ,作用是顯式開啟一個事務。 ``` mysql> BEGIN; #或者 mysql> START TRANSACTION; ``` ## 3. 事務隔離級別 ### 數據并發問題 1. 臟寫( Dirty Write ) 事務A修改了事務B未提交的的數據。 2. 臟讀( Dirty Read ) 事務A讀取了事務B修改但未提交的的數據。 3. 不可重復讀( Non-Repeatable Read ) 事務A讀取了一個字段,事務B修改了此字段,當事務A再次讀取此字段時,值不同了,那就意味著發生了不可重復讀。 4. 幻讀( Phantom ) 事務A讀取了一個字段,然后事務B在該表中插入了一些新的行,之后事務A再次讀取同一個表,就會多出幾行。 ### 四種隔離級別 * READ UNCOMMITTED :讀未提交,在該隔離級別,所有事務都可以看到其他未提交事務的執行結 果。不能避免臟讀、不可重復讀、幻讀。 * READ COMMITTED :讀已提交,它滿足了隔離的簡單定義:一個事務只能看見已經提交事務所做 的改變。這是大多數數據庫系統的默認隔離級別(但不是MySQL默認的)。可以避免臟讀,但不可 重復讀、幻讀問題仍然存在。 * REPEATABLE READ :可重復讀,事務A在讀到一條數據之后,此時事務B對該數據進行了修改并提 交,那么事務A再讀該數據,讀到的還是原來的內容。可以避免臟讀、不可重復讀,但幻讀問題仍 然存在。這是MySQL的默認隔離級別。 * SERIALIZABLE :可串行化,確保事務可以從一個表中讀取相同的行。在這個事務持續期間,禁止 其他事務對該表執行插入、更新和刪除操作。所有的并發問題都可以避免,但性能十分低下。能避 免臟讀、不可重復讀和幻讀。 ![](https://img.kancloud.cn/16/21/1621661177f80ec0159b53ae4079f258_1649x556.png) ![](https://img.kancloud.cn/d1/a3/d1a36d683449ee34ef2eb9abf76fbeb6_1545x1047.png) MySQL支持的四種隔離級別 MySQL的默認隔離級別為 REPEATABLE READ **可重復讀** (Oracle,SqlServer中都是選擇讀已提交(Read Commited)) ``` # 查看隔離級別,MySQL 5.7.20的版本之前: SHOW VARIABLES LIKE 'tx_isolation'; # 查看隔離級別,MySQL 5.7.20的版本及之后: SHOW VARIABLES LIKE 'transaction_isolation'; # 或者不同MySQL版本中都可以使用的: SELECT @@transaction_isolation; ``` **如何設置事務的隔離級別** 修改事務的隔離級別: ``` # 使用 GLOBAL 關鍵字(在全局范圍影響):只對執行完該語句之后產生的會話起作用 # 使用 SESSION 關鍵字(在會話范圍影響): SET [GLOBAL|SESSION] TRANSACTION ISOLATION LEVEL 隔離級別; #其中,隔離級別格式: > READ UNCOMMITTED > READ COMMITTED > REPEATABLE READ > SERIALIZABLE 或者 SET [GLOBAL|SESSION] TRANSACTION_ISOLATION = '隔離級別' #其中,隔離級別格式: > READ-UNCOMMITTED > READ-COMMITTED > REPEATABLE-READ > SERIALIZABLE ``` 數據庫規定了多種事務隔離級別,不同隔離級別對應不同的干擾程度,隔離**級別越高,數據一致性 就越好,但并發性越弱。** ## 4. 事務的常見分類 從事務理論的角度來看,可以把事務分為以下幾種類型: * 扁平事務(Flat Transactions) * 帶有保存點的扁平事務(Flat Transactions with Savepoints) * 鏈事務(Chained Transactions) * 嵌套事務(Nested Transactions) * 分布式事務(Distributed Transactions) ## 5. MySQL事務日志 事務有4種特性:原子性、一致性、隔離性和持久性。那么事務的四種特性到底是基于什么機制實現呢? * 事務的**隔離性**由** 鎖機制** 實現。 * 而事務的原子性、一致性和持久性由事務的 redo 日志和 undo 日志來保證。 * REDO LOG 稱為 **重做日志** ,提供再寫入操作,恢復提交事務修改的頁操作,用來保證事務的**持久性**。 * UNDO LOG 稱為 **回滾日志** ,回滾行記錄到某個特定版本,用來保證事務的**原子性、一致性**。 ### 5.1 redo日志 重做日志 #### 為什么需要 redo 日志? 已經提交了的事務對數據庫中數據所做的修改永久生效,即使后來系 統崩潰,在重啟后也能把這種修改恢復出來。沒有必要在每次事務提交時就把該事務在內 存中修改過的全部頁面刷新到磁盤,只需要把 修改 了哪些東西 記錄一下 就好。 ![](https://img.kancloud.cn/fb/f7/fbf7bebd63fad3e9202910c3e0960c3d_1523x715.png) REDO日志的好處、特點 * 好處 * redo日志降低了刷盤頻率 (保存到硬盤的頻率) * redo日志占用的空間非常小 * 特點 * redo日志是順序寫入磁盤的 * 事務執行過程中,redo log不斷記錄 redo的組成 * 重做日志的緩沖 (redo log buffer) ,保存在內存中,是易失的。 * 重做日志文件 (redo log file) ,保存在硬盤中,是持久的。 redo的整體流程 ![](https://img.kancloud.cn/6c/b5/6cb5bdda40f5334c12eb023ab746579c_1144x378.png) 1. 先將原始數據從磁盤中讀入內存中來,修改數據的內存拷貝 2. 生成一條重做日志并寫入redo log buffer,記錄的是數據被修改后的值 3. 當事務commit時,將redo log buffer中的內容刷新到 redo log file,對 redo log file采用追加 寫的方式 4. 定期將內存中修改的數據刷新到磁盤中 redo log的刷盤策略 **先保存在緩存池,然后再寫入磁盤** redo log的寫入并不是直接寫入磁盤的,InnoDB引擎會在寫redo log的時候先寫redo log buffer,之后以 一 定的頻率 刷入到真正的redo log file 中。 ![](https://img.kancloud.cn/9b/24/9b24b1569a796ad53ceb8ae32b57934b_1126x597.png) **注意**,redo log buffer刷盤到redo log file的過程并不是真正的刷到磁盤中去,只是刷入到 **文件系統緩存** (page cache)中去(這是現代操作系統為了提高文件寫入效率做的一個優化),真正的寫入會交給系統自己來決定(比如page cache足夠大了)。那么對于InnoDB來說就存在一個問題,如果交給系統來同步,同樣如果系統宕機,那么數據也丟失了 InnoDB給出 innodb_flush_log_at_trx_commit 參數該參數控制 commit提交事務 時,如何將 redo log buffer 中的日志刷新到 redo log file 中。它支持三種策略: * **設置為 0** :表示**每次**事務提交時**不進行刷盤**操作。(系統默認master thread每隔1s進行一次重做日 志的同步) * **設置為 1** :表示**每次**事務提交時都將進行**同步**,**刷盤**操作( 默認值 ) * **設置為 2** :表示**每次**事務提交時都只把 **緩存池**(redo log buffer) 內容寫入 **文件系統緩存**(page cache),**不進行同步**。由操作**系統自己決定**什么時候同步到磁盤文件。 ### 5.2 Undo日志 回滾日志 redo log是事務持久性的保證,undo log是事務原子性的保證。在事務中 更新數據 的 前置操作 其實是要 先寫入一個 undo log 。 如何理解Undo日志 事務需要保證 原子性 ,也就是事務中的操作要么全部完成,要么什么也不做。但有時候事務執行到一半 會出現一些情況,如宕機,手動需要回滾數據,這需要把數據回滾到初始狀態 Undo日志的作用 **1. 回滾數據 2. MVCC** **undo的存儲結構** 1. 回滾段與undo頁, InnoDB對undo log的管理采用段的方式,也就是 回滾段(rollback segment) 。每個回滾段記錄了 1024 個 片段(undo log segment) ,而在每個undo log segment段中進行 undo頁 的申請。 * InnoDB1.1版本之前 只有一個rollback segment,但是在1.1 及其后面,支持最大 128個rollback segment,故其支持同時在線的事務限制提高到 了 128\*1024 2. 回滾段與事務 * 每個事務只會使用一個回滾段,一個回滾段在同一時刻可能會服務于多個事務。 * 當一個事務開始的時候,會制定一個回滾段,在事務進行的過程中,當數據被修改時,原始的數 據會被復制到回滾段。 * 在回滾段中,事務會不斷填充盤區,直到事務結束或所有的空間被用完。如果當前的盤區不夠 用,事務會在段中請求擴展下一個盤區,如果所有已分配的盤區都被用完,事務會覆蓋最初的盤 區或者在回滾段允許的情況下擴展新的盤區來使用。 * 回滾段存在于undo表空間中,在數據庫中可以存在多個undo表空間,但同一時刻只能使用一個 undo表空間。 * 當事務提交時,InnoDB存儲引擎會做以下兩件事情: * 將undo log放入列表中,以供之后的purge操作 * 判斷undo log所在的頁是否可以重用,若可以分配給下個事務使用 3. 回滾段中的數據分類 * 未提交的回滾數據(uncommitted undo information) * 已經提交但未過期的回滾數據(committed undo information) * 事務已經提交并過期的數據(expired undo information) undo的類型 在InnoDB存儲引擎中,undo log分為: * insert undo log * update undo log
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看