<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國際加速解決方案。 廣告
                ## innodb行鎖簡介 1. 行鎖類型 ~~~ LOCK_S:共享鎖 LOCK_X: 排他鎖 ~~~ 1. GAP類型 ~~~ LOCK_GAP:只鎖間隙 LOCK_REC_NO_GAP:只鎖記錄 LOCK_ORDINARY: 鎖記錄和記錄之前的間隙 LOCK_INSERT_INTENTION: 插入意向鎖,用于insert時檢查鎖沖突 ~~~ 每個行鎖由鎖類型和GAP類型組成 例如: LOCK_X|LOCK_ORDINARY 表示對記錄和記錄之前的間隙加排他鎖 LOCK_S|LOCK_GAP 表示只對記錄前的間隙加共享鎖 鎖的兼容性: 值得注意的是,持有GAP的鎖(LOCK_GAP和LOCK_ORDINARY)與其他非LOCK_INSERT_INTENTION的鎖都是兼容的,也就是說,GAP鎖就是為了防止插入的。 詳細可以參考之前的[月報](http://mysql.taobao.org/monthly/2016/01/01/) ## innodb 鎖分裂、繼承與遷移 這里的鎖分裂和合并,只是針對innodb行鎖而言的,而且一般只作用于GAP類型的鎖。 * 鎖分裂 插入的記錄的間隙存在GAP鎖,此時此GAP需分裂為兩個GAP ~~~ lock_rec_inherit_to_gap_if_gap_lock: for (lock = lock_rec_get_first(block, heap_no); lock != NULL; lock = lock_rec_get_next(heap_no, lock)) { if (!lock_rec_get_insert_intention(lock) && (heap_no == PAGE_HEAP_NO_SUPREMUM || !lock_rec_get_rec_not_gap(lock))) { lock_rec_add_to_queue( LOCK_REC | LOCK_GAP | lock_get_mode(lock), block, heir_heap_no, lock->index, lock->trx, FALSE); } } ~~~ * 鎖繼承 刪除的記錄前存在GAP鎖,此GAP鎖會繼承到要刪除記錄的下一條記錄上 ~~~ lock_rec_inherit_to_gap: for (lock = lock_rec_get_first(block, heap_no); lock != NULL; lock = lock_rec_get_next(heap_no, lock)) { if (!lock_rec_get_insert_intention(lock) && !((srv_locks_unsafe_for_binlog || lock->trx->isolation_level <= TRX_ISO_READ_COMMITTED) && lock_get_mode(lock) == (lock->trx->duplicates ? LOCK_S : LOCK_X))) { lock_rec_add_to_queue( LOCK_REC | LOCK_GAP | lock_get_mode(lock), heir_block, heir_heap_no, lock->index, lock->trx, FALSE); } } ~~~ * 鎖遷移 B數結構變化,鎖信息也會隨之遷移. 鎖遷移過程中也涉及鎖繼承。 ## 鎖分裂示例 * 鎖分裂例子 ~~~ set global tx_isolation='repeatable-read'; create table t1(c1 int primary key, c2 int unique) engine=innodb; insert into t1 values(1,1); begin; # supremum 記錄上加 LOCK_X|LOCK_GAP 鎖住(1~) select * from t1 where c2=2 for update; # 發現插入(3,3)的間隙存在GAP鎖,因此給(3,3)加LOCK_X | LOCK_GAP鎖。這樣依然鎖住了(1~) insert into t1 values(3,3); ~~~ 這里如果插入(3,3)沒有給(3,3)加LOCK_X | LOCK_GAP,那么其他連接插入(2,2)就可以成功 ## 鎖繼承示例 * 隔離級別repeatable-read ![](https://box.kancloud.cn/2016-07-22_5791a6c86da7c.jpg) 驗證:session 1執行insert into t1 values(1,1)發生了鎖等待,說明(2,2)上有gap鎖 ~~~ mysql> select * from information_schema.innodb_locks; +------------------------+-------------+-----------+-----------+-----------------+------------+------------+-----------+----------+-----------+ | lock_id | lock_trx_id | lock_mode | lock_type | lock_table | lock_index | lock_space | lock_page | lock_rec | lock_data | +------------------------+-------------+-----------+-----------+-----------------+------------+------------+-----------+----------+-----------+ | 16582717714:888654:4:3 | 16582717714 | X,GAP | RECORD | `cleaneye`.`t1` | c2 | 888654 | 4 | 3 | 2 | | 16582692183:888654:4:3 | 16582692183 | X,GAP | RECORD | `cleaneye`.`t1` | c2 | 888654 | 4 | 3 | 2 | +------------------------+-------------+-----------+-----------+-----------------+------------+------------+-----------+----------+-----------+ 2 rows in set (0.01 sec) 其中session 2 在(2,2) 加了LOCK_X|LOCK_GAP session 1 在(2,2) 加了LOCK_X|LOCK_GAP|LOCK_INSERT_INTENTION. LOCK_INSERT_INTENTION與LOCK_GAP沖突發生等待 ~~~ * 隔離級別read-committed ![](https://box.kancloud.cn/2016-07-22_5791a6c88627c.jpg) 驗證: session 1執行insert into t1 values(1)發生了鎖等待,說明(2)上有gap鎖 ~~~ mysql> select * from information_schema.innodb_locks; +------------------------+-----------------+-----------+-----------+-------------+------------+------------+-----------+----------+-----------+ | lock_id | lock_trx_id | lock_mode | lock_type | lock_table | lock_index | lock_space | lock_page | lock_rec | lock_data | +------------------------+-----------------+-----------+-----------+-------------+------------+------------+-----------+----------+-----------+ | 1705:32:3:3 | 1705 | X,GAP | RECORD | `test`.`t1` | PRIMARY | 32 | 3 | 3 | 2 | | 421590768578232:32:3:3 | 421590768578232 | S,GAP | RECORD | `test`.`t1` | PRIMARY | 32 | 3 | 3 | 2 | +------------------------+-----------------+-----------+-----------+-------------+------------+------------+-----------+----------+-----------+ X.GAP insert 加鎖LOCK_X | LOCK_GAP | LOCK_INSERT_INTENTION S.GAP 加鎖LOCK_S|LOCK_GAP,記錄(2)從刪除的記錄(1)繼承過來的GAP鎖 ~~~ 而實際在讀提交隔離級別上,insert into t1 values(1)應該可以插入成功,不需要等待的,這個鎖是否繼承值得商榷。 來看一個插入成功的例子 ![](https://box.kancloud.cn/2016-07-22_5791a6c8a8fa2.jpg) * 隔離級別serializable ![](https://box.kancloud.cn/2016-07-22_5791a6c8c2e54.jpg) 驗證方法同read-committed。 ## B樹結構變化與鎖遷移 B樹節點發生分裂,合并,刪除都會引發鎖的變化。鎖遷移的原則是,B數結構變化前后,鎖住的范圍保證不變。 我們通過例子來說明 * 節點分裂 假設原節點A(infimum,1,3,supremum) 向右分裂為B(infimum,1,supremum), C(infimum,3,supremum)兩個節點 > infimum為節點中虛擬的最小記錄,supremum為節點中虛擬的最大記錄 假設原節點A上鎖為3上LOCK_S|LOCK_ORIDNARY,supremum為LOCK_S|LOCK_GAP,實際鎖住了(1~) 鎖遷移過程大致為: 1. 將3上的gap鎖遷移到C節點3上 2. 將A上supremum遷移繼承到C的supremum上 3. 將C上最小記錄3的鎖遷移繼承到B的supremum上 遷移完成后鎖的情況如下(lock_update_split_right) B節點:suprmum LOCK_S|LOCK_GAP C節點:3 LOCK_S|LOCK_ORINARY, suprmum LOCK_S|GAP 遷移后仍然鎖住了范圍(1~) 節點向左分裂情形類似 * 節點合并 以上述節點分裂的逆操作來講述合并過程 B(infimum,1,supremum), C(infimum,3,supremum)兩個節點,向左合并為A節點(infimum,1,3,supremum) 其中B,C節點鎖情況如下 B節點:suprmum LOCK_S|LOCK_GAP C節點:3 LOCK_S|LOCK_ORINARY, suprmum LOCK_S|GAP 遷移流程如下(lock_update_merge_left): 1)將C節點鎖記錄3遷移到B節點 2)將B節點supremum遷移繼承到A的supremum上 遷移后仍然鎖住了范圍(1~) 節點向右合并情形類似 * 節點刪除 如果刪除節點存在左節點,則將刪除節點符合條件的鎖,遷移繼承到左節點supremum上 否則將刪除節點符合條件的鎖,遷移繼承到右節點最小用戶記錄上 參考lock_update_discard ## 鎖繼承相關的BUG [bug#73170](https://bugs.mysql.com/bug.php?id=73170)?二級唯一索引失效。這個bug觸發條件是刪除的記錄沒有被purge, 鎖還沒有被繼承的。如果鎖繼承了就不會出現問題。 [bug#76927](https://bugs.mysql.com/bug.php?id=76927)?同樣是二級唯一索引失效。這個bug是鎖繼承機制出了問題。 以上兩個bug詳情參考[這里](http://mysql.taobao.org/monthly/2015/06/02/)
                  <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>

                              哎呀哎呀视频在线观看