基于mysql5.7
復制就是把一臺MySQL服務(Master)上的數(shù)據(jù)拷貝到另外一臺或幾臺MySQL服務器(slaves)上。復制默認是異步進行的 。 根據(jù)配置,可以復制MySQL 服務上的全部數(shù)據(jù)庫、指定的數(shù)據(jù)庫或是一個數(shù)據(jù)庫中指定的幾個表。
復制的好處:
- 一個橫向擴展的方案: 讀寫分離
- 數(shù)據(jù)安全: salves 可以將復制處理掛起后做備份而不影響master
- 分析: 在線數(shù)據(jù)處理放在master上; 分析統(tǒng)計處理放到slaves上,不影響master的性能。
- 異地數(shù)據(jù)分布
復制的方式
- bin-log: 傳統(tǒng)的方式
- GTIDs: 新方式
復制類型
- oneway asynchronous replication
- synchronous repalication
復制方式
- 基于語句的復制 Statement Based Replication (SBR)
- 基于行的復制 Row Based Replication (RBR)
- 混合方式 Mixed Base Replication (MRB)
16.1 復制的配置
16.1.1 基于bin-log配置的概要
主庫將更新事件寫入bin-log。
從庫讀取主庫的bin-log, 并執(zhí)行bin-log的中的事件。
每個從庫會獲取完整的bin-log。 從庫默認是執(zhí)行bin-log中所有的事件。
但可以配置只執(zhí)行特定數(shù)據(jù)庫或特定數(shù)據(jù)表的事件。
不能說配置只執(zhí)行某一個事件。
bin-log的坐標: 文件名和文件內(nèi)的位置。
每一個主庫和從庫都要配置一個唯一的 server-id。
從庫上要配置主庫的host name 和 bin-log 文件名、位置。
server-id: a unique ID which the master and each slave must be configured.
slave statement : "CHANGE MASTER TO"
16.1.2 基于bin-log 的復制配置
一般步驟
- 在主庫上打開bin-log,并配置唯一的server-id。 需要重啟服務
- 為每個從庫配置唯一的server-id。 需要重啟服務
- 創(chuàng)建一個復制作業(yè)專用的的用戶(可選)
- 創(chuàng)建數(shù)據(jù)快照前或啟動復制處理前,需要記下主庫的bin-log 坐標, 用來配置從庫。
- 主庫如果已經(jīng)有了數(shù)據(jù),需要將既有數(shù)據(jù)通過數(shù)據(jù)快照先拷貝到所有的從庫上。 根據(jù)存儲引擎的不同, 數(shù)據(jù)快照的方式也不同。 對于MyISAM ,需要停下所有的處理獲取一個讀鎖,然后獲取bin-log坐標并導出數(shù)據(jù)。如果這個過程種數(shù)據(jù)有更新,會造成數(shù)據(jù)快照與主庫信息不匹配,最終得到的從庫數(shù)據(jù)也是不正確的。 (如果是InnoDB, 則不需要加讀鎖, 事務可以充分保證數(shù)據(jù)快照的生成了)?。
- 配置從庫連接主庫:主庫連接, 用戶名密碼, bin-log坐標
16.1.2.1 主庫配置
關閉MySQL 服務并修改 my.cnf 或 my.ini 文件。
在[mysqld] 下面添加log-bin 和 server-id配置
server-id 的取值范圍 [1 , (2的32次方)?1]
[mysqld]
log-bin=mysql-bin
server-id=1
注意:
- 沒有配置server-id 的話, 主庫會拒絕所有的從庫連接請求
- 為了保證持久性和一致性, 使用InnoDB時要在主庫的my.cnf文件中配置 innodb_flush_log_at_trx_commit=1 和 sync_binlog=1 in the master my.cnf file
- 確保主庫沒有打開skip-networking 配置, 否則從庫連不上主庫
16.1.2.2 創(chuàng)建復制用戶
mysql> CREATE USER 'repl'@'%.example.com' IDENTIFIED BY 'password';
mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%.example.com';
16.1.2.3 獲取bin-log坐標
第一步: 打開一個客戶端session 執(zhí)行 【FLUSH TABLES WITH READ LOCK】 并保持客戶端session一直打開
mysql> FLUSH TABLES WITH READ LOCK;
第二步: 再打開一個客戶端session 執(zhí)行 【SHOW MASTER STATUS】
mysql > SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000003 | 73 | test | manual,mysql |
+------------------+----------+--------------+------------------+
如果之前沒有打開bin-log, 這里得到的file 和 position 都是空的, 這時從庫配置filename 和 position 為 空字符串 ('') 和 4。
16.1.2.4 生成數(shù)據(jù)快照
主庫如果已經(jīng)數(shù)據(jù),需要將主庫數(shù)據(jù)復制到每一個從庫上。
- mysqldump:推薦, 尤其是InnoDB
- 復制數(shù)據(jù)文件: 更快速。 InnoDB不建議這么做
mysqldump
shell on master> mysqldump --all-databases --master-data > dbdump.db
--master-data: 配置會自動添加一個 CHANGE MASTER TO 語句, 這樣從庫就可以不用配置bin-log坐標了。
--all-databases: 所有的數(shù)據(jù)庫
--ignore-table: 排除指定的表
--databases : 指定數(shù)據(jù)庫
16.1.2.5 配置從庫
前提:
- 主庫已經(jīng)配置好
- bin-log 坐標,數(shù)據(jù)快照OK
- 主庫的讀鎖已經(jīng)釋放
mysql> UNLOCK TABLES;
在配置文件 [mysqld] 下配置:
[mysqld] server-id=2
一定要配置,不能和其它mysql服務沖突,否則連不上。
從庫不需要配置bin-log。 也可以配置bin-log,將這個從庫當作其它mysql的主庫。
沒有既有數(shù)據(jù)需要導入:
- 重啟服務
- 連接主庫
mysql> CHANGE MASTER TO
-> MASTER_HOST='master_host_name',
-> MASTER_USER='replication_user_name',
-> MASTER_PASSWORD='replication_password',
-> MASTER_LOG_FILE='recorded_log_file_name',
-> MASTER_LOG_POS=recorded_log_position;
如果有既有數(shù)據(jù)需要導入:
- 啟動從庫時帶上 --skip-slave-start 參數(shù), 不啟動復制處理
- 導入dump文件(通過上面的配置導出的dump文件帶有 CHANGE MASTER TO,后面就不用執(zhí)行了 )
shell> mysql < fulldb.dump
16.1.2.6 復制環(huán)境中添加從庫
我們可以在不影響主庫的情況下向復制環(huán)境中添加一個新的從庫。 直接拷貝現(xiàn)存從庫的數(shù)據(jù)文件夾到新從庫,并配置一個不同的 server-id (用戶配置) 和 一個 server UUID (啟動時生成)。
- 關閉現(xiàn)存從庫復制處理, 并記錄復制狀態(tài)。
mysql> STOP SLAVE;
mysql> SHOW SLAVE STATUS\G
- 關閉現(xiàn)存從庫
shell> mysqladmin shutdown
- 將所有的數(shù)據(jù)文件從老的從庫上拷貝到新從庫,
- 拷貝完成后,將新從庫數(shù)據(jù)文件中的 auto.cnf刪除(重啟后自動生成 server UUID)。
- 重啟現(xiàn)存從庫
- 為新的從庫配置一個 server-id(唯一)
- 啟動新從庫,帶上 --skip-slave-start 參數(shù)。
- 使用 【SHOW SLAVE STATUS 】 確認復制狀態(tài)和之前記錄的 源從庫一致
- 確認 server-id 和 server UUID 沒有沖突
- 【START SLAVE】