<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>

                [TOC] # 并發控制 OceanBase 數據庫基于多版本(Multi Version)及行級別鎖實現了數據庫的并發控制邏輯、讀不加鎖、寫加互斥鎖。做到了讀讀、讀寫、寫讀不相互阻塞,大大提高了系統的并發能力。由于讀讀并發對數據沒有任何修改,因此沒有正確性的問題。關于并發控制的設計,下文主要討論讀寫、寫讀、寫寫三種情況。 ## 事務版本號 * 語句快照 RC 隔離級別下,每條語句都能讀到該語句開始之前的最新數據,這一特性的保證,需要在語句開啟之前獲取一次最新快照版本,該版本我們稱為語句快照。 * 事務快照 可串行化隔離級別下,事務內的每條語句只能看到該事務開啟之前的數據,這一特性的保證,需要在開啟事務之前獲取一次最新快照版本,該版本我們稱為事務快照。RR 隔離級別下,OceanBase 數據庫也采用事務級別快照。 * 提交版本號 事務提交過程中需要為本次修改的數據確定一個版本號,我們稱之為事務的提交版本號。GTS 打開場景下,提交版本號從 GTS Leader 獲取并確認;GTS 關閉場景下,提交版本號由數據所在 server 共同進行協商。 ## 一致性讀 OceanBase 數據庫支持兩種類型的讀請求,強一致性讀和弱一致性讀。強一致性讀要求根據快照信息讀取 leader 上的數據;弱一致性讀允許讀取某一個稍舊的版本的數據。 **強一致性讀** * 跨機查詢的語句,需要獲取全局一致的快照,否則無法保證強讀的一致性。因此該情況下,需要確保 GTS 是打開的。 * 單機的查詢,理論上不需要依賴 GTS,通過獲取待讀分區的最大已經提交的版本號,取其最大值作為讀快照,就能保證強讀的一致性。 **弱一致性讀** 用戶使用弱讀的功能,有兩種方法: * 查詢語句添加 hint ~~~ Select /*+read_consistency(weak)*/ * from test where c1=1; ~~~ * 設置系統變量 Session 級別設置: `set @@ob_read_consistency=2,其中1=FROZEN、2=WEAK、3=STRONG;` 用戶級別設置: `set global ob_read_consistency=2;` OceanBase 數據庫維護了一個租戶級別最大安全可讀的版本號,弱讀語句快照由該版本號決定。非 RC 隔離級別的弱讀沒有意義,因此 OceanBase 數據庫只在 RC 隔離級別下支持弱讀。 下文討論的并發控制,沒有特殊說明,均指的是強一致性讀。 ## 寫讀并發 對某行數據而言,讀寫事務和只讀事務并發執行,只讀事務讀取過程中,該行正在被讀寫事務修改且尚未提交,我們稱之為寫讀并發。 該場景下,OceanBase 數據庫的正確性保證邏輯如下: 讀寫事務 T1 提交過程中,確定 commit 成功之前,該事務的提交版本號(commit version)是無法知道的。此時如果有讀事務 T2 并發讀取該行,是否能夠讀到該事務的修改呢?需要分情況討論:如果 T1 的提交版本號(commit version) < T2 的讀快照(read version),則 T2 需要讀到 T1 的修改;否則 T2 不需要讀到 T1 的修改。 具體而言,如果 T1 此時尚未收到用戶發來的 commit,那么 T2 的 read version 一定會小于 T1 的 commit version,因此該情況下 T2 不需要等T1提交結束;如果T1此時處于正在提交過程中,則T2需要等T1確定 commit version,才能決定是否需要讀T1修改的數據。這里的等待對用戶而言是透明的,因此仍能滿足“寫不阻塞讀”的這一結論。 ## 讀寫并發 對某行數據而言,讀寫事務和只讀事務并發執行,讀寫事務操作該行之前,已經有只讀事務對該行進行讀操作,我們稱之為讀寫并發。該場景下,OceanBase 數據庫的正確性保證邏輯如下: 只讀事務讀取過程中,讀寫事務還在執行,客戶端尚未發出 commit,因此 T1 的 read version 一定小于 T2 的 commit version,T1 不需要讀到 T2 的修改。T1 和 T2 不會相互等待。 ## 寫寫并發 寫寫并發場景,主要通過對行加互斥鎖來實現,即前一個事務尚未提交結束,后一個需要操作同一行的事務需要等待。寫寫并發場景,lost update 問題是重點需要解決的。考慮事務 T1 和事務 T2,兩者并發單分區表 A 中的同一行 R1,待更新的列上有局部索引。執行流程如下: 1. 事務 T1 和事務 T2 語句開啟,獲取相同的語句快照版本號,假設均為 100。 2. 事務 T1 語句執行過程中,先于 T2 獲取行鎖,并執行更新。事務 T2 出現行鎖沖突,重試等行鎖釋放。 3. 事務 T1 提交結束,行鎖釋放。 事務 T2 該如何執行?如果 T2 直接持有行鎖,繼續修改,將會出現數據一致性問題,因為 T2 并沒有看到 T1 的修改,直接將其數據進行了覆蓋。OceanBase 數據庫為了解決該問題,T2 加上 R1 的行鎖之后,會進行一次 Double Check,如果發現存在該問題,不同隔離級別下的處理方法不同: * RC 隔離級別下重試執行該語句。 * 可串行化隔離級別下,該語句不能重試并且需要向用戶返回如下錯誤: ORA-08177: Cannot serialize access for this transaction 當數據庫返回 ORA-08177 時,用戶可以根據業務的情況做出決定: * 回滾事務,然后重新執行整個事務。或者, * 提交該語句之前的事務。或者, * 回滾到某個 save point 然后執行其他分支。
                  <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>

                              哎呀哎呀视频在线观看