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

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                **前言** 與oracle 不同,mysql 的主庫與備庫的同步是通過 binlog 實現的,而redo日志只做為mysql 實例的crash recovery使用。mysql在4.x 的時候放棄redo 的同步策略而引入 binlog的同步,一個重要原因是為了兼容其它非事務存儲引擎,否則主備同步是沒有辦法進行的。 redo 日志同步屬于物理同步方法,簡單直接,將修改的物理部分傳送到備庫執行,主備共用一致的 LSN,只要保證 LSN 相同即可,同一時刻,只能主庫或備庫一方接受寫請求; binlog的同步方法屬于邏輯復制,分為statement 或 row 模式,其中statement記錄的是SQL語句,Row 模式記錄的是修改之前的記錄與修改之后的記錄,即前鏡像與后鏡像;備庫通過binlog dump 協議拉取binlog,然后在備庫執行。如果拉取的binlog是SQL語句,備庫會走和主庫相同的邏輯,如果是row 格式,則會調用存儲引擎來執行相應的修改。 本文簡單說明5.5到5.7的主備復制性能改進過程。 replication improvement (from 5.5 to 5.7) **(1) 5.5 中,binlog的同步是由兩個線程執行的** io_thread: 根據binlog dump協議從主庫拉取binlog, 并將binlog轉存到本地的relaylog; sql_thread: 讀取relaylog,根據位點的先后順序執行binlog event,進而將主庫的修改同步到備庫,達到主備一致的效果; 由于在主庫的更新是由多個客戶端執行的,所以當壓力達到一定的程度時,備庫單線程執行主庫的binlog跟不上主庫執行的速度,進而會產生延遲造成備庫不可用,這也是分庫的原因之一,其SQL線程的執行堆棧如下: ~~~ sql_thread: exec_relay_log_event apply_event_and_update_pos apply_event rows_log_event::apply_event storage_engine operation update_pos ~~~ (2)?**5.6 中,引入了多線程模式,在多線程模式下,其線程結構如下** io_thread: 同5.5 Coordinator_thread: 負責讀取 relay log,將讀取的binlog event以事務為單位分發到各個 worker thread 進行執行,并在必要時執行binlog event(Description_format_log_event, Rotate_log_event 等)。 worker_thread: 執行分配到的binlog event,各個線程之間互不影響; **多線程原理** sql_thread 的分發原理是依據當前事務所操作的數據庫名稱來進行分發,如果事務是跨數據庫行為的,則需要等待已分配的該數據庫的事務全部執行完畢,才會繼續分發,其分配行為的偽碼可以簡單的描述如下: ~~~ get_slave_worker if (contains_partition_info(log_event)) db_name= get_db_name(log_event); entry {db_name, worker_thread, usage} = map_db_to_worker(db_name); while (entry->usage > 0) wait(); return worker; else if (last_assigned_worker) return last_assigned_worker; else push into buffer_array and deliver them until come across a event that have partition info ~~~ **需要注意的細節** * * 內存的分配與釋放。relay thread 每讀取一個log_event, 則需要 malloc 一定的內存,在work線程執行完后,則需要free掉; * 數據庫名 與 worker 線程的綁定信息在一個hash表中進行維護,hash表以entry為單位,entry中記錄當前entry所代表的數據庫名,有多少個事務相關的已被分發,執行這些事務的worker thread等信息; * 維護一個綁定信息的array , 在分發事務的時候,更新綁定信息,增加相應 entry->usage, 在執行完一個事務的時候,則需要減少相應的entry->usage; * slave worker 信息的維護,即每個 worker thread執行了哪些事務,執行到的位點是在哪,延遲是如何計算的,如果執行出錯,mts_recovery_group 又是如何恢復的; * 分配線程是以數據庫名進行分發的,當一個實例中只有一個數據庫的時候,不會對性能有提高,相反,由于增加額外的操作,性能還會有一點回退; * 臨時表的處理,臨時表是和entry綁定在一起的,在執行的時候將entry的臨時表掛在執行線程thd下面,但沒有固化,如果在臨時表操作期間,備庫crash,則重啟后備庫會有錯誤; **總體上說,5.6 的并行復制打破了5.5 單線程的復制的行為,只是在單庫下用處不大,并且5.6的并行復制的改動引入了一些重量級的bug** * * mysql slave sql thread memory leak ([http://bugs.mysql.com/bug.php?id=71197](http://bugs.mysql.com/bug.php?id=71197)) * Relay log without xid_log_event may case parallel replication hang ([http://bugs.mysql.com/bug.php?id=72794](http://bugs.mysql.com/bug.php?id=72794)) * Transaction lost when relay_log_info_repository=FILE and crashed ([http://bugs.mysql.com/bug.php?id=73482](http://bugs.mysql.com/bug.php?id=73482)) (3) 5.7中,并行復制的實現添加了另外一種并行的方式,即主庫在 ordered_commit中的第二階段的時候,將同一批commit的 binlog 打上一個相同的seqno標簽,同一時間戳的事務在備庫是可以同時執行的,因此大大簡化了并行復制的邏輯,并打破了相同 DB 不能并行執行的限制。備庫在執行時,具有同一seqno的事務在備庫可以并行的執行,互不干擾,也不需要綁定信息,后一批seqno的事務需要等待前一批相同seqno的事務執行完后才可以執行。 詳細實現可參考:[http://bazaar.launchpad.net/~mysql/mysql-server/5.7/revision/6256](http://bazaar.launchpad.net/~mysql/mysql-server/5.7/revision/6256)?。 reference:[http://geek.rohitkalhans.com/2013/09/enhancedMTS-deepdive.html](http://geek.rohitkalhans.com/2013/09/enhancedMTS-deepdive.html)
                  <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>

                              哎呀哎呀视频在线观看