MySQL主從復制原理深入講解
主從復制模型
一主一從
一主多從
雙主
線性級聯
環狀級聯
這次用來講解的是一主一從模型
主從復制原理圖
主從復制過程存在三個線程,Master端的I/O線程,Slave的I/O線程與SQL線程。Master端需要開啟binlog日誌,Slave端需要開啟relay日誌。
(master.info文件在配置主從復制時使用change master命令來指定生成)
2、Master端的I/O線程會根據Slave端的I/O線程請求的信息來讀取Master的binlog日誌信息與及讀取到最新的binlog文件名和位置點一同返回給Slave的I/O線程。
3、Slave端的I/O線程會把獲取到的binlog日誌寫入relay日誌(中繼日誌)文件中,並且更新master.info文件信息。(把讀取到Master最新的binlog日誌文件名和位置點更新到master.info文件中,下一次當前位置去讀取Master的binlog日誌)
主從復制實戰配置
配置小結
Master端
1、同步Master端的原始數據到所有Slave端
2、開啟binlog日誌,保持server-id唯一
3、配置Slave驗證授權用戶,權限replication slave
Slave端
1、執行change master語句,生成master.info文件
2、開啟relay日誌,保持server-id唯一
3、啟動Slave復制(start slave)
Master端全備數據庫同步到Slave端
在開始做主從復制之前,需要把Master原有的數據都先同步到所有的Slave,否則在做同步復制之時,因為原有數據不一致導致同步失敗。(註意,如果使用原來備份時間點比如昨天淩晨的全備數據同步所有Slave數據時,還需要把當前時間點之前的所有binlog增量備份同步,使在截取主從復制時間點時,Master和所有Slave的數據保持一致)
原有數據不一致導致主從復制失敗
mysql> show slave status\G
Last_Error: Error ‘Table ‘ricky.test‘ doesn‘t exist‘ on query. Default database: ‘ricky‘. Query: ‘insert into test values(987654,9,‘gogo‘,30)‘
並且全備時,要鎖表備份,並導入所有Slave,保證截取的時間點數據一致,同時刷新binlog日誌。
[root@db02 ~]# mysqldump -uroot -p123456 -S /data/3306/mysql.sock -A -B -R --flush-logs --lock-all-tables --events >/tmp/mysql_bak_$(date +%F).sql
[root@db02 ~]# mysql -uroot -p123456 -S /data/3307/mysql.sock </tmp/mysql_bak_2018-07-12.sql
[root@db02 ~]# mysql -uroot -p123456 -S /data/3307/mysql.sock
mysql> show databases;
Master端配置
Master端開啟binlog日誌功能
[root@db02 ~]# egrep "log-bin|server-id" /data/3306/my.cnf
log-bin = /data/3306/mysql-bin
server-id = 1
Master配置slave復制授權用戶
#權限replication slave
mysql> GRANT REPLICATION SLAVE ON *.* TO ‘mysql52‘@‘172.16.1.52‘ IDENTIFIED BY ‘123456‘;
mysql> flush privileges;
檢查Master端當前binlog日誌文件名和位置點
當前binlog文件名和位置點,在配置Slave端時,需要告訴Slave端
mysql> show master status\G
*************************** 1. row ***************************
File: mysql-bin.000004
Position: 337
Binlog_Do_DB:
Binlog_Ignore_DB:
1 row in set (0.00 sec)
Slave端配置
Slave端開啟relaylog日誌功能
[root@db02 ~]# egrep "relay-bin|server-id" /data/3307/my.cnf
relay-log = /data/3307/relay-bin
server-id = 3
告訴Slave端主從復制時連接的Master(ip+端口【默認可以不需要】)、授權連接用戶和密碼、binlog文件名和位置點。這裏的binlog文件名和位置點還有另一種解決辦法,在mysqldump全備時加入--master-data參數,把change master【1,不註釋;2,註釋】語句嵌入到備份文件中(mysqldump邏輯備份,以SQL語句形式導出數據),把備份文件復制到Slave端導入時,如果參數選項為“1”,則會自動執行change master語句,把binlog文件名和位置點寫入Slave端的master.info文件中。其它的master端信息、授權用戶和密碼則需要手動change master寫入master.info文件。
執行change master語句
mysql> CHANGE MASTER TO MASTER_HOST=‘172.16.1.52‘,
-> MASTER_PORT=3306,
-> MASTER_USER=‘mysql52‘,
-> MASTER_PASSWORD=‘123456‘,
-> MASTER_LOG_FILE=‘mysql-bin.000004‘,
-> MASTER_LOG_POS=337;
啟動Slave
mysql> start slave;
查看Slave端狀態
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 172.16.1.52
Master_User: mysql52
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000004
Read_Master_Log_Pos: 337
Relay_Log_File: relay-bin.000002
Relay_Log_Pos: 253
Relay_Master_Log_File: mysql-bin.000004
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB: mysql
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 337
Relay_Log_Space: 403
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1
1 row in set (0.00 sec)
測試主從復制功能
Master端向test表中插入一條數據
mysql> insert into test values(987654,9,‘gogo‘,30);
Slave端對應的test會同步了該條數據
mysql> select * from ricky.test;
MySQL主從復制原理深入講解