複製的作用
- 讀寫分離,分擔讀負載
- 分庫分表時,數據轉移
- 實現高可用架構時,故障自動切換(failover),避免單點故障造成系統不可用
複製並不等於備份
主從複製的延遲較小,主庫被刪除後,從庫也會很快沒有了, 所以備份要單獨進行
基於日誌的複製原理
基於主庫的二進制日誌,日誌記錄了主庫DDL(對錶結構的創建、修改、刪除操作)、DML(對記錄的增刪改操作)操作,異步增量傳輸到從庫,讓從庫重現二進制日誌記錄的操作
- master將變更寫入二進制日誌中
- slave開闢單獨的I/O線程跟master建立TCP連接(master會建立一個轉儲線程與之響應)讀取master的二進制日誌的變更(首次全量複製,之後是master有新的變更後通過信號告訴slave可以讀取)並寫入到本地的中繼日誌(relay_log)中
- slave的sql線程讀取中繼日誌relay_log,重現master上的數據操作
開啓基於行ROW格式的二進制日誌(基於行復制的主從節點表結構要一致)
配置my.cnf
mkdir /usr/local/mysql/all-logs
vim /usr/local/mysql/my.cnf
server-id=1
log_bin=/usr/local/mysql/all-logs/mysql-bin
binlog_format=ROW
binlog_row_image=MINIMA
基於日誌點的複製配置步驟
1. 在Master上建立mysql的複製用戶賬號並授權
create user repluser@"192.168.16.%" identified by "repluser123";
grant replication slave on *.* to repluser @"192.168.16.%";
2. 配置Master開啓二進制日誌
mkdir /usr/local/mysql/all-logs
chown mysql:mysql /usr/local/mysql/all-logs
chmod -R 755 /usr/local/mysql/all-logs
vim /usr/local/mysql/my.cnf
server-id=1
log_bin=/usr/local/mysql/all-logs/mysql-bin
binlog_format=ROW
binlog_row_image=MINIMA
3. 配置Slave的relaylog等
mkdir /usr/local/mysql/all-logs
chown mysql:mysql /usr/local/mysql/all-logs
chmod -R 755 /usr/local/mysql/all-logs
vim /usr/local/mysql/my.cnf
server-id=2
log_bin=/usr/local/mysql/all-logs/mysql-bin
binlog_format=ROW
binlog_row_image=MINIMA
relay_log=/usr/local/mysql/all-logs/mysql-relay-bin
read_only=on
log_slave_update=on
log_slave_update開啓後可以當做其他從節點的主節點
read_only=on設置只讀,但是在mysql5.7之前就算在Slave的my.cnf中設置了read_only=on,有權限的用戶仍然可以執行寫操作成功
配置完my.conf記得重啓mysql
4. 初始化Slave的數據
通過master的備份數據庫還原到從庫
慎用mysqldump備份會枷鎖,阻塞當前mysql運行的性能
首先,在Master上執行數據導出
/usr/local/mysql/bin/mysqldump --single-transaction --master-data --triggers --routines --all-databases -uroot -p >> all.sql
對於所有的表都是InnoDB時可以用xtrabackup備份,不會造成枷鎖
然後,將master的數據拷貝到在slave上,執行數據導入完成數據初始化
mysql -uroot -p < all.sql
5. 在Slave中執行啓動複製的命令
進入mysql:
首先,執行change
change master to master_host = "192.168.16.11",
master_user="repluser",
master_password="repluser123",
master_log_file="mysql-bin.000001",
master_log_pos=440;
master_log_file和master_log_pos的值取自剛纔導出的主庫數據all.sql裏寫明的CHANGE MASTER TO MASTER_LOG_FILE這行信息,代表從庫是從主庫的哪個二進制文件記錄的哪個數據偏移量開始複製
**然後,執行start slave;開啓複製**
start slave;
6.查看主從複製狀態
在Master上可以看到爲每個從節點建立了dump線程
show processlist\G
在Slave上可以看到爲複製而生的IO線程和SQL線程
show processlist\G
show slave status \G;
常見錯誤
Error executing row event: 'Cannot execute statement: impossible to write to binary loformat and BINLOG_FORMAT = STATEMENT.'
原因:主從節點的二進制日誌格式不一致,
解決辦法:統一配置所有節點my.cnf的binlog_format同一個值,最好是ROW
Could not execute Write_rows event on table project1.t_users; Duplicate entry ‘6’ for 062; handler error HA_ERR_FOUND_DUPP_KEY; the event’s master log mysql-bin.000001, en
原因:從庫執行了寫操作且成功了,因爲主從數據不一致導致這臺從庫複製失敗,在mysql5.7之前就算在Slave的my.cnf中設置了read_only=on,有權限的用戶仍然可以執行寫操作成功
解決:一般保留主庫的數據,跳過本次複製錯誤,從庫重新從主庫複製,具體操作如下
stop slave;
set GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
start slave;