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

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                **bug描述** Oracle 最新發布的版本 5.6.22 中有這樣一個關于GTID的bugfix,在主備場景下,如果我們在主庫上 SET GLOBAL GTID_PURGED = "some_gtid_set",并且 some_gtid_set 中包含了備庫還沒復制的事務,這個時候如果備庫接上主庫的話,預期結果是主庫返回錯誤,IO線程掛掉的,但是實際上,在這種場景下主庫并不報錯,只是默默的把自己 binlog 中包含的gtid事務發給備庫。這個bug的造成的結果是看起來復制正常,沒有錯誤,但實際上備庫已經丟事務了,主備很可能就不一致了。 **背景知識** 一) binlog GTID事件 binlog 中記錄的和GTID相關的事件主要有2種,Previous_gtids_log_event 和 Gtid_log_event,前者表示之前的binlog中包含的gtid的集合,后者就是一個gtid,對應一個事務。一個 binlog 文件中只有一個 Previous_gtids_log_event,放在開頭,有多個 Gtid_log_event,如下面所示 ~~~ Previous_gtids_log_event // 此 binlog 之前的所有binlog文件包含的gtid集合 Gtid_log_event // 單個gtid event Transaction Gtid_log_event Transaction . . . Gtid_log_event Transaction ~~~ 二) 備庫發送GTID集合給主庫 我們知道備庫的復制線程是分IO線程和SQL線程2種的,IO線程通過GTID協議或者文件位置協議拉取主庫的binlog,然后記錄在自己的relay log中;SQL線程通過執行realy log中的事件,把其中的操作都自己做一遍,記入本地binlog。在GTID協議下,備庫向主庫發送拉取請求的時候,會告知主庫自己已經有的所有的GTID的集合,Retrieved_Gtid_Set + Executed_Gtid_Set,前者對應 realy log 中所有的gtid集合,表示已經拉取過的,后者對應binlog中記錄有的,表示已經執行過的;主庫在收到這2個總集合后,會掃描自己的binlog,找到合適的binlog然后開始發送。 三)主庫如何找到要發送給備庫的第一個binlog 主庫將備庫發送過來的總合集記為 slave_gtid_executed,然后調用 find_first_log_not_in_gtid_set(slave_gtid_executed),這個函數的目的是從最新到最老掃描binlog文件,找到第一個含有不存在 slave_gtid_executed 這個集合的gtid的binlog。在這個掃描過程中并不需要從頭到尾讀binlog中所有的gtid,只需要讀出 Previous_gtids_log_event ,如果Previous_gtids_log_event 不是 slave_gtid_executed的子集,就繼續向前找binlog,直到找到為止。 這個查找過程總會停止的,停止條件如下: 1. 找到了這樣的binlog,其Previous_gtids_log_event 是slave_gtid_executed子集 2. 在往前讀binlog的時候,發現沒有binlog文件了(如被purge了),但是還沒找到滿足條件的Previous_gtids_log_event,這個時候主庫報錯 3. 一直往前找,發現Previous_gtids_log_event 是空集 在條件2下,報錯信息是這樣的 Got fatal error 1236 from master when reading data from binary log: 'The slave is connecting using CHANGE MASTER TO MASTER_AUTO_POSITION = 1, but the master has purged binary logs containing GTIDs that the slave requires. 其實上面的條件3是條件1的特殊情況,這個bugfix針對的場景就是條件3這種,但并不是所有的符合條件3的場景都會觸發這個bug,下面就分析下什么情況下才會觸發bug。 **bug 分析** 假設有這樣的場景,我們要用已經有MySQL實例的備份重新做一對主備實例,不管是用 xtrabackup 這種物理備份工具或者mysqldump這種邏輯備份工具,都會有2步操作, 1. 導入數據 2. SET GLOBAL GTID_PURGED ="xxxx" 步驟2是為了保證GTID的完備性,因為新實例已經導入了數據,就需要把生成這些數據的事務對應的GTID集合也設置進來。 正常的操作是主備都要做這2步的,如果我們只在主庫上做了這2步,備庫什么也不做,然后就直接用 GTID 協議把備庫連上來,按照我們的預期這個時候是應該出錯的,主備不一致,并且主庫的binlog中沒東西,應該報之前停止條件2報的錯。但是令人大跌眼鏡的是主庫不報錯,復制看起來是完全正常的。 為啥會這樣呢,SET GLOBAL GTID_PURGED 操作會調用 mysql_bin_log.rotate_and_purge切換到一個新的binlog,并把這個GTID_PURGED 集合記入新生成的binlog的Previous_gtids_log_event,假設原有的binlog為A,新生成的為B,主庫剛啟動,所以A就是主庫的第一個binlog,它之前啥也沒有,A的Previous_gtids_log_event就是空集,并且A中也不包含任何GTID事件,否則SET GLOBAL GTID_PURGED是做不了的。按照之前的掃描邏輯,掃到A是肯定會停下來的,并且不報錯。 **bug 修復** 官方的修復就是在主庫掃描查找binlog之前,判斷一下 gtid_purged 集合不是不比slave_gtid_executed大,如果是就報錯,錯誤信息和條件2一樣 Got fatal error 1236 from master when reading data from binary log: 'The slave is connecting using CHANGE MASTER TO MASTER_AUTO_POSITION = 1, but the master has purged binary logs containing GTIDs that the slave requires. 詳細的bugfix請看revno:?[6211](http://bazaar.launchpad.net/~mysql/mysql-server/5.6/revision/6211)
                  <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>

                              哎呀哎呀视频在线观看