MySQL-複製

複製功能不僅有利於構建高性能的應用,同時也是高可用性、可擴展性、災難恢復、備份以及數據倉儲等工作的基礎。

MySQL支持兩種複製方式:基於行的複製和基於語句的複製。基於語句的而複製(邏輯複製)在很早的版本就支持,基於行的複製在5.1版本中被支持。

複製應用場景:
數據分佈,負載均衡,備份,高可用性和故障切換,MySQL升級測試

複製步驟:
在主庫上把數據更改記錄到二進制日誌中。
備庫將主庫上的日誌複製到自己的中繼日誌中。
備庫讀取中級日誌中的事件,將其重放到備庫數據之上。

配置複製:
在每臺服務器上創建複製賬號。
配置主庫和備庫。
通知備庫連接到主庫並從主庫瀆職數據。

創建複製賬號:
grant replication slave,replication client on . to repl@‘192.168.0.%’ identified by ‘****’;

配置主庫和備庫
在主庫的my.cnf文件中增加或修改如下內容:
log_bin=mysqk_bin
server_id=10

在備庫上修改my.cnf中增加類似的配置,並且通過楊需要重啓服務器。
log_bin=mysql_bin
server_id=2
relay_log=/var/lib/mysql-relay-bin
og_slave_update=1
read_only=1

啓動複製
change master to maste_host=‘server1’, master_suer=‘repl’, master_passward=’****’, master_log_file=‘mysql_bin.00001’, master_log_pos=0;

校驗執行語句
show slave status\G

開始複製:
start slave;

查看備庫向主庫發起的連接:
show processlist\G

保持主庫和備庫同步條件:
在某個時間點的主庫的數據快照;
主庫當前的二進制日誌文件,和獲得數據快照時在該二進制日誌文件中的偏移量,我們把這兩個值稱爲日誌文件座標。通過這兩個值可以確定二進制文件的位置。可以通過show master status命令來獲取這些值。
從快照時間到現在的二進制日誌。

從別的服務器克隆備庫的方法:
使用冷備份:關閉主庫,把數據複製到備庫。重啓主庫後,會使用一個新的二進制日誌文件,我們在備庫通過執行change master to 指向這個文件的起始處。這個方法的缺點很明顯:在複製數據時需要關閉主庫。

使用熱備份:如果僅使用了MYiSAM表,可以在主庫運行時使用mysqlhotcopy或rsync來複制數據。
使用mysqldump:如果只包含InnoDB表,那麼可以使用以下命令來轉存主庫數據並將其加載到備庫,然後色湖之相應的二進制日誌座標:
mysqldump --single-transaction --all-databases --master-data=1 --host=server1 |mysql --host=server2

使用快照或備份:只需要知道對應的二進制日誌座標,就可以使用主庫的快照或者備份來時初始化備庫。只需要把備份或者快照恢復到備庫,然後使用change master to指定二進制日誌的座標。

使用percona xtrabackup:percona的ctrabackup是一款開源的熱備份工具,它能夠在備份時不阻塞服務器的操作,因此可以在不影響主庫的情況下設置備庫。可以通過克隆主庫或者另一個已存在的備庫的方式來建立備庫。

使用另外的備庫:可以使用任何一種提及的克隆或者拷貝技術來從任意一臺備庫數據克隆到另外一臺服務器。

主庫上二進制日誌最重要的選項:
sync_binlog=1

如果使用InnoDB,我們強烈推薦設置如下選項:
innodb_flush_logs_at_trx_commit
innodb_support_xa=1
innodbd_safe_binlog

配置二進制日誌名:
log_bin=/var/lib/mysql/mysql-bin

在備庫上面指定相應的配置:
relay_log=/path/to/logs/relay-bin
skip_slave_start
read_only

基於行的複製模式能夠更高效地複製數據。重放一些查詢的代價可能會很高。將查詢的數據彙總到一張表中:
insert into summary_table(col1,col2,col3) select col1,col2,col3 from enormous_table group by col1,col2;

基於語句的複製方式代價會小很多:
update enormous_table set col1=0;

在實際中基於行的複製模式整體上更優,並且在實際中也適用於大多數場景。

基於語句的複製模式優缺點:當主備的模式不同時,邏輯複製能夠在多種情況下工作。例如,在主備上的表的定義不同單數類型相兼容、列的順序不同等情況。這樣就很容易先在備庫上修改schema,然後將其提升爲主庫,減少停機時間。基於語句的複製模式一般允許更靈活的操作。就語句的方式執行復制的過程基本上就是執行SQL語句。這意味着所有在服務器上發生的變更都以一種更容易理解的方式運行。這樣當出現問題時就可以很好地定位。但在很多情況下基於語句的模式無法正確複製,幾乎每一個安裝的備庫都至少碰到一次。事實上對於存儲過程,觸發器以及其他的一些語句的複製在5.0和5.1的一些列版本中存在大量的bug。這些語句的複製的方式已經被修改了很多次,以使其更好地工作。因此,如果正在使用觸發器或者存儲過程,就不要使用基於語句的複製模式,除非能夠清楚地確定不會碰到複製問題。

基於行的複製模式的優缺點:幾乎沒有基於行的複製模式無法處理的場景。對於所有的SQL構造、觸發器、存儲過程都能正確執行。只有當你試圖做一些諸如在備庫修改表的schema這樣的事情時纔可能導致複製失敗。這種方式可以減少鎖的使用,因爲它並不要求這種強行串行化是可重複的。但是由於語句並沒有在日誌裏記錄,因此無法判斷執行了那些SQL,除了需要知道行的變化外,這在很多情況下也很重要。

