<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國際加速解決方案。 廣告
                **背景** MySQL從5.6版本開始支持GTID特性,也就是所謂全局事務ID,在整個復制拓撲結構內,每個事務擁有自己全局唯一標識。GTID包含兩個部分,一部分是實例的UUID,另一部分是實例內遞增的整數。 GTID的分配包含兩種方式,一種是自動分配,另外一種是顯式設置session.gtid_next,下面簡單介紹下這兩種方式: **自動分配** 如果沒有設置session級別的變量gtid_next,所有事務都走自動分配邏輯。分配GTID發生在GROUP COMMIT的第一個階段,也就是flush stage,大概可以描述為: ~~~ Step 1:事務過程中,碰到第一條DML語句需要記錄Binlog時,分配一段Gtid事件的cache,但不分配實際的GTID Step 2:事務完成后,進入commit階段,分配一個GTID并寫入Step1預留的Gtid事件中,該GTID必須保證不在gtid_owned集合和gtid_executed集合中。 分配的GTID隨后被加入到gtid_owned集合中。 Step 3:將Binlog 從線程cache中刷到Binlog文件中。 Step 4:將GTID加入到gtid_executed集合中。 Step 5:在完成sync stage 和commit stage后,各個會話將其使用的GTID從gtid_owned中移除。 ~~~ **顯式設置** 用戶通過設置session級別變量gtid_next可以顯式指定一個GTID,流程如下: ~~~ Step 1:設置變量gtid_next,指定的GTID被加入到gtid_owned集合中。 Step 2:執行任意事務SQL,在將binlog從線程cache刷到binlog文件后,將GTID加入到gtid_executed集合中。 Step 3:在完成事務COMMIT后,從gtid_owned中移除。 ~~~ 備庫SQL線程使用的就是第二種方式,因為備庫在apply主庫的日志時,要保證GTID是一致的,SQL線程讀取到GTID事件后,就根據其中記錄的GTID來設置其gtid_next變量。 **問題** 由于在實例內,GTID需要保證唯一性,因此不管是操作gtid_executed集合和gtid_owned集合,還是分配GTID,都需要加上一個大鎖。我們的優化主要集中在第一種GTID分配方式。 對于GTID的分配,由于處于Group Commit的第一個階段,由該階段的leader線程為其follower線程分配GTID及刷Binlog,因此不會產生競爭。 而在Step 5,各個線程在完成事務提交后,各自去從gtid_owned集合中刪除其使用的gtid。這時候每個線程都需要獲取互斥鎖,很顯然,并發越高,這種競爭就越明顯,我們很容易從pt-pmp輸出中看到如下類似的trace: ~~~ ha_commit_trans—>MYSQL_BIN_LOG::commit—>MYSQL_BIN_LOG::ordered_commit—>MYSQL_BIN_LOG::finish_commit—>Gtid_state::update_owned_gtids_impl—>lock_sidno ~~~ 這同時也會影響到GTID的分配階段,導致TPS在高并發場景下的急劇下降。 **解決** 實際上對于自動分配GTID的場景,并沒有必要維護gtid_owned集合。我們的修改也非常簡單,在自動分配一個GTID后,直接加入到gtid_executed集合中,避免維護gtid_owned,這樣事務提交時就無需去清理gtid_owned集合了,從而可以完全避免鎖競爭。 當然為了保證一致性,如果分配GTID后,寫入Binlog文件失敗,也需要從gtid_executed集合中刪除。不過這種場景非常罕見。 **性能數據** 使用sysbench,100張表,每張10w行記錄,update_non_index.lua,純內存操作,innodb_flush_log_at_trx_commit = 2,sync_binlog = 1000 ~~~ 并發線程 原生 修改后 32 24500 25000 64 27900 29000 128 30800 31500 256 29700 32000 512 29300 31700 1024 27000 31000 ~~~ 從測試結果可以看到,優化前隨著并發上升,性能出現下降,而優化后則能保持TPS穩定。
                  <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>

                              哎呀哎呀视频在线观看