首先主伺服器把資料變化記錄到主日志,然後從伺服器通過i/o線程讀取主伺服器上的主日志,并且把它寫入到從伺服器的中繼日志中,接着sql線程讀取中繼日志,并且在從伺服器上重放,進而實作mysql複制。具體如下圖所示:
mysql複制
整個過程反映到從伺服器上,對應三套日志資訊,可在從伺服器上用如下指令檢視:
master_log_file & read_master_log_pos:下一個傳輸的主日志資訊。
relay_master_log_file & exec_master_log_pos:下一個執行的主日志資訊。
relay_log_file & relay_log_pos:下一個執行的中繼日志資訊。
了解這些日志資訊的含義對于解決故障至關重要,後文會詳細闡述。
先在主伺服器上建立複制賬号:
然後設定主伺服器配置檔案(預設:/etc/my.cnf):
注:一定要保證主從伺服器各自的server_id唯一,避免沖突。
client requested master to start replication from impossible position
因為日志資料已經丢失了,是以此類問題基本上不能處理,隻能重新安裝同步從伺服器。
接下來設定從伺服器配置檔案(預設:/etc/my.cnf):
下面最重要的步驟是如何克隆一份主伺服器的資料:
如果資料庫使用的是myisam表類型的話,可按如下方式操作:
有了資料檔案,傳輸到從伺服器上并導入:
當然,整個過程也可以利用管道符一次性操作:
因為我們開始設定了master-data=1,是以系統會自動設定參數:master_log_file和master_log_pos,我們還需要設定剩下的參數:
如果資料量很大的話,mysqldump會非常慢,此時直接拷貝資料檔案能節省不少時間:
在拷貝之前要先鎖定資料,然後再獲得相關的日志資訊(file & position):
接下來拷貝資料檔案時,如果是myisam表類型的話,直接拷貝即可;如果是innodb表類型的話,一定要先停止mysql服務再拷貝,否則拷貝檔案可能無法使用。把拷貝的資料檔案直接複制到從伺服器的資料目錄。
最後還需要再指定一下日志資訊:
注:不要在my.cnf配置檔案裡設定master_user和master_password,因為最終生效的是change master to生成的master.info檔案裡的資訊。
在主伺服器上直接拷貝資料檔案雖然很快,但需要鎖表或者停止服務,這會影響線上服務。如果先前已經有了從伺服器,那麼可以用舊的從伺服器做母本來克隆新的從伺服器:
先在舊的從伺服器上查詢日志資訊:
我們需要的是其中的relay_master_log_file & exec_master_log_pos。
然後在舊的從伺服器上按照前面的方法得到資料,并在新的從伺服器上還原。
接着在新的從伺服器上設定日志資訊:
不管用那個方法,最後記得在從伺服器上啟動複制,并檢查工作是否正常:
如果io線程和sql線程都顯示yes,就可以感謝上帝了:
slave_io_running: yes
slave_sql_running: yes
如果顯示no,則說明某些配置步驟有問題,請重新對照一遍前面所說的步驟。
問題:主從複制不止何故停止了,我該怎麼辦?
答案:複制錯誤多半是因為日志錯誤引起的,是以首先要搞清楚是主日志錯誤還是中繼日志錯誤,從錯誤資訊裡一般就能判斷,如果不能可以使用類似下面的mysqlbinlog指令:
如果沒有錯誤,則不會有任何輸出,反之如果有錯誤,則會顯示出來。
如果是主日志錯誤,需要手動找到正确的日志資訊,重新change master to即可:
如果是中繼日志錯誤,隻要在從伺服器使用show slave status結果中的日志資訊重新change master to即可,系統會抛棄目前的中繼日志,重新下載下傳:
至于為什麼使用的是relay_master_log_file & exec_master_log_pos,參見概述。
有時候由于bug或者在從伺服器執行了寫操作可能會造成鍵重複錯誤,錯誤資訊如下:
error ‘duplicate entry …’ for key … on query
問題:主伺服器當機了,如何把從伺服器提升會主伺服器?
答案:在一主多從的環境總,需選擇資料最新的從伺服器做新的主伺服器。如下圖所示:
提升從伺服器為主伺服器
在一主(server1)兩從(server2,、server3)環境中,server1當機後,等到server2和server3把當機前同步到的日志都執行完,比較master_log_file和read_master_log_pos就可以判斷出誰快誰慢,因為server2從server1同步的資料(1582)比server3從server1同步的資料(1493)新,是以應該提升server2為新的主伺服器,那麼server3在change master to到server2的時候應該使用什麼樣的參數呢?1582-1493=89,而server2的最後的二進制日志位置是8167,是以答案是8167-89=8078。
主從伺服器中的表可以使用不同的表類型。比如主伺服器可以使用innodb表類型,提供事務,行鎖等進階特性,從伺服器可以使用myisam表類型,記憶體消耗少,易備份等優點。還有一個例子,一台主伺服器如果同時帶很多個從伺服器的話,勢必會影響其性能,此時可以拿出一台伺服器作為從伺服器代理,使用blackhole表類型,隻記錄日志,不寫資料,由它帶多台從伺服器,進而提升性能。
主從伺服器中的表可以使用不同的鍵類型。比如主伺服器用innodb,鍵用varchar的話節省空間,從伺服器使用myisam,鍵用char提高速度,因為myisam有靜态表一說。
主從伺服器中的表可以使用不同的索引。主伺服器主要用來應付寫操作,是以除了主鍵和唯一索引等保證資料關系的索引一般都可以不加,從伺服器用來應付讀操作,是以可以針對查詢特征設定索引,甚至不同的從伺服器可以針對不同的查詢設定不同的索引。
有一些優秀的工具可以讓你的得到事半功倍的效果,詳細内容請參考各自文檔:
<a href="http://mysql-mmm.org/" target="_blank">multi-master replication manager for mysql</a>
<a href="http://www.percona.com/software/percona-xtrabackup/" target="_blank">percona xtrabackup</a>
<a href="http://code.openark.org/forge/openark-kit" target="_blank">openark kit</a>
<a href="http://www.percona.com/software/percona-toolkit" target="_blank">percona toolkit</a>
<a href="http://code.google.com/p/tungsten-replicator/" target="_blank">tungsten-replicator</a>
說明:本文參考了下面列出的書籍中相關的内容:
<a href="http://www.amazon.com/high-performance-mysql-optimization-replication/dp/0596101716/" target="_blank">high performance mysql: optimization, backups, replication, and more</a>
<a href="http://www.amazon.com/mysql-high-availability-building-centers/dp/0596807309/" target="_blank">mysql high availability: tools for building robust data centers</a>
希望我的總結能讓大家少走一些彎路。