複製過濾器
在主庫上過濾記錄到二進制日誌的事件,在備庫上過濾記錄到中繼日誌的事件,通過選項binlog_do_db和binlog_ignore_db來控制過濾。

在備庫上,可以通過設置replicate_*選項,在從中繼日誌中來讀取事件時進行過濾。你可以複製或忽略一個或多個數據庫,把一個數據庫重寫到另外一個數據庫,或者使用類似like的模式複製或忽略數據庫表。

複製拓撲:
一個MySQL備庫實例只能有一個主庫。
每個備庫必須有一個唯一的服務器ID。
一個主庫可以有多個備庫。
如果打開了log_slave_updates選項,一個備庫可以把其主庫的數據變化傳播到其他備庫。

監控複製
在主庫上使用show master status命令來查看當前主庫的二進制日誌位置和配置。查看當前主庫有哪些二進制日誌是磁盤上的:show master logs;通過show binlog events來查看複製事件。

測量備庫延遲
備庫seconds_behind_master值是通過將服務器當前的事件戳於二進制日誌的事件的事件戳相比較得到的,所以只有在執行事件時才能報告延遲。
如果備庫複製線程沒有運行,就會報延遲爲NULL。
一些錯誤可能中斷複製並且停止複製線程,但second_behind_master將顯示爲0而不是顯示錯誤。
即使備庫線程正在運行,備庫有時候無法計算延時。如果發生這種情況,備庫會報0或NULL。
一個大事務可能會導致延遲波動。
如果分發主庫落後了,並且其本身也有已經追趕上它的備庫,備庫的延遲將顯示爲0,而事實上和源主庫之間是有延遲的。

確定主備是否一致
通常情況下可以在主庫上運行該工具,參數如下:
pt-table-checksum --replicate-test.checksum <master_host>

從主庫重新同步備庫
使用mysqldump轉儲受影響的數據並重新導入,如果在繁忙的服務器上有可能行不通。可以通過複製改變備庫數據,而pt-table-sync可以解決該問題。

將備庫提升爲主庫步驟:
停止向老的主庫寫入。
讓備庫追趕上主庫。
將一臺備庫配置爲新的主庫。
將備庫和寫操作指向新的主庫,然後開啓主庫的寫入。

大多數配置需要的步驟:
1.停止當前主庫上的所有寫操作。如果可以,最好能將所有的客戶端程序關閉。爲客戶端程序建立一個“do not run"這樣的類似標記可能會有所幫助。如果正在使用虛擬IP地址,也可以簡單地關閉虛擬IP,然後斷開所有的客戶端連接以關閉其打開的事務。
2.通過flush table with read lock在主庫上停止所有活躍的寫入,這一步是可選的。也可以在主庫上設置read_only選項。從這一刻開始,應該向即將被替換的主庫做任何寫入。因爲一旦他不是主庫,寫入就意味着數據丟失。
3.選擇一個備庫作爲新的主庫,並確保它已經完全跟上主庫。
4.確保新主庫和舊主庫的數據是一致的。
5.在新主庫上執行stop slave。
6.在新主庫上執行change master to master_host=’’,然後執行reset slave,使其斷開於老主庫的連接,並丟棄master.info裏面記錄的信息。
7.執行show master status記錄新主庫的二進制日誌座標。
8.確保其他備庫已經追趕上。
9.關閉舊主庫。
10.在MySQL 5.1以上版本中,如果需要,激活新主庫上事件。
11.將客戶端連接到新主庫。
12.在每臺備庫上執行change master to 語句,使用之前通過how master status獲得的二進制日誌座標,來指向新的主庫。

計劃外的提升:
確定哪臺備庫的數據最新。檢查每臺備庫上show slave status命令的輸出,選擇其中master_log_file/read_master_log_pos的值最新的那個。
讓所有備庫執行完所有其他從崩潰的舊主庫哪裏獲得的中繼日誌。如果在未完成前修改備庫的主庫,它會拋棄剩下的日誌事件,從而無法獲知該備庫在什麼地方停止。
執行前一小節的5-7步。
比較每臺備庫和新主庫上的master_log_file/read_master_log_pos的值。
執行前一小節的10-12步。

切換服務器角色:
停止主動服務器上的所有寫入。
在主動服務器上執行set global read_only=1,同時在配置文件裏也設置一下read_only,防止重啓後失效,但記住者不會阻止擁有超級權限的用戶修改數據。如果想要阻止所有人修改數據,可以執行flush tables with read lock。如果沒有這麼做,你必須kill所有的客戶端連接來保證沒有長時間運行的語句或者提交的事務。
在主動服務器上執行show master status並記錄二進制日誌座標。
使用主動服務器上的二進制日誌座標在被動服務器上執行select master_pos_wait()。該語句將阻塞住,直到複製跟上主動服務器。
在被動服務器上執行set global read_only=0,這樣就變成主動服務器。
修改應用的配置,使其寫入到新額主動服務器中。

複製的問題和解決方案

數據損壞或丟失的錯誤

主庫意外關閉,備庫意外關閉,主庫上的二進制日誌損壞(數據改變,但事件仍是有效的SQL;數據改變並且事件是無效的SQL;數據遺漏並且/或者事件的長度是錯誤的;某些事件已經損壞或被覆蓋,或者偏移量已經改變並且下一個事件的起始偏移量也是錯誤的),備庫上的中繼日誌損壞,二進制日誌於InnoDB事務日誌不同步,

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章