Mysql_Replication

關於資料複製的專有名詞:
1. 主伺服器(Master Server):
執行交易將資料寫入的地方。
保存二進位日誌檔。
傳遞資料給從伺服器。

2. 從伺服器(Slave Server):
跟主伺服器要事件的資料。
將事件內容同步到本地的伺服器。

3. 二進位日誌檔(Binary Log):
紀錄每一個改動的資料。
日誌內容依交易群組而切割。

4. 同步資料複製(Synchronous Replication):
在伺服器執行交易時,該交易需等到資料被複製到其他伺服器後才會提交。
確保資料的一致性,但速度較慢(相較於非同步資料複製)。
MySQL叢集伺服器才提供同步資料複製。

5. 非同步資料複製(Asynchronous Replication):
交易馬上提交並複製到其他伺服器。
不保證資料的一致性,但速度較快(相較於同步資料複製)。
一般的MySQL伺服器就有提供此功能


資料複製架構:
1. 主-從資料複製。
這樣一對一的複製架構,可用來作異地備援,避免因意外造成資料丟失。

2. 一主-多從資料複製。
這樣一對多的複製架構,使用者可以用多個從伺服器來分散資料的讀取負載,也讓使用者可以輕易的延展(Scale-Out)從伺服器進而提昇讀取效能。但新增/修改/刪除交易,還是由主伺服器負責,也引此,這樣的架構,較適合用在查詢負載較重的OLAP系統。

3. 主-主資料複製。
這是建構MySQL複製中最常見的架構。這兩台伺服器都可以讀/寫,且互為備援。在應用程式的支援下(自動切換資料庫連線),可以達成高用度的系統。

4. 多主資料複製。

相較於”一主-多從”與”主-主”的資料複製架構,多主資料複製可以在提昇效能的前提下,又達到高可用度的目的。


資料複製的流程圖:

在這個流程圖中,並沒有將全部的步驟都繪畫出來,只針對主要的流程加以說明(例如,這個圖就沒有畫出,當從伺服器中的SQL程序將資料輸入資料庫時,也會將資料寫入Bin Log)。讓我們來走過一次流程吧!
1. 當用戶端連線到資料庫時,資料庫即建立一個session。當資料從session將資料輸入到資料庫中,則資料庫會將收到的事件(insert/update/delete)紀錄一份到Bin Log。
2. 從伺服器的I/O執行緒會定期跟主伺服器的Dump執行緒要資料,而主伺服器的Dump執行緒會將資料傳給從伺服器的I/O執行緒,並由I/O執行緒將資料傳入到從伺服器的Relay Log。
3. SQL執行緒會將資料從Relay Log取出,並輸入到本機的資料庫中。




Replication實作 一: 單向(主-從)
1. master: 編輯/etc/my.cnf 確認以下設定
[mysqld]
server-id=1
log-bin=/xxx/master-bin
slave:
[mysqld]
server-id=2
2. 在master上建立帳號&授與權限
CREATE USER 'repluser'@'10.0.0.52' IDENTIFIED BY 'YOUR_PASSWORD';
GRANT REPLICATION SLAVE ON *.* TO 'repluser'@'10.0.0.52';
FLUSH PRIVILEGES;
3.備份master上資料庫
mysqldump -u root -p --master-data --all-databases > all_mysql_db.sql
4.將master資料庫回復到slave
mysql -u root -p --default-character-set=utf8 < all_mysql_db.sql
# 重新啟動slave mysql
/etc/init.d/mysql restart
5.設定 Slave 資料庫實體,指定 Master 資料庫的登入資訊,並且正式啟動複寫機制
slave> CHANGE MASTER TO
-> MASTER_HOST = 'master_host',
-> MASTER_PORT = 3306,
-> MASTER_USER = 'repluser',
-> MASTER_PASSWORD = 'YOUR_PASSWORD',
-> MASTER_LOG_FILE='mysql-bin.000005',   //file跟pos可以不用指定
-> MASTER_LOG_POS=98;
slave> START SLAVE;
6.檢查資料複寫狀態:
SHOW SLAVE STATUS \G;


Replication實作 二: 環狀(A->B->C->A)
目的:是要實現在ABC三台任意一台數據服務器上執行數據操作,其它任意兩台都要同步實現相同的操作
1.配置三台 my.cnf 加上
log-slave-updates = on
server-id = 1[2|3]     //三台id要注意不可相同
log-bin=mysql-bin     //確定log-bin有開啟
binlog-do-db = test   //指定slave-要同步的master 資料庫,不設定將同步所有資料庫
修改完成後重啟資料庫

2.在每台數據庫服務器上為slave創建一個用戶並授予複製的權限 ex:A->B主從
mysql> CREATE USER 'repluser'@'10.0.0.2' IDENTIFIED BY 'YOUR_PASSWORD';
GRANT REPLICATION SLAVE ON *.* TO 'repluser'@'10.0.0.2';
FLUSH PRIVILEGES;
重啟mysql服務
3.查看master狀態:
鎖表
mysql> FLUSH TABLES WITH READ LOCK;
mysql> show master status;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000005 | 98 | | |
+------------------+----------+--------------+------------------+
解鎖
mysql> UNLOCK TABLES;
配置A與_B連結:
mysql> CHANGE MASTER TO
-> MASTER_HOST = 'master_host',
-> MASTER_PORT = 3306,
-> MASTER_USER = 'repluser',
-> MASTER_PASSWORD = 'YOUR_PASSWORD',
-> MASTER_LOG_FILE='mysql-bin.000005',   //file跟pos可以不用指定
-> MASTER_LOG_POS=98;
5. B -> C 與 C -> A 參照 1、2 丶3步驟

資料複寫災難復原:
復原一:當主從因某些因素斷開時,重新建立主從連線所以步驟如下: 1.備份的影像檔 2.備份的二進位日誌檔 執行步驟: 1.確認備份的影像檔 + 二進位日誌檔是否正確 2.資料回復 3.套用二進位日誌檔 EX:
mysqlbinlog -- start-position=position --stop-datetime=datetime master-bin.000001 master-bin.000002 … | mysql -u root -p
重新設定資料複寫
 CHANGE MASTER TO
-> ...
-> MASTER_LOG_FILE = 'master-bin.000010'
-> MASTER_LOG_POS = '123456';
資料復原二:master 當掉主從斷開,slave重新連上線後繼續複寫出現錯誤: Slave I/O: Got fatal error 1236 from master when reading data from binary log: ‘Client requested master to start replication from impossible position’, Error_code: 1236 這是因為slave重新連上線後繼續要求當掉的bin下一筆資料,導致出現錯誤,解決方法
master> show master status\G
File: master-bin.000073
Position: 21959116
Binlog_Do_DB:
Binlog_Ignore_DB:
1 row in set (0.00 sec)
在slave上將file跟位置指向下一個新開的檔案
slave> slave stop;
slave> change master to
->MASTER_LOG_FILE='master-bin.000073',
->MASTER_LOG_POS=0;
slave> slave start;
slave> show slave status\G;