天天看點

MySQL核心月報 2014.09-MySQL· 限制改進·GTID和更新

<b>gtid 資料</b>

mysql 5.6 引入了global transaction identifiers (gtids,全局事務id)的特性,這一特性是用來解決主從複制(replication)場景下的一些問題,gtid 隻存在于 binlog 中,資料庫中是沒有的。

<a href="http://svenmysql.blogspot.se/2012/10/failover-and-flexible-replication.html">failover and flexible replication topologies in mysql 5.6</a>

<a href="http://svenmysql.blogspot.jp/2012/10/advanced-use-of-global-transaction.html">advanced use of global transaction identifiers</a>

<a href="http://svenmysql.blogspot.jp/2013/03/flexible-fail-over-policies-using-mysql.html">flexible fail-over policies using mysql and global transaction identifiers</a>

<b>更新遇到的問題</b>

gtid 能很好的解決 failover 問題,做到主庫切換自動化,減輕 dba 同學的負擔,但是這個前提是所有的 mysql 執行個體都是 5.6,如果線上執行個體是 5.5 的,必須全部升到 5.6 才行,而目前官方并沒有提供平滑的 5.5 更新到 5.6 gtid 的方式,中間必須要有一個執行個體重新開機過程,這是由 gtid 目前的實作方式決定的:

限制1. gtid 模式執行個體和非gtid模式執行個體是不能進行複制的,要求非常嚴格,一刀切,要麼都是gtid,要麼都不是

限制2. gtid_mode 是隻讀的,要改變狀态必須1)關閉執行個體、2)修改配置檔案、3) 重新開機執行個體

在這種條件要求下,我們來看下線上執行個體從 5.5 更新到 5.6 會有什麼問題,為了保證業務不中斷,更新過程一直要有執行個體對外提供服務,是以更新方式是建立一個新的 5.6 執行個體,從5.5同步資料,然後業務切換到 5.6。

為了描述友善,做如下假設:

<dl></dl>

<dt>執行個體a</dt>

<dd>5.5 版本的,目前業務用的資料庫</dd>

<dt>執行個體b</dt>

<dd>5.6 版本的,資料遷移的目标</dd>

遷移步驟如下:

用熱備份工具如 percona xtrabackup 将 a 資料備份然後導入到b

b 用非 gtid 模式和 5.5 同步資料,這時用的是傳統的基于檔案位置的複制

b和a同步的差不多的時候,在 a 上設 read_only,等 b 同步完成,假設同步完後時間點為 t1

關閉 b,修改參數開啟gtid,重新開機b

将業務的資料操作指向b,假設這個時間點為 t2

b 開始提供服務,遷移完畢

在上面的步驟中,t1 到 t2 的時間段内相當于資料庫服務不可用,整個資料庫停掉重新開機,這對線上業務來說是不可接受的,上面是用單個執行個體a和執行個體b說明問題,同樣可以擴充到叢集a和叢集b。

gtid_mode 的取值範圍除了 off 和 on 這兩個值外,還有 upgrade_step_1和upgrade_step_2,目前後2者并不支援,不過從名字上看應該是為了更新預留的,但是目前并沒有好的更新方式。

<b>解決方案</b>

之前的更新方式是 a-&gt;b 這種拓撲,現在變為 a-&gt;c-&gt;b

<dt>執行個體c</dt>

<dd>5.6 版本的,一種中間狀态執行個體,既可以和非gtid通信,又可以和gtid通信</dd>

建立 a-&gt;c-&gt;b 這種複制關系,其中 a-&gt;c 之間是檔案位置協定,c-&gt;b 之間是 gtid 協定

b、c和a同步的差不多的時候,在 a 上設 read_only,等b同步完成

将業務的資料操作指向b

這裡為了和之前遷移目标一緻,多用了一個執行個體c,其實這時候可以把b給去掉,還是2個執行個體。可以看到,引入了c後,更新過程中并沒有執行個體重新開機過程,隻有一個短暫的隻讀時間段,這個是無法避免的,即使不用gtid,也會有這個過程。

目前rds執行個體更新到5.6也是用這種方式。如果是叢集到叢集的話,要注意一點,處于中間狀态的執行個體c最好隻有一個,因為這種執行個體相當于一個gtid轉換器,将a中沒有 gtid 的 binlog 轉成包含 gtid 的 binlog,然後傳給b,如果有多個執行個體c的話,a中同一個binlog 中的事務會轉換出不同的gtid,這與 gtid 和事務一一對應的根本原則相沖突,複制會出問題。當然,如果能保證經過不同的c的binlog事務不會重複的話就可以有多個c。