天天看點

MySQL核心月報 2014.12-MySQL· 答疑釋惑·server_id為0的Rotate

<b>背景</b>

  在mysql的m-s結構裡面,event是binlog日志的基本機關。每個event來源于主庫,每個event都包含了serverid,用于表示該event是哪個執行個體生成的。

  在5.6裡面,細心的同學會發現,備庫的relaylog中出現了server_id為0的event,其類型為rotate event。

  這裡說說server_id=0的rotate event。

<b>心跳event</b>

  mysql cluster中從ndb 6.3開始就出現的headbeat event(hb event), 在社群版直到5.6.2才提供。

  hb event的目的是為了保持m-s之間的心跳。用法上是slave在change master的時候可以指定master_heartbeat_period。當此值為0時,主庫發送完所有事件後這個主備通道就一直idle直到發送新的event;當此值為非0的n時,主庫通道在idle超過n秒之後,發一個hb event。

  心跳event的另外一個作用是主庫将目前的最新位點通知給備庫。hb event中包含主庫目前binlog最新位置的檔案名和位點。備庫收到hb event後判斷主庫位點是否大于本地儲存的位點,若是,則在relay log中記錄一個server_id為0的rotate事件, 這意味着主庫上新增了不需要發送給自己的event。

<b>出現條件</b>

  在傳統的主備環境中,正常情況下心跳事件是不會被觸發寫入到備庫的relaylog的。這是因為所有的主庫binlog中的事件都會發給備庫,是以備庫收到的hb event中的位點總是不大于備庫已經接收到的binlog event最大值(注意到hb event隻在通道idle時才發)。

  但是在5.6啟用了gtid以後,就出現了這樣的case。最常見的是每個binlog檔案開頭用于表示之前所有binlog執行過的事件合集的previous-gtids,這個事件需要記錄在binlog中,但是不需要發給slave。這就會讓備庫在接收到hb之後記錄一個server_id=0的rotate event。

<b>主庫relaylog</b>

  與此相關的,一個可能出現的現象是雙m單寫場景下,備庫沒有更新,但是主庫會一直寫relay log。

  步驟如下:

  1、主備之間完成mm關系(gtid_mode=on)

  2、主庫和備庫各自stop slave

  3、主庫執行大量更新

  4、主庫start slave

  5、備庫start slave

  在備庫同步日志過程中生成了本地的binlog,這些binlog需要再發回給主庫。5.6的一個機制是,如果發現通道對面的接收方的executed_set已經包含了這個事件,則不發送。

  由于這些事件本身就是主庫發送過來的,是以備庫都不需要發回。但是備庫必須通知主庫本地的binlog的最新位點,是以構造了一個hb event。

  主庫收到hb event後記錄在relaylog中,形式就是server_id=0的rotate事件。

繼續閱讀